Tìm hiểu và làm việc với docker container networks (P1)
Bài viết này xin đưa ra cái nhìn tổng quan về default networking bên trong Docker native. Mô tả các loại network trong docker, làm thế nào để tạo ra chúng, các tài nguyên cần thiết để tạo network trên single host hoặc cluster hosts. 1. Default Networks Khi bạn cài đặt xong Docker, sẽ có 3 ...
Bài viết này xin đưa ra cái nhìn tổng quan về default networking bên trong Docker native. Mô tả các loại network trong docker, làm thế nào để tạo ra chúng, các tài nguyên cần thiết để tạo network trên single host hoặc cluster hosts.
1. Default Networks
Khi bạn cài đặt xong Docker, sẽ có 3 loại networks được tự động tạo ra. Chúng ta có thể liệt kê tất cả bằng câu lệnh docker network ls:
$ docker network ls NETWORK ID NAME DRIVER 7fca4eb8c647 bridge bridge 9f904ee27bf5 none null cf03ee007fb4 host host
Ở đây chúng ta có 3 loại networks mặc định của docker, Khi bạn run một container, bạn có thể sử dụng flag: --network để chỉ định loại network mà bạn muốn container chạy trên đó khi run. Vì mặc định được tao ra bởi docker, nên bạn có thể sử dụng nó bất cứ khi nào cần.
bridge network được thể hiện bởi docker0 network. Trù khi bạn chỉ định một option network khác bằng lệnh docker run --network=<NETWORK>, nếu ko Docker daemon sẽ tự động connect các containers tới loại network này. Bạn có thể thấy bridge như một phần của host’s network stack bằng cách sử dụng câu lệnh ifconfig trên host:
$ ifconfig docker0 Link encap:Ethernet HWaddr 02:42:47:bc:3a:eb inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:47ff:febc:3aeb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:17 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:1100 (1.1 KB) TX bytes:648 (648.0 B)
none network thêm một container vào container-specific network stack. Container này bị thiếu network interface. Thử attach một container và xem điều gì đã diễn ra :v
$ docker attach nonenetcontainer root@0cb243cd1293:/# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters root@0cb243cd1293:/# ifconfig 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) root@0cb243cd1293:/#
host network thêm một container lên hosts network stack. Bạn có thể tìm thấy network configuration bên trong container đồng nhất với host.
Ngoại trừ bridge network, bạn ko thực sự cần tương tác với default networks. Khi bạn có thể list hoặc inspect chúng, tuy nhiên bạn không thể xóa chúng. Ngoài default network, ta có thể add thêm user-defined networks, có thể xóa khi ko muốn dùng. Trước khi học cách để tạo ra networks, chúng ta sẽ tìm hiểu một chút về default bridge network.
Bridge network
Default bridge network được hiện diện trên tất cả các Docker hosts. Câu lệnh docker network inspect trả lại các thông tin về network:
$ docker network inspect bridge [ { "Name": "bridge", "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.17.0.1/16", "Gateway": "172.17.0.1" } ] }, "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": "9001" } } ]
Docker Engine tự động tạo ra Subnet và Gateway tới network. Trong khi câu lệnh docker run tự động add container mới tạo vào chính network này:
$ docker run -itd --name=container1 busybox 3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c $ docker run -itd --name=container2 busybox 94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c
Thử inspect bridge network lại, sau khi chạy 2 containers chúng ta sẽ thấy id của container hiển thị trên “Containers” section:
$ docker network inspect bridge {[ { "Name": "bridge", "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.17.0.1/16", "Gateway": "172.17.0.1" } ] }, "Containers": { "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": { "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": { "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48", "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": "9001" } } ]
Câu lệnh docker network inspect hiển thị toàn bộ các container được kết nối và network resources của loại network được truyền vào. Containers trong default network có thể giao tiếp với nhau bằng IP addresses. Docker không hỗ trợ tự động quét service trên default bridge network. Nếu bạn muốn giao tiếp thông qua container names trong default bridge network, bạn phải kết nối các containers với nhau thông qua docker run --link option.
Bạn có thể attach & chạy một container, và xem thông tin về configuration:
$ docker attach container1 root@0cb243cd1293:/# ifconfig ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:16 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:1296 (1.2 KiB) 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)
Hãy thử sử dụng ping để gửi 3 ICMP requests, và test kết nối của các containers trên bridge network.
root@0cb243cd1293:/# ping -w3 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.096 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.074 ms --- 172.17.0.3 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.074/0.083/0.096 ms
Cuối cùng, hãy sử dụng câu lệnh cat để kiểm tra cấu hình network container1:
root@0cb243cd1293:/# cat /etc/hosts 172.17.0.2 3386a527aa08 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Để detach ra khỏi container1 nhưng vẫn muốn chúng tiếp tục running, ta sử dụng CTRL-p CTRL-q. Sau đó attach container2 và lặp lại 3 câu lệnh: ifconfig, ping, cat.
$ docker attach container2 root@0cb243cd1293:/# 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:15 errors:0 dropped:0 overruns:0 frame:0 TX packets:13 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1166 (1.1 KiB) TX bytes:1026 (1.0 KiB) 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) root@0cb243cd1293:/# ping -w3 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.067 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 --- 172.17.0.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.067/0.071/0.075 ms / # cat /etc/hosts 172.17.0.3 94447ca47985 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Mặc định docker0 bridge network hỗ trợ sử dụng port mapping và docker run --link cho phép các containers giao tiếp với nhau qua docker0 network.
2. User-defined networks
Bạn có thể tạo ra user-defined networks, Docker cung cấp một vài default network drivers cho việc create networks. Bạn có thể tạo ra 1 bridge network mới hoàn toàn hoặc overlay network hoặc MACVLAN network. Bạn cũng có thể tạo ra network plugin hoặc remote network.
Docker cho phép ta tạo nhiều network, Một network có thể có nhiều containers, các containers chỉ có thể communicate với nhau bên trong network, một container được attached vào 2 network.
A bridge network
user-defined network dễ dàng tạo ra nhất là bridge network. Network này tương tự default docker0 network.
$ docker network create --driver bridge isolated_nw 1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1/16" } ] }, "Containers": {}, "Options": {} } ] $ docker network ls NETWORK ID NAME DRIVER 9f904ee27bf5 none null cf03ee007fb4 host host 7fca4eb8c647 bridge bridge c5ee82f76de3 isolated_nw bridge
Sau khi tạo ra network, bạn có thể chạy containers trên đó bằng cách sử dụng docker run --network=<NETWORK> option.
$ docker run --network=isolated_nw -itd --name=container3 busybox 8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ {} ] }, "Containers": { "8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c": { "EndpointID": "93b2db4a9b9a997beb912d28bcfc117f7b0eb924ff91d48cfa251d473e6a9b08", "MacAddress": "02:42:ac:15:00:02", "IPv4Address": "172.21.0.2/16", "IPv6Address": "" } }, "Options": {} } ]
Container mà bạn chạy trên network này đều phải thuộc về cùng một Docker host. Mỗi container trong network có thể communicate với các containers khác trong cùng network.
linking không được hỗ trợ bên trong một user-defined bridge network. Bạn có thể expose và publish container ports trên các containers trong network này. Điều này rất hữu ích nếu bạn muốn tạo ra 1 phầm của bridge network available với một outside network.
bridge network rất hữu ích trong các trường hợp mà ở đó ta muốn chạy một relatively small network trên single host. Tuy nhiên chúng ta có thể tạo ra các networks lớn hơn bằng cách tạo một overlay network.
An overlay network with Docker Engine swarm mode
Bạn có thể tạo ra một overlay network trên một manager node running trong swarm mode mà không cần tới một external key-value store. Swarm tạo ra overlay network chỉ available với các nodes bên trong swarm. Khi bạn tạo ra một service sử dụng overlay network, manager node sẽ tự động kế thừa overlay network tới các nodes chạy các service tasks.
Ví dụ sau sẽ hướng dẫn cách tạo ra một network và sử dụng nó cho một service từ một manager node bên trong swarm:
# Create an overlay network `my-multi-host-network`. $ docker network create --driver overlay --subnet 10.0.9.0/24 my-multi-host-network 400g6bwzd68jizzdx5pgyoe95 # Create an nginx service and extend the my-multi-host-network to nodes where # the service's tasks run. $ $ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx 716thylsndqma81j6kkkb5aus
An overlay network with an external key-value store
Nếu bạn không sử dụng Docker Engine trong swarm mode, thì overlay network yêu cầu phải có một valid key-value store service. Hỗ trợ key-value stores gồm có Consul, Etcd, và ZooKeeper (Distributed store).
Chú ý: Docker Engine chạy trong swarm mode không tương thích với networking sử dụng external key-value store.
Mỗi host trong network phải run một Docker Engine instance. Cách dễ dàng nhất để tạo ra các host là sử dụng Docker Machine.
Bạn nên open các ports của mỗi hosts.
Protocol | Port | Description |
---|---|---|
udp | 4789 | Data plane (VXLAN) |
tcp/udp | 7946 | Control plane |
key-value store service có thể yêu cầu thêm một vài port khác. Check vendor’s documentation và open bất kỳ required port nào cần thêm.