Phần 14 – Bridge network trong docker
Bài viết này giới thiệu Docker Bridge Network và cách thức hoạt động
Nội dung chính
Giới thiệu môi trường
Các xét nghiệm sau đây sẽ được thực hiện trong các môi trường sau:
- Hệ điều hành
Ubuntu 18.04
- Docker:
18.03.1-ce
Xem trạng thái Mạng Docker hiện tại
Sau đây là trạng thái mạng docker ngay sau khi docker 18.03.1 được cài đặt trên Ubuntu 18.04:
$ docker network ls NETWORK ID NAME DRIVER SCOPE a1c7b6f80389 bridge bridge local dc2f51e1056f host host local f28460d3a620 none null local
Như có thể thấy từ trên, chỉ cần cài đặt Docker Linux máy chủ, docker sẽ tạo ra 3 loại network mặc định đó là bridge
, host
cũng null
.
Sau đây sẽ giới thiệu chế độ hoạt động của mạng cầu một cách cẩn thận.
Tổng quát
Hãy bắt đầu với khái niệm Docker Bridge Network:
- Bridge Network tạo ra một cây cầu trên Docker Host để đạt được mục đích cho phép container kết nối với bên ngoài. Thông qua cây cầu này, các container của cùng một cây cầu có thể giao tiếp với nhau và trình điều khiển cầu docker sẽ tự động được đặt trên máy chủ. Quy tắc tương ứng (iptables, không gian tên mạng) cho phép mạng của bộ chứa được sử dụng chính xác.
- Bridge Network được sử dụng để xử lý giao tiếp giữa các container đang chạy trên một trình docker daemon duy nhất. Nếu bạn muốn giao tiếp các container trên nhiều server khác nhau, bạn phải sử dụng overlay network.
Hình dưới đây là kiến trúc của Bridge Network
Sử dụng Bridge Network (docker0)
Sau khi docker được cài đặt, trên thực tế docker đã chuẩn bị một cây cầu docker0
cho chúng ta như một cây cầu phần mềm bên ngoài của container. Ví dụ sau đây trước tiên sẽ sử dụng docker0 để thử nghiệm.
Tạo container
Đầu tiên tạo Container cần thiết và xem trạng thái network:
# tạo alpine linux container 1 (alpine1) $ docker run -dit --name alpine1 alpine ash b75464efd30bf09e118450de2abaeb35549e732bac5805671f1e6e97cd970897 # tạo alpine linux container 2 (alpine2) $ docker run -dit --name alpine2 alpine ash 16aa4a102b14de3e151cb5e19522925bb4e143034d5b2aac4ce239c79716b703 # kiểm tra software bridge status $ brctl show bridge name bridge id STP enabled interfaces docker0 8000.024284431eec no vethbddc381 vethee2a421 # xem trạng thái docker bridge network $ docker network inspect bridge [ { # docker network đang sử dụng là "bridge" "Name": "bridge", "Id": "a1c7b6f8038999f034b8e64ae66885fa8094a020a306ce4f5b5692d7230890b0", "Created": "2018-07-09T01:23:03.98371109Z", "Scope": "local", # driver đang dùng là bridge "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { # tên container alpine2 (tương ứng với container ID) "16aa4a102b14de3e151cb5e19522925bb4e143034d5b2aac4ce239c79716b703": { "Name": "alpine2", "EndpointID": "4dc3947583ece828dd4371351501e7d0ba9fa149ac5373ea4ddb9466d333b85d", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, # container alpine1 (tương ứng với container ID) "b75464efd30bf09e118450de2abaeb35549e732bac5805671f1e6e97cd970897": { "Name": "alpine1", "EndpointID": "ea0138a2c51812f3f142db086e1690f6696e36ff972c826727be30e3c8b8cb41", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "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", # tên bridge được sử dụng "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
Kiến trúc mạng hiện tại trở thành như sau:
Kiểm tra network container
Sau khi hiểu kiến trúc mạng ở trên, hãy kiểm tra mạng container:
# Xem container IP $ docker exec -it alpine1 ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever # Kiểm tra kết nối $ docker exec -it alpine1 ping -c 3 www.google.com PING www.google.com (216.58.200.228): 56 data bytes 64 bytes from 216.58.200.228: seq=0 ttl=54 time=2.112 ms 64 bytes from 216.58.200.228: seq=1 ttl=54 time=2.166 ms 64 bytes from 216.58.200.228: seq=2 ttl=54 time=2.417 ms # Kiểm tra có mạng với container khác (dùng IP) $ docker exec -it alpine1 ping -c 3 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.121 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.071 ms 64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.068 ms # Kiểm tra có mạng với container khác (dùng domain name) => không connect được $ docker exec -it alpine1 ping -c 3 alpine2 ping: bad address 'alpine2'
Từ thử nghiệm trên, chúng ta có thể thấy rằng trên thực tế, hai container docker0
có thể giao tiếp với nhau vì chúng sử dụng cùng một cây cầu ( ), nhưng chúng không thể sử dụng tên miền, có nghĩa là chúng không biết nhau.
Tạo một Bridge Network
Docker Network tùy chỉnh
Điều này cũng là việc sử dụng điều khiển Bridge Network, nhưng thông qua docker network create
việc tạo một Bridge Network mới, ở đây tên là alpine-net
:
$ docker network create --driver bridge alpine-net 2575acac8e781004cb0dc5c5b020c0252a4bc4cdf18dfc661fe3ffcde30fd0b2 $ docker network ls NETWORK ID NAME DRIVER SCOPE 2575acac8e78 alpine-net bridge local a1c7b6f80389 bridge bridge local dc2f51e1056f host host local f28460d3a620 none null local $ docker network inspect alpine-net [ { # docker bridge network đã được đổi tên "Name": "alpine-net", # ID của bridge "Id": "2575acac8e781004cb0dc5c5b020c0252a4bc4cdf18dfc661fe3ffcde30fd0b2", "Created": "2018-07-09T03:05:05.505539609Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] # đã thêm một software bridge $ brctl show bridge name bridge id STP enabled interfaces br-2575acac8e78 8000.0242a2569c8d no docker0 8000.024284431eec no # Cái bridge được sử dụng là 172.18.0.1/16 khác biệt với docker0 $ ip a .... () 14: br-2575acac8e78: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:a2:56:9c:8d brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-2575acac8e78 valid_lft forever preferred_lft forever
Có thể thấy từ các kết quả trên, mạng docker mới được tạo ( alpine-net
) sẽ được phân bổ để sử dụng một phân đoạn mạng khác, khác với docker0 ban đầu.
Tạo container
Ở đây để xây dựng tổng cộng bốn container, cụ thể là alpine1
, alpine2
, alpine3
và alpine4
làm cho các thiết lập mạng như sau:
ContainerDocker Networkalpine1alpine-netalpine2alpine-netalpine3docker0alpine4alpine-net + docker0
Và hoàn thành nó với các hướng dẫn sau:
# tạo container,sử dụng alpine-net $ docker run -dit --name alpine1 --network alpine-net alpine ash 010ba5c3e71a723f8c980bb00bb87c97bc41b073163415705006ce5d0071e97c # tạo container,sử dụng alpine-net $ docker run -dit --name alpine2 --network alpine-net alpine ash aecb66274c3b3ec9109ff4eaa582ad4708ed871428d3b4894f9d04330aabcbc4 # tạo container,sử dụng default bridge docker0 $ docker run -dit --name alpine3 alpine ash 3c602d26fcdcc8c0145d4d2d159b20b5b760c1b74393c7b5f7be060f4f8822ac # tạo container,sử dụng alpine-net $ docker run -dit --name alpine4 --network alpine-net alpine ash 83133e6103d63513116e0fb791efea64b016424ca73357ba3fed41b7ea92df95 # chỉnh sử alpine4 connect tới default bridge docker0 $ docker network connect bridge alpine4
Sau đó, đảm bảo rằng các cài đặt mạng có liên quan được thiết lập chính xác:
# Show veth device $ brctl show bridge name bridge id STP enabled interfaces br-2575acac8e78 8000.0242a2569c8d no veth19aee42 veth403e609 veth439dc39 docker0 8000.024284431eec no veth1c78e99 veth9857cc8 # Xem docker bridge - bridge(docker0) $ docker network inspect bridge [ { # tên docker network "Name": "bridge", "Id": "a1c7b6f8038999f034b8e64ae66885fa8094a020a306ce4f5b5692d7230890b0", "Created": "2018-07-09T01:23:03.98371109Z", "Scope": "local", #driver là bridge "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { # Đây là mạng được sử dụng bởi alpine3 (tương ứng với ID container ở trên) "3c602d26fcdcc8c0145d4d2d159b20b5b760c1b74393c7b5f7be060f4f8822ac": { "Name": "alpine3", "EndpointID": "7bd6ae1d8a28a554f57f9937953716cc5f62ea8bd669fc744d3aeffacf05f3c1", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, # Đây là mạng được sử dụng bởi alpine4 (tương ứng với ID container ở trên) "83133e6103d63513116e0fb791efea64b016424ca73357ba3fed41b7ea92df95": { "Name": "alpine4", "EndpointID": "2bb63005cf4bcb037d644ab230023e65e8ee9e00cf4d98b3fcf9526c14790492", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" } }, "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": {} } ] # xem docker bridge - alpine-net $ docker network inspect alpine-net [ { # tên docker network "Name": "alpine-net", "Id": "2575acac8e781004cb0dc5c5b020c0252a4bc4cdf18dfc661fe3ffcde30fd0b2", "Created": "2018-07-09T03:05:05.505539609Z", "Scope": "local", # driver là bridge "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { # Đây là mạng được sử dụng bởi alpine1 (tương ứng với ID container ở trên) "010ba5c3e71a723f8c980bb00bb87c97bc41b073163415705006ce5d0071e97c": { "Name": "alpine1", "EndpointID": "f1357dd263dea947c4cd203fd8031be40fae4840f6994dd5e11d6790a038569c", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, # Đây là mạng được sử dụng bởi alpine4 (tương ứng với ID container ở trên) "83133e6103d63513116e0fb791efea64b016424ca73357ba3fed41b7ea92df95": { "Name": "alpine4", "EndpointID": "cf6bb33270eca6d40d4d953cea49302d210bc8ba995f04cdcf138344d5378d2f", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, # Đây là mạng được sử dụng bởi alpine2 (tương ứng với ID container ở trên) "aecb66274c3b3ec9109ff4eaa582ad4708ed871428d3b4894f9d04330aabcbc4": { "Name": "alpine2", "EndpointID": "28a237e9fe55f133459140c9e5265470e34baeec43c2c0f6c32d5d539b694403", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
Vì alpine4 được kết nối cụ thể với hai mạng, hãy kiểm tra trạng thái mạng của alpine4:
# Như có thể thấy từ output bên dưới, vì alpine4 đã nhận được hai bridge nên hai card mạng sẽ được hiển thị. $ docker exec -it alpine4 ip a ..... (more) 21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever 23: eth1@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth1 valid_lft forever preferred_lft forever
Kiến trúc mạng hiện tại trở thành như sau:
Kiểm tra mạng container
Cuối cùng, hãy kiểm tra kết nối giữa các container:
# Kiểm tra giao tiếp với alpine2 $ docker exec -it alpine1 ping -c 2 alpine2 PING alpine2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.095 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.076 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.076/0.085/0.095 ms # Kiểm tra giao tiếp với alpine4 $ docker exec -it alpine1 ping -c 2 alpine4 PING alpine4 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.145 ms 64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.102 ms --- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.102/0.123/0.145 ms # Kiểm tra giao tiếp với alpine3 $ docker exec -it alpine1 ping -c 2 alpine3 ping: bad address 'alpine3' # Kiểm tra giao tiếp với alpine3 bằng IP $ docker exec -it alpine1 ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes --- 172.17.0.2 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss # Kiểm tra giao tiếp với alpine1 (riêng) $ docker exec -it alpine1 ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.052 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.079 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.052/0.065/0.079 ms # thử connect ra ngoài $ docker exec -it alpine1 ping -c 2 www.google.com PING www.google.com (172.217.160.68): 56 data bytes 64 bytes from 172.217.160.68: seq=0 ttl=53 time=7.252 ms 64 bytes from 172.217.160.68: seq=1 ttl=53 time=7.329 ms --- www.google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 7.252/7.290/7.329 ms
Các kết luận sau đây có thể được rút ra từ các thử nghiệm trên:
- Trong mạng docker được tạo, container có thể giao tiếp với các container khác trong cùng mạng docker thông qua tên miền
- Các mạng container giữa các mạng docker khác nhau được cách ly và không thể giao tiếp với nhau, cho dù thông qua tên miền hoặc IP
Kết luận đầu tiên là bởi vì docker sẽ cung cấp automatic service discovery cho mạng docker tự tạo , để các container có thể giao tiếp với nhau thông qua tên
Ngoài ra, nếu cùng lúc docker0
với alpine-net
hai Bridge Network được dùng cùng lúc bởi alpine4 thực hiện các bài kiểm tra trên container thì kết quả là gì?
# Có thể giao tiếp với container (alpine1) dưới bridge alpine-net theo name $ docker exec -it alpine4 ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.093 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.077 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.077/0.085/0.093 ms # Không thể liên lạc với container (alpine3) dưới bridge docker0 theo name $ docker exec -it alpine4 ping -c 2 alpine3 ping: bad address 'alpine3' # Nhưng vẫn có thể giao tiếp với container (alpine3) dùng docker0 qua IP $ docker exec -it alpine4 ping -c 2 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.140 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.092 ms --- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.092/0.116/0.140 ms # kiểm tra connect ra ngoài $ docker exec -it alpine4 ping -c 2 www.google.com PING www.google.com (172.217.160.68): 56 data bytes 64 bytes from 172.217.160.68: seq=0 ttl=53 time=7.429 ms 64 bytes from 172.217.160.68: seq=1 ttl=53 time=7.361 ms --- www.google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 7.361/7.395/7.429 ms
Các kết luận sau đây có thể được rút ra từ các thử nghiệm trên alpine4:
- Trong
docker0
container dưới bridge không thể giao tiếp với nhau thông qua tên miền - Bạn có thể sử dụng giao tiếp thông qua IP
Với các kết quả kiểm tra sau, nếu bạn muốn sử dụng tên miền để xử lý giao tiếp giữa các container, bạn phải nhớ thiết lập mạng docker mới để xử lý nó để có thể giao tiếp bình thường.
0
0
votes
Like this:
Like
Loading…