一、Docker網(wǎng)絡(luò)
1.實(shí)現(xiàn)原理
docker 使用linux 橋接,在宿主機(jī)虛擬一個docker 容器網(wǎng)橋(docker0) ,docker 啟動一個容器時會根據(jù)docker 網(wǎng)橋的網(wǎng)段分配給容器一個IP地址,稱為Container-IP,同時Docker 網(wǎng)橋是每個容器的默認(rèn)網(wǎng)關(guān)。因?yàn)樵谕凰拗鳈C(jī)內(nèi)的容器都接入同一個網(wǎng)橋,這樣容器之間就能夠通過容器的 Container-IP 直接通信。
docker 網(wǎng)橋是宿主機(jī)虛擬出來的,并不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無法尋址到的,這也意味著外部網(wǎng)絡(luò)無法直接通過Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主機(jī)(端口映射),即 docker run 創(chuàng)建容器時候,通過 -p 或者 -P 參數(shù)來啟用。訪問容器的時候,就通過 [宿主機(jī)IP]:[映射端口] 訪問容器。
2 .為容器創(chuàng)建端口映射
端口映射,底層原理實(shí)際是做了一個DNAT轉(zhuǎn)換。
方法一:隨機(jī)映射端口(從32768開始)
?docker run -itd ?--name=為容器指定名稱 -P 鏡像名稱
方法二:指定映射端口
?docker run -itd --name=為容器指定名稱 -p 宿主機(jī)端口:容器端口 鏡像名稱
?#隨機(jī)映射端口
?docker run -itd --name web1 -P nginx
?#查看映射端口號
?docker ps -a
?#使用宿主機(jī)IP:映射端口訪問測試
?curl http://192.168.10.19:49153
??
??
[root@localhost ~]# docker run -itd --name web1 -P nginx
363bd5d94a70aa477a0e03a34fa7264a971e63925bc072fde4a3f5c893ab3032
?[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
363bd5d94a70 nginx "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp web1
[root@localhost ~]# curl http://192.168.10.19:49153 ? ? #使用宿主機(jī)IP:映射端口訪問測試
?文章來源地址http://www.zghlxwxcb.cn/news/detail-744475.html
?#指定映射端口,將容器的80端口映射到宿主機(jī)的48888端口
?docker run -itd --name web2 -p 48888:80 nginx
?#使用宿主機(jī)IP:映射端口訪問測試
?curl http://192.168.41.46:48888
??
??
?#指定映射端口,將容器的80端口映射到宿主機(jī)的48888端口
?[root@localhost ~]# docker run -itd --name web2 -p 48888:80 nginx
WARNING: IPv4 forwarding is disabled. Networking will not work.
21d1d27309f8190950413597c1ef7bb55d9a39d595a1f7d1f93dfca1be678dbe
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21d1d27309f8 nginx "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:48888->80/tcp, :::48888->80/tcp web2
363bd5d94a70 nginx "/docker-entrypoint.…" 10 minutes ago Up 10 minutes 0.0.0.0:49153->80/tcp, :::49153->80/tcp web1
?#使用宿主機(jī)IP:映射端口訪問測試
?[root@localhost ~]# curl http://192.168.10.19:48888
??
?#查看宿主機(jī)監(jiān)聽的端口號
[root@localhost ~]# netstat -natp|grep docker
tcp 0 0 0.0.0.0:48888 0.0.0.0:* LISTEN 7869/docker-proxy
tcp 0 0 0.0.0.0:49153 0.0.0.0:* LISTEN 7621/docker-proxy
tcp6 0 0 :::48888 :::* LISTEN 7876/docker-proxy
tcp6 0 0 :::49153 :::* LISTEN 7627/docker-proxy
??
?#查看iptables規(guī)則,端口映射實(shí)際是做了一個DNAT轉(zhuǎn)換,通過nat表進(jìn)行轉(zhuǎn)發(fā)的
?[root@localhost ~]# iptables -nL -t nat
?......
?Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:48888 to:172.17.0.3:80
端口映射,底層原理實(shí)際是做了一個DNAT轉(zhuǎn)換。
192.168.10.19:49153 映射到 172.17.0.2:80,192.168.10.19:48888 映射到 172.17.0.3:80。
二、Docker的網(wǎng)絡(luò)模式
1. Docker的網(wǎng)絡(luò)模式
- Host:?容器不會虛擬出自己的網(wǎng)卡,配置主機(jī)的IP等,而是使用宿主機(jī)的IP和端口
- Container:?創(chuàng)建的容器不會創(chuàng)建自己的網(wǎng)卡,配置自己的IP,而是和一個指定的容器共享IP,端口范圍
- None:?該模式關(guān)閉了容器的網(wǎng)絡(luò)功能。
- Bridge:?默認(rèn)為該模式,此模式會為每一個容器分配,設(shè)置IP等,并將容器連接到一個docker0 的虛擬網(wǎng)橋,通過docker 0 網(wǎng)橋以及iptables nat 表配置與宿主機(jī)通信。
- 自定義網(wǎng)絡(luò)
在安裝Docker 時,它會自動創(chuàng)建三個網(wǎng)絡(luò):bridge(創(chuàng)建容器默認(rèn)連接到此網(wǎng)絡(luò)),none,host。
2 .查看docker 的網(wǎng)絡(luò)列表
?#查看docker的網(wǎng)絡(luò)列表
?docker network ls
?或者
?docker network list
3 .指定容器網(wǎng)絡(luò)模式
?#使用docker' run 創(chuàng)建Docker容器時,可以用--net 或--network 選項(xiàng)指定容器的網(wǎng)絡(luò)模式
?●host模式:使用 --net=host 指定。
?●none模式:使用 --net=none 指定。
?●container模式:使用--net=container:NAME/ID指定。
?●bridge模式:使用 --net=bridge 指定,默認(rèn)設(shè)置,可省略。
三、Docker網(wǎng)絡(luò)模式詳解
1. host模式
- 相當(dāng)于Vmware中的橋接模式,與宿主機(jī)在同一個網(wǎng)絡(luò)中,但沒有獨(dú)立IP地址。
- Docker使用了Linux的Namespaces技術(shù)來進(jìn)行資源隔離,如PID Namespace隔離進(jìn)程,Mount Namespace隔離文件系統(tǒng),Network Namespace隔離網(wǎng)絡(luò)等。
- 一個Network Namespace提供了一 份獨(dú)立的網(wǎng)絡(luò)環(huán)境,包括網(wǎng)卡、路由、iptable規(guī)則等都與其他的Network Namespace隔離。
- 一個Docker容器一般會分配一個獨(dú)立的NetworkNamespace。但如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨(dú)立的NetworkNamespace,而是和宿主機(jī)共用一個NetworkNamespace。容器將不會虛擬出自己的網(wǎng)卡、配置自己的IP等,而是使用宿主機(jī)的IP和端口。
容器和宿主機(jī)共享網(wǎng)絡(luò)命名空間,但沒有獨(dú)立IP地址,使用宿主機(jī)的IP地址,和宿主機(jī)共享端口范圍,例如宿主機(jī)使用了80端口,那么容器不能使用80端口。這種模式比較方便,但不安全。
?#創(chuàng)建容器tt1,指定網(wǎng)絡(luò)模式為 host
?#容器和宿主機(jī)共享網(wǎng)絡(luò)命名空間,但沒有獨(dú)立IP地址。使用宿主機(jī)的IP,和宿主機(jī)共享端口范圍。
?docker run -d --name t1 --net=host nginx
??
?#訪問宿主機(jī)的ip和80端口,則可以訪問到tt1的nginx服務(wù)
?curl http://192.168.10.19:80
2 .container模式
- container模式: 使用
–net=contatiner:NAME/ID
指定。 - 這個模式指定新創(chuàng)建的容器和已經(jīng)存在的一個容器共享一個Network Namespace,而不是和宿主機(jī)共享。新創(chuàng)建的容器不會創(chuàng)建自己的網(wǎng)卡、配置自己的IP,而是和一個指定的容器共享IP,端口范圍等。 可以在一定程度上節(jié)省網(wǎng)絡(luò)資源,容器內(nèi)部依然不會擁有所有端口。
- 同樣,兩個容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng),進(jìn)程列表等還是隔離的。
- 兩個容器的進(jìn)程可以通過lo網(wǎng)卡設(shè)備通信。
新創(chuàng)建的B容器和A容器共享命名空間。假如A容器使用了80端口,B容器就不能使用80端口。
?#基于鏡像centos:7 創(chuàng)建一個名為t2的容器
[root@localhost ~]#docker run -itd --name t2 centos:7 sh
4f6a854a0e91abc6f0932a51cd7f35eae5830dbe15f2b2fa02a9cc31f6b23914
?#查看容器t2的pid號
[root@localhost ~]# docker inspect -f '{{.State.Pid}}' t2
7527
?#查看t2的網(wǎng)絡(luò)命名空間編號,net:[4026532633]
[root@localhost ~]# ls -l /proc/7527/ns
總用量 0
lrwxrwxrwx. 1 root root 0 11月 22 09:59 ipc -> ipc:[4026532630]
lrwxrwxrwx. 1 root root 0 11月 22 09:59 mnt -> mnt:[4026532628]
lrwxrwxrwx. 1 root root 0 11月 22 09:58 net -> net:[4026532633]
lrwxrwxrwx. 1 root root 0 11月 22 09:59 pid -> pid:[4026532631]
lrwxrwxrwx. 1 root root 0 11月 22 09:59 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 11月 22 09:59 uts -> uts:[4026532629]
??
??
?#創(chuàng)建t1容器,使用container網(wǎng)絡(luò)模式,和t2共享網(wǎng)絡(luò)命名空間
?[root@localhost ~]# docker run -itd --name t1 --net=container:t2 centos:7 sh
?cb62a8464ab6ebad550f287cdfbc66811800dd7a4b7c8d13c27ad43ceb421a13
?#查看t1容器的pid
?[root@localhost ~]# docker inspect -f '{{.State.Pid}}' t1
8301
?#查看t1容器的網(wǎng)絡(luò)命名空間編號,net:[4026532633],和t2相同。
[root@localhost ~]# ls -l /proc/8301/ns
總用量 0
lrwxrwxrwx. 1 root root 0 11月 22 10:44 ipc -> ipc:[4026532748]
lrwxrwxrwx. 1 root root 0 11月 22 10:44 mnt -> mnt:[4026532746]
lrwxrwxrwx. 1 root root 0 11月 22 10:44 net -> net:[4026532633]
lrwxrwxrwx. 1 root root 0 11月 22 10:44 pid -> pid:[4026532749]
lrwxrwxrwx. 1 root root 0 11月 22 10:44 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 11月 22 10:44 uts -> uts:[4026532747]
??
?#可以看到t1和t2共享同一個網(wǎng)絡(luò)命名空間
?3. none 模式
- none模式:使用 --net=none 指定
- 使用none 模式,docker 容器有自己的network Namespace ,但是并不為Docker 容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說,這個Docker 容器沒有網(wǎng)卡,ip, 路由等信息。
- 這種網(wǎng)絡(luò)模式下,容器只有l(wèi)o 回環(huán)網(wǎng)絡(luò),沒有其他網(wǎng)卡。
- 這種類型沒有辦法聯(lián)網(wǎng),但是封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
- 該容器將完全獨(dú)立于網(wǎng)絡(luò),用戶可以根據(jù)需要為容器添加網(wǎng)卡。此模式擁有所有端口。(none網(wǎng)絡(luò)模式配置網(wǎng)絡(luò)
- 特殊情況下才會用到,一般不用。
4 .bridge 模式?
bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不用--net參數(shù), 就是bridge模式。
相當(dāng)于Vmware中的nat模式,容器使用獨(dú)立network Namespace, 并連接到docker0虛擬網(wǎng)卡I通過docker0網(wǎng)橋以及iptables nat表配置與宿主機(jī)通信,此模式會為每. 個容器分配Network Namespace、 設(shè)置IP等,并將一一個 主機(jī)上的Docker 容器連接到一個虛擬網(wǎng)橋上。
(1)當(dāng)Docker進(jìn)程啟動時,會在主機(jī)上創(chuàng)建一個名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動的Docker容器會連接到這個虛擬網(wǎng)橋上。虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過交換機(jī)連在了一“個二層網(wǎng)絡(luò)中。
(2)從docker0子網(wǎng)中分配一個IP給容器使用(分配一個和網(wǎng)橋相同網(wǎng)段內(nèi)的IP,網(wǎng)橋作為網(wǎng)關(guān)),并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。在主機(jī)上創(chuàng)建一對虛擬網(wǎng)卡veth pair設(shè)備。veth設(shè)備總是成對出現(xiàn)的,它們組成了一個數(shù)據(jù)的通道,數(shù)據(jù)從一個設(shè)備進(jìn)入,就會從另一個設(shè)備出來。因此,veth設(shè)備常用來連接兩個網(wǎng)絡(luò)設(shè)備。
(3)Docker將 veth pair設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0 (容器的網(wǎng)卡),另一端放在主機(jī)中,以veth*這樣類似的名字命名,并將這個網(wǎng)絡(luò)設(shè)備加入到docker0 網(wǎng)橋中??梢酝ㄟ^brctl show命令查看。
(4)使用docker run -P 時,docker實(shí)際 是在iptables做了DNAT規(guī)則,實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能??梢允褂?code>iptables -t nat -vnL查看。
每個容器有自己獨(dú)立的命名空間。容器之間通過網(wǎng)橋轉(zhuǎn)發(fā)進(jìn)行通信,成對的網(wǎng)絡(luò)設(shè)備veth pair。
?#bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不用--net參數(shù),就是bridge模式。 ? ? ? ? ?
?[root@localhost ~]# docker run -itd --name a1 centos:7 sh
WARNING: IPv4 forwarding is disabled. Networking will not work.
cf24acd344c936bc531e2dbe1d13d34041bcf37b7bf0fc8d66fcddbc04d7d39e
??
?#查看容器tt2的網(wǎng)絡(luò)模式,為默認(rèn)網(wǎng)絡(luò)模式。
?[root@localhost ~]# docker inspect a1 |grep -i 'networkmode'
"NetworkMode": "default",
?
5 .定義網(wǎng)絡(luò)模式
直接使用bridge 模式,是無法指定IP運(yùn)行docker 的,例如執(zhí)行以下命令就會報錯:
[root@localhost ~]# docker run -itd --name a2 --network bridge --ip 172.17.0.10 centos:7 sh
WARNING: IPv4 forwarding is disabled. Networking will not work.
00fee129bbbf912a88a980f5891b7174688d58e6fbae851e5c37e68c2969c673
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
?
創(chuàng)建自定義網(wǎng)絡(luò):
需要先自定義網(wǎng)絡(luò),再指定IP運(yùn)行docker。
?#(1)先自定義網(wǎng)絡(luò),設(shè)置網(wǎng)卡地址池,網(wǎng)卡名,網(wǎng)絡(luò)模式名稱
[root@localhost ~]# docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
e73646c1e5ddff760a2987ffe651364ff36abfb68e7b83ce89a88b4cd9a69fe4
??
?-------------注釋---------------------------------------------------------------------
?●docker1 :為執(zhí)行ifconfig -a 命令時顯示的網(wǎng)卡名,如果不使用 --opt 參數(shù)指定此名稱,使用 ifconfig -a 查看網(wǎng)卡的網(wǎng)絡(luò)信息時,看到的將會是類似 br-110eb56a0b22這樣的名字,這顯然不好記。
?●mynetwork:為執(zhí)行"docker network list" 命令時,顯示的 bridge 網(wǎng)絡(luò)模式名稱。
?-------------------------------------------------------------------------------------
?#查看docker的網(wǎng)絡(luò)列表
?[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
02491d13b596 bridge bridge local
33d18fa2ad5d host host local
e73646c1e5dd mynetwork bridge local #生成了自定義網(wǎng)絡(luò)模式
baea95f0747a none null local
??
??
?#(2)再使用該網(wǎng)段內(nèi)的地址,創(chuàng)建自定義網(wǎng)絡(luò)的容器a3
?[root@localhost ~]# docker run -itd --name a3 --net mynetwork --ip 172.18.0.10 centos:7 sh
WARNING: IPv4 forwarding is disabled. Networking will not work.
84977b6b15bcd93b1c72389990d41c5352330c791f2c5a067d34116af7a8d1f5
?#查看容器a3的IP地址
?[root@yuji ~]# docker inspect a3 | grep -i "IPv4Address"
? ? ? ? ? ? ? ? ? ? ? ? ?"IPv4Address": "172.18.0.10"
??
?#也可以docker exec進(jìn)入容器后下載net-tools工具,之后使用ifconfig命令查看容器IP地址。
?刪除自定義網(wǎng)絡(luò):
如果想要刪除自定義的網(wǎng)絡(luò),可以使用?docker network rm 網(wǎng)絡(luò)模式名稱
?進(jìn)行刪除,例如docker network rm mynetwork
。
刪除網(wǎng)絡(luò)模式前,需要先確保使用該網(wǎng)絡(luò)模式創(chuàng)建的容器已退出(即已停止)。如果容器仍在運(yùn)行,則該網(wǎng)絡(luò)無法刪除。
?#當(dāng)使用自定義網(wǎng)絡(luò)創(chuàng)建的容器處于運(yùn)行狀態(tài)時,無法刪除自定義網(wǎng)絡(luò)。
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84977b6b15bc centos:7 "sh" 45 minutes ago Up 45 minutes a3
00fee129bbbf centos:7 "sh" 50 minutes ago Created a2
cf24acd344c9 centos:7 "sh" 55 minutes ago Up 55 minutes a1
cb62a8464ab6 centos:7 "sh" 2 hours ago Up 2 hours t1
4f6a854a0e91 centos:7 "sh" 2 hours ago Up 2 hours t2
[root@localhost ~]# docker network rm mynetwork
Error response from daemon: error while removing network: network mynetwork id e73646c1e5ddff760a2987ffe651364ff36abfb68e7b83ce89a88b4cd9a69fe4 has active endpoints
??
?#需要先將容器停止,之后再刪除網(wǎng)絡(luò)
[root@localhost ~]# docker stop $(docker ps -q)
84977b6b15bc
cf24acd344c9
cb62a8464ab6
4f6a854a0e91
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84977b6b15bc centos:7 "sh" 49 minutes ago Exited (137) 12 seconds ago a3
00fee129bbbf centos:7 "sh" 54 minutes ago Created a2
cf24acd344c9 centos:7 "sh" 59 minutes ago Exited (137) 12 seconds ago a1
cb62a8464ab6 centos:7 "sh" 2 hours ago Exited (137) 12 seconds ago t1
4f6a854a0e91 centos:7 "sh" 2 hours ago Exited (137) 12 seconds ago t2
[root@localhost ~]# docker network rm mynetwork ? #刪除自定義網(wǎng)絡(luò)mynetwork
?mynetwork
[root@localhost ~]# docker network ls #自定義網(wǎng)絡(luò)已被刪除
NETWORK ID NAME DRIVER SCOPE
02491d13b596 bridge bridge local
33d18fa2ad5d host host local
baea95f0747a none null local
文章來源:http://www.zghlxwxcb.cn/news/detail-744475.html
?
到了這里,關(guān)于Docker的四種網(wǎng)絡(luò)模式和相關(guān)網(wǎng)絡(luò)命令的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!