Docker Network Bridge Mode
今天要來了解 Docker 網路的相關基礎知識,網路相關的功能有一個專用的命令 docker network
我們試著輸入以下命令,查看有什麼功能可以使用
$ docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
接下來輸入 docker network ls
,列出目前所有 docker 網路,會列出三個預設的網路分別是
bridge
此為預設選擇的網路,如果沒有特別指定會選擇使用此網路,經常使用在 container 跟 container 內部需要互相溝通的場景host
不使用 docker 網路區段,直接使用 host 機器的的網路,可以直接在 host 機器搜尋到使用 host 模式的 containernone
使用 none 模式的 container 網路功能會被關閉
[node1] (local) root@192.168.0.8 ~
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
8de8a559d867 bridge bridge local
bea36735c2b3 host host local
be46e85defe6 none null local
我們來詳細看看 bridge 網路的內容,這個網路有一個 Subnet: 172.17.0.0/16
並且 Containers 目前為空,代表現在沒有container 在使用此網路
$ docker network inspect bridge
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "8de8a559d867d48cf4810fabec0e757a497bfb3ed555eed4e9ba4104d54dc8f5",
"Created": "2023-03-02T15:24:26.582911093Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
接下來在 host 機器上輸入 ifconfig
或者 ip addr show
,查看 host 主機上面的網路
這邊注意到 docker0
ip 為 172.17.0.1
, docker 預設使用的區段為 172.17.0.0/16
, 也可以按照公司規定修改此網路區段
[node1] (local) root@192.168.0.8 ~
$ ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:5C:74:6C:9B
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 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)
eth0 Link encap:Ethernet HWaddr 86:D6:D1:A4:CA:2F
inet addr:192.168.0.8 Bcast:0.0.0.0 Mask:255.255.254.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10 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:828 (828.0 B) TX bytes:0 (0.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:40
inet addr:172.18.0.64 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:140 errors:0 dropped:0 overruns:0 frame:0
TX packets:80 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:20328 (19.8 KiB) TX bytes:70585 (68.9 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:40 errors:0 dropped:0 overruns:0 frame:0
TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:4730 (4.6 KiB) TX bytes:4730 (4.6 KiB)
有了基礎概念後,可以來做幾個簡單的小測試,先建立一個自己的網路,使用-d
參數明確指定使用 bridge 模式
docker network create -d bridge my-bridge-network
並且輸入docker network inspect my-bridge-network
會發現我們的新建立的網路使用了172.19.0.0/16
這個區段
$ docker network inspect my-bridge-network
[
{
"Name": "my-bridge-network",
"Id": "23749258e265ffeae29a7805743dbf1ed7e36b765fb6eac69fc9cb02aa95c512",
"Created": "2023-03-02T15:26:43.454719222Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
接下來建立一個 nginx container 並開放 80 端口,注意這邊只有開啟 container 內部的 80 端口,並且使用我們建立的網路my-bridge-network
docker run -d -p 80 --network=my-bridge-network --name nginx nginx
完成後查看 container 的詳細資料,知道目前 nginx container 使用的 ip 是 172.19.0.2
$ docker inspect nginx
[
{
...
"Networks": {
"my-bridge-network": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"5cc7663c1bd6"
],
"NetworkID": "23749258e265ffeae29a7805743dbf1ed7e36b765fb6eac69fc9cb02aa95c512",
"EndpointID": "5f0007ea0229eef0cf4a859c7f5537b53b8886ba14ceb11103c31b44a8067c7c",
"Gateway": "172.19.0.1",
"IPAddress": "172.19.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:13:00:02",
"DriverOpts": null
}
}
}
}
]
接著在建立一個 alpine container ,並且安裝 curl
docker run -it --name alpine alpine
apk --no-cache add curl
安裝完成後我們可以試著在 alpine container 訪問我們的 nginx container
curl 172.19.0.2:80 --connect-timeout 5
結果顯示為超時,這樣是正常的因為我們剛剛建立 alpine container 時並沒有指定使用我們自己的網路,所以現在使用的是預設網路172.17.0.2
區段跟我們的 172.19.0.2
不同所以無法訪問
/ # curl 172.19.0.2:80 --connect-timeout 5
curl: (28) Failed to connect to 172.19.0.2 port 80 after 5001 ms: Timeout was reached
先使用快捷鍵 Ctrl + p
+ Ctrl + q
暫時脫離 alpine container
對於已經建立完成的 container 事後要在新增網路,可以使用以下命令
docker network connect my-bridge-network alpine
更換成功後再次進入 container,並再次訪問 nginx
docker exec -it alpine sh
curl 172.19.0.2:80 --connect-timeout 5
重新設定到同一區段後現在就可以成功訪問了
[node1] (local) root@192.168.0.8 ~
$ docker exec -it alpine sh
/ # curl 172.19.0.2:80 --connect-timeout 5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
這邊要注意使用 docker network connect
時並不會移除舊的網路,需要使用以下命令來移除
docker network disconnect bridge alpine
Summary
今天學習了 bridge 的基礎用法,概念其實跟我們平常設定虛擬機器的網路時一樣,並沒有什麼特殊的自創功能 之後會在更加深入了解 Docker 網路機制