Docker Certified Associate(DCA)認證考試學習- Docker Network Bridge Mode Docker Certified Associate(DCA)認證相關資源、Docker Network Bridge Mode

Published on Thursday, March 2, 2023

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 模式的 container
  • none 使用 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 網路機制