ทำความเข้าใจ Docker Network


Network inteface แบบ พื้นๆ เมื่อสร้าง server ขึ้นมา

$ ip addr
...
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 9a:b6:0d:02:2a:80 brd ff:ff:ff:ff:ff:ff
    inet 178.128.126.91/20 brd 178.128.127.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.15.0.6/16 brd 10.15.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2400:6180:0:d1::4fb:a001/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::98b6:dff:fe02:2a80/64 scope link
       valid_lft forever preferred_lft forever

จะมีแบบเดิมๆ อยู่ 2 ตัว คือ

  • lo ( loobback interfaces )
    เอาไว้ใส่ IP address ประจำตัว Router และ loopback interface นี้ไม่มีวัน Down หรือ เปลี่ยนแปลง ตราบใดที่ Router ยังทำงานอยู่ก็สามารถอ้างอิงถึง IP address นี้ได้ตลอด
  • eth0
    คือ interface ชนิด ethernet interface ที่ชื่อ eth ขึ้นมา โดย ethernet ตัวแรก เราจะตั้งชื่อเป็น eth0 ถ้าเรามี ethernet มากกว่าหนึ่งตัวก็สามารถเรียกเป็น eth1 eth2 … ไปจนครบจำนวน ethernet

เมื่อเราทำการติดตั้ง Docker

$ ip addr
...
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 9a:b6:0d:02:2a:80 brd ff:ff:ff:ff:ff:ff
    inet 178.128.126.91/20 brd 178.128.127.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.15.0.6/16 brd 10.15.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2400:6180:0:d1::4fb:a001/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::98b6:dff:fe02:2a80/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:77:ed:32:69 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

จะได้ network interface เพิ่มมาอีกตัวคือ docker0
ซึ่งเป็น network ของ docker เลย เมื่อมีการ สร้าง container ขึ้น ip ที่ได้ะถูกจับ เข้ามาอยู่ใน network ตัวนี้โดย อัตโนมัติ


เมื่อเราติดตั้ง Docker เราจะได้ network default ใน docker0 มาทั้งหมด สามตัว

$ docker network ls
...
NETWORK ID          NAME                DRIVER              SCOPE
3227166132e5        bridge              bridge              local
ae562b91a256        host                host                local
da732c29fd29        none                null                local

Docker Network มีอะไรบ้าง

1. None Network

เป็น network แบบปิดไม่สามารถออกนอกได้และไม่สามารถเข้าถึงจาก host ได้

$ docker run --rm -it --network=none --name playground-network-none busybox ping 8.8.8.8
...
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Network is unreachable
failed to resize tty, using default size
$ docker run --rm -it --network=none busybox ifconfig
...
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:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

failed to resize tty, using default size

2. Host Network

เป็น network แบบ full access สามารถ จัดการและเข้าถึงได้จาก host

$ docker run --rm -it --network=host busybox ifconfig
...
docker0   Link encap:Ethernet  HWaddr 02:42:39:73:DA:BD
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:39ff:fe73:dabd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11296 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18268 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1434735 (1.3 MiB)  TX bytes:21757287 (20.7 MiB)

docker_gwbridge Link encap:Ethernet  HWaddr 02:42:A9:E6:43:2A
          inet addr:172.21.0.1  Bcast:172.21.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:a9ff:fee6:432a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:1566 (1.5 KiB)

eth0      Link encap:Ethernet  HWaddr 02:50:00:00:00:01
          inet addr:192.168.65.3  Bcast:192.168.65.255  Mask:255.255.255.0
          inet6 addr: fe80::50:ff:fe00:1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:476015 errors:0 dropped:0 overruns:0 frame:0
          TX packets:153523 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:700108451 (667.6 MiB)  TX bytes:8875942 (8.4 MiB)

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:5281 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5281 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1176193 (1.1 MiB)  TX bytes:1176193 (1.1 MiB)

veth3c9a665 Link encap:Ethernet  HWaddr 1A:B8:B1:94:3A:F7
          inet6 addr: fe80::18b8:b1ff:fe94:3af7/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1099 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1464 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:677560 (661.6 KiB)  TX bytes:201423 (196.7 KiB)

vethae12dee Link encap:Ethernet  HWaddr 86:6C:0D:4A:5D:B1
          inet6 addr: fe80::846c:dff:fe4a:5db1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:196 errors:0 dropped:0 overruns:0 frame:0
          TX packets:312 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:43510 (42.4 KiB)  TX bytes:36514 (35.6 KiB)

vethef548b7 Link encap:Ethernet  HWaddr C2:B2:95:B2:83:B4
          inet6 addr: fe80::c0b2:95ff:feb2:83b4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:3132 (3.0 KiB)

3. Bridge Network

เป็น network default ของ Docker เมือทำการสร้าง container Docker จะสร้าง Subnet และ Gateway ของ network นี้ให้อัตโนมัติ

$ docker run --rm -it  busybox ifconfig
...
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5 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:482 (482.0 B)  TX bytes:0 (0.0 B)

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:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

failed to resize tty, using default size
$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "3227166132e5dc873607d5df4de4b80ed9cbc5bdb70a082b49a11bc6a91b7e88",
        "Created": "2020-07-17T03:24:20.029193137Z",
        "Scope": "local",
        "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": {
            "57395cceb68ed2043415a11a18446ecd89ab7ef8e77b9bc44d6467a5dc939aa4": {
                "Name": "mongo",
                "EndpointID": "6dadde520e9ab656bcdf93a7f698c20920287a658619d1209399d178d796bfc0",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "d2e7724fa685f1c779e4b7d446f0d13b4ec732fe88fc27b1270eaeaab369c494": {
                "Name": "lotto-database",
                "EndpointID": "f2882ed75a5e890df44ddea965937b52a6b4f88e9f1485a6cdc077599dff585f",
                "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": {}
    }
]

ซึ่งใน container ที่ได้จะมี network interface อยู่ สองตัวคือ et0 ( private network interface ) และ lo ( loopback interface ) และ ภายใน network bridge สามารถ ติดต่อ กันได้ เหมือนเป็น private ip

4. Overlay Network

การทำให้ container ที่มีการคุยกันข้าม host network ( docker daemon ) ได้ ยกตัวอย่างในกรณีที่ต้องการ ทำ distributed network หรือ การทำ swarm ซึ่งอยู่กันคนละ host network ในสามารถ คุยกันได้

5. MacVlan Network

สามารถ assign Physical Network หรือ Mac Address เข้าไปยัง Container ตรงๆ ได้

$ docker network create -d macvlan \
  --subnet=172.16.86.0/24 \
  --gateway=172.16.86.1 \
  -o parent=eth0 \
  my-macvlan-net
$ docker run --net=my-macvlan-net --ip=172.16.86.xxx --mac-address 00:50:56:00:60:42 -it nginx bash

เพิ่มเติม docs.docker.com/network/macvlan


ทั้ง นี้ เป็นการทำความเข้าใจ หลังจาก อ่านมาจากบทความต่างๆ อาจมีบางอย่างที่เข้าใจผิดหรือผิดพลาดอย่างไร สามารถแนะนำเพิ่มเติมได้ครับ

July 18, 2020