本文提供可用於與Docker網絡及與網絡中容器進行交互的network子命令的示例。這些命令可通過Docker Engine CLI獲得。 這些命令是:
docker network create
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
<!-- more -->
雖然不是必需的,但在嘗試本節中的示例之前,先閱讀 瞭解Docker網絡 更佳。 示例使用默認bridge
網絡以便您可以立即嘗試。要實驗overlay
網絡,請參閱 多主機網絡入門指南 。
創建網絡
Docker Engine在安裝時自動創建bridge
網絡。 該網絡對應於Engine傳統依賴的docker0
網橋。除該網絡外,也可創建自己的bridge
或overlay
網絡。
bridge
網絡駐留在運行Docker Engine實例的單個主機上。 overlay
網絡可跨越運行Docker Engine的多個主機。 如果您運行docker network create
並僅提供網絡名稱,它將爲您創建一個橋接網絡。
$ docker network create simple-network
69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a
$ docker network inspect simple-network
[
{
"Name": "simple-network",
"Id": "69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.22.0.0/16",
"Gateway": "172.22.0.1"
}
]
},
"Containers": {},
"Options": {},
"Labels": {}
}
]
與bridge
網絡不同, overlay
網絡需要一些預製條件才能創建——
- 訪問key-value存儲。 引擎支持Consul,Etcd和ZooKeeper(分佈式存儲)key-value存儲。
- 與key-value存儲連接的主機集羣。
- 在swarm中的每個主機上正確配置的
Docker daemon
。
支持overlay
網絡的dockerd
選項有:
--cluster-store
--cluster-store-opt
--cluster-advertise
在創建網絡時,Docker引擎默認會爲網絡創建一個不重疊的子網。 您可以覆蓋此默認值,並使用--subnet
選項直接指定子網。 對於bridge
網絡,只可指定一個子網。 overlay
網絡支持多個子網。
注意 :強烈建議在創建網絡時使用
--subnet
選項。 如果未指定--subnet
則Docker daemon會自動爲網絡選擇並分配子網,這可能會導致與您基礎結構中的另一個子網(該子網不受--subnet
管理)重疊。 當容器連接到該網絡時,這種重疊可能導致連接問題或故障。
除--subnet
選項以外,您還可以指定--gateway
, --ip-range
--gateway
--ip-range
和--aux-address
選項。
$ docker network create -d overlay \
--subnet=192.168.0.0/16 \
--subnet=192.170.0.0/16 \
--gateway=192.168.0.100 \
--gateway=192.170.0.100 \
--ip-range=192.168.1.0/24 \
--aux-address="my-router=192.168.1.5" --aux-address="my-switch=192.168.1.6" \
--aux-address="my-printer=192.170.1.5" --aux-address="my-nas=192.170.1.6" \
my-multihost-network
確保您的子網不重疊。 如果重疊,那麼網絡將會創建失敗,Docker Engine返回錯誤。
創建自定義網絡時,您可以向驅動傳遞其他選項。 bridge
驅動程序接受以下選項:
Option | Equivalent | Description |
---|---|---|
com.docker.network.bridge.name | - | 創建Linux網橋時要使用的網橋名稱 |
com.docker.network.bridge.enable_ip_masquerade | --ip-masq | 啓用IP僞裝 |
com.docker.network.bridge.enable_icc | --icc | 啓用或禁用跨容器連接 |
com.docker.network.bridge.host_binding_ipv4 | --ip | 綁定容器端口時的默認IP |
com.docker.network.driver.mtu | --mtu | 設置容器網絡MTU |
overlay
驅動也支持com.docker.network.driver.mtu
選項。
以下參數可以傳遞給任何網絡驅動的docker network create
。
Argument | Equivalent | Description |
---|---|---|
--internal | - | 限制對網絡的外部訪問 |
--ipv6 | --ipv6 | 啓用IPv6網絡 |
以下示例使用-o
選項,在綁定端口時綁定到指定的IP地址,然後使用docker network inspect
來檢查網絡,最後將新容器attach到新網絡。
$ docker network create -o "com.docker.network.bridge.host_binding_ipv4"="172.23.0.1" my-network
b1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a
$ docker network inspect my-network
[
{
"Name": "my-network",
"Id": "b1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.23.0.0/16",
"Gateway": "172.23.0.1"
}
]
},
"Containers": {},
"Options": {
"com.docker.network.bridge.host_binding_ipv4": "172.23.0.1"
},
"Labels": {}
}
]
$ docker run -d -P --name redis --network my-network redis
bafb0c808c53104b2c90346f284bda33a69beadcab4fc83ab8f2c5a4410cd129
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bafb0c808c53 redis "/entrypoint.sh redis" 4 seconds ago Up 3 seconds 172.23.0.1:32770->6379/tcp redis
連接容器
您可以將一個現有容器連接到一個或多個網絡。 容器可連接到使用不同網絡驅動的網絡。 一旦連接,容器即可使用另一個容器的IP地址或名稱進行通信。
對於支持多主機連接的overlay
網絡或自定義插件,不同主機上的容器,只要連接到同一multi-host network多主機網絡,也可以這種方式進行通信。
此示例使用六個容器,並指示您根據需要創建它們。
基本容器網絡示例
-
首先,創建並運行兩個容器,
container1
和container2
:$ docker run -itd --name=container1 busybox 18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731 $ docker run -itd --name=container2 busybox 498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152
-
創建一個隔離的
bridge
網絡進行測試。$ docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw 06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8
-
將
container2
連接到網絡,然後inspect
網絡以驗證連接:$ docker network connect isolated_nw container2 $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.25.0.0/16", "Gateway": "172.25.0.1/16" } ] }, "Containers": { "90e1f3ec71caf82ae776a827e0712a68a110a3f175954e5bd4222fd142ac9428": { "Name": "container2", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "MacAddress": "02:42:ac:19:00:02", "IPv4Address": "172.25.0.2/16", "IPv6Address": "" } }, "Options": {} } ]
請注意,
container2
自動分配了一個IP地址。 因爲在創建網絡時指定了--subnet
選項,所以IP地址會從該子網選擇。作爲提醒,
container1
僅連接到默認bridge
。 -
啓動第三個容器,但這次使用
--ip
標誌分配一個IP地址,並使用docker run
命令的--network
選項將其連接到--isolated_nw
網絡:$ docker run --network=isolated_nw --ip=172.25.3.3 -itd --name=container3 busybox 467a7863c3f0277ef8e661b38427737f28099b61fa55622d6c30fb288d88c551
只要您爲容器指定的IP地址是如上子網的一部分,那就可使用
--ip
或--ip6
標誌將IPv4或IPv6地址分配給容器,將其連接到以上網絡。 當您在使用用戶自定義的網絡時以這種方式指定IP地址時,配置將作爲容器配置的一部分進行保留,並在容器重新加載時進行應用。 使用非用戶自定義網絡時,分配的IP地址將被保留,因爲不保證Docker daemon重啓時容器的子網不會改變,除非您使用用戶定義的網絡。【這一段官方文檔是不是有問題???】 -
檢查
container3
所使用的網絡資源。 簡潔起見,截斷以下輸出。$ docker inspect --format='' container3 {"isolated_nw": {"IPAMConfig": { "IPv4Address":"172.25.3.3"}, "NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "EndpointID":"dffc7ec2915af58cc827d995e6ebdc897342be0420123277103c40ae35579103", "Gateway":"172.25.0.1", "IPAddress":"172.25.3.3", "IPPrefixLen":16, "IPv6Gateway":"", "GlobalIPv6Address":"", "GlobalIPv6PrefixLen":0, "MacAddress":"02:42:ac:19:03:03"} } } }
因爲在啓動時將
container3
連接到isolated_nw
,所以它根本沒有連接到默認的bridge
網絡。 -
檢查
container2
所使用的網絡。 如果你安裝了Python,你可以打印輸出格式化。$ docker inspect --format='' container2 | python -m json.tool { "bridge": { "NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", "EndpointID": "0099f9efb5a3727f6a554f176b1e96fca34cae773da68b3b6a26d046c12cb365", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03" }, "isolated_nw": { "NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "Gateway": "172.25.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.25.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:19:00:02" } }
請注意,
container2
屬於兩個網絡。 當您啓動它時,它加入了默認bridge
網絡,並在步驟3中將其連接到isolated_nw
。eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02
-
使用
docker attach
命令連接到正在運行的container2
並檢查它的網絡堆棧:$ docker attach container2
使用
ifconfig
命令檢查容器的網絡堆棧。 您應該看到兩個以太網卡,一個用於默認bridge
,另一個用於isolated_nw
網絡。$ sudo ifconfig -a eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02 inet addr:172.25.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe19:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
-
Docker內嵌DNS服務器可使用容器名稱解析連接到給定網絡的容器。 這意味着網絡內的容器可以通過容器名稱ping在同一網絡中的另一個容器。 例如,從
container2
可以按名稱pingcontainer3
。/ # ping -w 4 container3 PING container3 (172.25.3.3): 56 data bytes 64 bytes from 172.25.3.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.3.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.3.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.3.3: seq=3 ttl=64 time=0.097 ms --- container3 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
此功能不適用於默認
bridge
網絡。container1
和container2
都連接到默認的bridge
網絡,但是並不能使用容器名稱從container2
pingcontainer1
。/ # ping -w 4 container1 ping: bad address 'container1'
但依然可直接ping IP地址:
/ # ping -w 4 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.095 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.101 ms --- 172.17.0.2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.072/0.085/0.101 ms
離開
container2
容器,並使用CTRL-p CTRL-q
保持容器運行。 -
當前,
container2
連接到默認bridge
網絡和isolated_nw
網絡,因此,container2
可與container1
以及container3
進行通信。 但是,container3
和container1
沒有任何共同的網絡,所以它們不能通信。 要驗證這一點,請附加到container3
並嘗試通過IP地址pingcontainer1
。$ docker attach container3 $ ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes ^C --- 172.17.0.2 ping statistics --- 10 packets transmitted, 0 packets received, 100% packet loss
離開
container3
容器,並使用CTRL-p CTRL-q
保持容器運行。
即使容器未運行,也可以將容器連接到網絡。 但是,
docker network inspect
僅顯示運行容器的信息。
鏈接容器而不使用用戶定義的網絡
完成基本容器網絡示例中的步驟後, container2
可以自動解析container3
的名稱,因爲兩個容器都連接到isolated_nw
網絡。 但是,連接到默認bridge
的容器無法解析彼此的容器名稱。 如果您需要容器能夠通過bridge
網絡進行通信,則需要使用遺留的連接功能。 這是唯一的建議使用--link
的情況。 您應該強烈地考慮使用用戶定義的網絡。
使用遺留的link
標誌爲可爲默認的bridge
網絡添加以下功能進行通信:
- 將容器名稱解析爲IP地址的能力
- 使用
--link=CONTAINER-NAME:ALIAS
定義一個網絡別名去連接容器的能力 - 安全的容器連接(通過
--icc=false
隔離) - 環境變量注入
需要重申的是,當您使用用戶自定義網絡時,默認情況下提供所有這些功能,無需額外的配置。 此外,您可以動態attach到多個網絡,也可動態從多個網絡中離開。
- 使用DNS進行自動名稱解析
- 支持
--link
選項爲鏈接的容器提供名稱別名 - 網絡中容器的自動安全隔離環境
- 環境變量注入
以下示例簡要介紹如何使用--link
。
-
繼續上面的例子,創建一個新的容器
container4
,並將其連接到網絡isolated_nw
。 另外,使用--link
標誌鏈接到容器container5
(不存在!)!$ docker run --network=isolated_nw -itd --name=container4 --link container5:c5 busybox 01b5df970834b77a9eadbaff39051f237957bd35c4c56f11193e0594cfd5117c
這有點棘手,因爲
container5
還不存在。 當container5
被創建時,container4
將能夠將名稱c5
解析爲container5
的IP地址。注意 :使用遺留的link功能創建的容器之間的任何鏈接本質上都是靜態的,並且通過別名強制綁定容器。 它無法容忍鏈接的容器重新啓動。 用戶自定義網絡中的新鏈接功能支持容器之間的動態鏈接,並且允許鏈接容器中的重新啓動和IP地址更改。
由於您尚未創建容器
container5
嘗試ping它將導致錯誤。 attach到container4
並嘗試ping任何container5
或c5
:$ docker attach container4 $ ping container5 ping: bad address 'container5' $ ping c5 ping: bad address 'c5'
從
container4
離開,並使用CTRL-p CTRL-q
使其保持運行。 -
創建一個容器,名爲
container5
,並使用別名c4
將其鏈接到container4
。$ docker run --network=isolated_nw -itd --name=container5 --link container4:c4 busybox 72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a
現在attach到
container4
,嘗試pingc5
和container5
。$ docker attach container4 / # ping -w 4 c5 PING c5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms --- c5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 container5 PING container5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms --- container5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
從
container4
分離,並使用CTRL-p CTRL-q
使其保持運行。 -
最後,附加到
container5
,驗證你可以pingcontainer4
。$ docker attach container5 / # ping -w 4 c4 PING c4 (172.25.0.4): 56 data bytes 64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms 64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms 64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms 64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms --- c4 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.065/0.070/0.082 ms / # ping -w 4 container4 PING container4 (172.25.0.4): 56 data bytes 64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms 64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms 64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms 64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms --- container4 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.065/0.070/0.082 ms
從
container5
離開,並使用CTRL-p CTRL-q
使其保持運行。
網絡範圍的別名示例
鏈接容器時,無論是使用遺留的link
方法還是使用用戶自定義網絡,您指定的任何別名只對指定的容器有意義,並且不能在默認bridge
上的其他容器上運行。
另外,如果容器屬於多個網絡,則給定的鏈接別名與給定的網絡範圍一致。 因此,容器可以鏈接到不同網絡中的不同別名,並且別名將不適用於不在同一網絡上的容器。
以下示例說明了這些要點。
-
創建另一個名爲
local_alias
網絡:$ docker network create -d bridge --subnet 172.26.0.0/24 local_alias 76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa
-
接下來,使用別名
foo
和bar
將container4
和container5
連接到新的網絡local_alias
:$ docker network connect --link container5:foo local_alias container4 $ docker network connect --link container4:bar local_alias container5
-
attach到
container4
並嘗試使用別名foo
pingcontainer4
(是的,同一個),然後嘗試使用別名c5
ping容器container5
:$ docker attach container4 / # ping -w 4 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 c5 PING c5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms --- c5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
兩個ping都成功了,但子網不同,這意味着網絡不同。
離開
container4
,並使用CTRL-p CTRL-q
使其保持運行。 -
從
isolated_nw
網絡斷開container5
。 附加到container4
並嘗試pingc5
和foo
。$ docker network disconnect isolated_nw container5 $ docker attach container4 / # ping -w 4 c5 ping: bad address 'c5' / # ping -w 4 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
您不能再從
container5
收到isolated_nw
網絡上的container5
。 但是,您仍然可以使用別名foo
到達container4
(從container4
)。離開
container4
,並使用CTRL-p CTRL-q
使其保持運行。
docker network
限制
雖然docker network
是控制您的容器使用的網絡的推薦方法,但它確實有一些限制。
環境變量注入
環境變量注入是靜態的,環境變量在容器啓動後無法更改。 遺留的--link
標誌將所有環境變量共享到鏈接的容器,但docker network
命令沒有等效選項。 當您使用docker network
將容器連接到網絡時,不能在容器之間動態共享環境變量。
使用網絡範圍的別名
遺留的link提供傳出名稱解析,隔離在配置別名的容器內。 網絡範圍的別名不允許這種單向隔離,而是爲網絡的所有成員提供別名。
以下示例說明了此限制。
-
在網絡
isolated_nw
創建另一個容器container6
,並給它網絡別名app
。$ docker run --network=isolated_nw -itd --name=container6 --network-alias app busybox 8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17
-
attach到
container4
。 嘗試通過名稱(container6
)和網絡別名(app
)ping容器。 請注意,IP地址是一樣的。$ docker attach container4 / # ping -w 4 app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms --- app ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 container6 PING container5 (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms --- container6 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
從
container4
離開,並使用CTRL-p CTRL-q
使其保持運行。 -
將
container6
連接到local_alias
網絡,併爲其賦予網絡範圍的別名scoped-app
。$ docker network connect --alias scoped-app local_alias container6
現在
container6
在網絡isolated_nw
中的別名爲app
,在網絡local_alias
中別名爲scoped-app
。 -
嘗試從
container4
(連接到這兩個網絡)和container5
(僅連接到isolated_nw
)連接到這些別名。$ docker attach container4 / # ping -w 4 scoped-app PING foo (172.26.0.5): 56 data bytes 64 bytes from 172.26.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.5: seq=3 ttl=64 time=0.097 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
離開
container4
,並使用CTRL-p CTRL-q
使其保持運行。$ docker attach container5 / # ping -w 4 scoped-app ping: bad address 'scoped-app'
離開
container5
,並使用CTRL-p CTRL-q
使其保持運行。這表明將別名僅在定義它的網絡上生效,只有連接到該網絡的容器才能訪問該別名。
將多個容器解析爲一個別名
多個容器可在同一網絡內共享相同的網絡範圍別名。 這提供了一種DNS輪詢(round-robbin)高可用性。 當使用諸如Nginx這樣的軟件時,這可能不可靠,Nginx通過IP地址來緩存客戶端。
以下示例說明了如何設置和使用網絡別名。
注意 :使用網絡別名進行DNS輪詢高可用的用戶應考慮使用swarm服務。 Swarm服務提供了開箱即用的、類似的負載均衡功能。 如果連接到任何節點,即使是不參與服務的節點。 Docker將請求發送到正在參與服務的隨機節點,並管理所有的通信。
-
在
isolated_nw
中啓動container7
,別名與container6
相同,即app
。$ docker run --network=isolated_nw -itd --name=container7 --network-alias app busybox 3138c678c123b8799f4c7cc6a0cecc595acbdfa8bf81f621834103cd4f504554
當多個容器共享相同的別名時,其中一個容器將解析爲別名。 如果該容器不可用,則另一個具有別名的容器將被解析。 這提供了羣集中的高可用性。
注意 :在IP地址解析時,所選擇的容器是不完全可預測的。 因此,在下面的練習中,您可能會在一些步驟中獲得不同的結果。 如果步驟假定返回的結果是
container6
但是您收到container7
,這就是爲什麼。 -
從
container4
開始連續ping到app
別名。$ docker attach container4 $ ping app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms ...
返回的IP地址屬於
container6
。 -
在另一個終端,停止
container6
。$ docker stop container6
在連接到
container4
的終端 ,觀察ping
輸出。 當container6
關閉時,它將暫停,因爲ping
命令在首次調用時查找IP,並且發現該IP不再可用。 但是,ping
命令在默認情況下具有非常長的超時時間,因此不會發生錯誤。 -
使用
CTRL+C
退出ping
命令並再次運行。$ ping app PING app (172.25.0.7): 56 data bytes 64 bytes from 172.25.0.7: seq=0 ttl=64 time=0.095 ms 64 bytes from 172.25.0.7: seq=1 ttl=64 time=0.075 ms 64 bytes from 172.25.0.7: seq=2 ttl=64 time=0.072 ms 64 bytes from 172.25.0.7: seq=3 ttl=64 time=0.101 ms ...
app
別名現在解析爲container7
的IP地址。 -
最後一次測試,重新啓動
container6
。$ docker start container6
在連接到
container4
的終端,再次運行ping
命令。 現在可能會再次解決container6
。 如果您幾次啓動和停止ping
,您將看到每個容器的響應。$ docker attach container4 $ ping app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms ...
用
CTRL+C
停止ping。 從container4
離開,並使用CTRL-p CTRL-q
使其保持運行。
斷開容器
您可以隨時使用docker network disconnect
命令斷開容器與網絡的連接。
-
從
isolated_nw
網絡斷開container2
,然後檢查container2
和isolated_nw
網絡。$ docker network disconnect isolated_nw container2 $ docker inspect --format='' container2 | python -m json.tool { "bridge": { "NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", "EndpointID": "9e4575f7f61c0f9d69317b7a4b92eefc133347836dd83ef65deffa16b9985dc0", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03" } } $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1/16" } ] }, "Containers": { "467a7863c3f0277ef8e661b38427737f28099b61fa55622d6c30fb288d88c551": { "Name": "container3", "EndpointID": "dffc7ec2915af58cc827d995e6ebdc897342be0420123277103c40ae35579103", "MacAddress": "02:42:ac:19:03:03", "IPv4Address": "172.25.3.3/16", "IPv6Address": "" } }, "Options": {} } ]
-
當容器與網絡斷開連接時,它不能再與連接到該網絡的其他容器進行通信,除非它與其他容器具有g共用他網絡。 驗證
container2
不能再到達isolated_nw
上的container3
。$ docker attach container2 / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / # ping container3 PING container3 (172.25.3.3): 56 data bytes ^C --- container3 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss
-
驗證
container2
是否仍具有與默認bridge
完全連接。/ # ping container1 PING container1 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.119 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.174 ms ^C --- container1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.119/0.146/0.174 ms / #
-
移除
container4
,container5
,container6
和container7
。$ docker stop container4 container5 container6 container7 $ docker rm container4 container5 container6 container7
處理過時的網絡端點
在某些情況下,例如在多主機網絡中以非優雅的方式重新啓動Docker daemon,Docker daemon將無法清除過時的連接端點。 如果新的容器連接到具有與過期端點相同的名稱的網絡,則此類過時的端點可能會導致錯誤:
ERROR: Cannot start container bc0b19c089978f7845633027aa3435624ca3d12dd4f4f764b61eac4c0610f32e: container already connected to network multihost
要清理這些過時的端點,可移除容器並強制將其與網絡斷開( docker network disconnect -f
)。 這樣,您就可將容器成功連接到網絡。
$ docker run -d --name redis_db --network multihost redis
ERROR: Cannot start container bc0b19c089978f7845633027aa3435624ca3d12dd4f4f764b61eac4c0610f32e: container already connected to network multihost
$ docker rm -f redis_db
$ docker network disconnect -f multihost redis_db
$ docker run -d --name redis_db --network multihost redis
7d986da974aeea5e9f7aca7e510bdb216d58682faa83a9040c2f2adc0544795a
刪除網絡
當網絡中的所有容器都已停止或斷開連接時,您可以刪除網絡。 如果網絡連接了端點,則會發生錯誤。
-
斷開
container3
與isolated_nw
連接。$ docker network disconnect isolated_nw container3
-
檢查
isolated_nw
以驗證沒有其他端點連接到它。$ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1/16" } ] }, "Containers": {}, "Options": {} } ]
-
刪除
isolated_nw
網絡。$ docker network rm isolated_nw
-
列出所有網絡以驗證
isolated_nw
不再存在:$ docker network ls NETWORK ID NAME DRIVER SCOPE 4bb8c9bf4292 bridge bridge local 43575911a2bd host host local 76b7dc932e03 local_alias bridge local b1a086897963 my-network bridge local 3eb020e70bfd none null local 69568e6336d8 simple-network bridge local
相關信息
原文
https://docs.docker.com/engine/userguide/networking/work-with-networks/