Docker container เป็นเสมือนคอมเครื่องย่อมๆ เครื่องนึงที่รันอยู่ในคอมจริงๆ อีกที มีความเป็นเอกเทศ แล้วถ้าเราต้องการแต่ละ container สามารถเชื่อมต่อกันได้ล่ะ เราจะทำยังไงได้บ้างนะ?

Docker container สามารถคุยกันระหว่าง container ได้ด้วย network ของมันเอง ที่จะเรียกว่า bridge โดย bridge แบ่งเป็นสองประเภท คือ

  1. Default bridge หรือ bridge เริ่มต้น คือ bridge ที่ Docker สร้างมาให้ตั้งแต่แรก และ container ที่เปิดใช้งานอยู่ก็จะเข้าไปอยู่ใน Default bridge โดยอัตโนมัติ และเราสามารถใช้ local IP ของ container ใน default bridge นี้เพื่อเชื่อมต่อไปยัง container นั้นๆ ได้
  2. User-defined bridge เป็น bridge ที่เราสร้างมาเอง ซึ่งดีกว่าตรงที่ เราอ้างอิง container อื่นด้วยชื่อได้ และสามารถจัดการ container ในแต่ละ bridge ได้เอง ก็เป็นความปลอดภัยอีกแบบนึงฮะ

ข้อมูล Bridge ของ container

เราสามารถดู IP ของ container ตัวนี้ รวมไปถึง container นี้ผูกกับ bridge อะไรบ้าง ด้วยคำสั่ง

docker inspect -f '{{json .NetworkSettings.Networks}}' container_name | json_pp

-f คือ จัด format มันตามด้วย '{{json .NetworkSettings.Networks}}' แปลว่าแปลงให้เป็น JSON format แล้วไปหาค่าใน jsonpath $.NetworkSettings.Networks จากนั้นก็ใช้ json_pp (JSON Pretty Print) เพื่อจัดให้เป็นรูปแบบ json ที่สวยงาม จะได้ผลลัพท์หน้าตาประมาณนี้นะฮะ

{
   "bridge" : {
      "GlobalIPv6PrefixLen" : 0,
      "Aliases" : null,
      "IPPrefixLen" : 16,
      "IPv6Gateway" : "",
      "IPAddress" : "172.17.0.4",
      "Gateway" : "172.17.0.1",
      "EndpointID" : "5d72289befb7a1bbaad35b4042dc3ae59fde42c90317d9d70c87b3038008607e",
      "MacAddress" : "02:42:ac:11:00:04",
      "DriverOpts" : null,
      "IPAMConfig" : null,
      "NetworkID" : "e6c26e049348db683f946490bd80d3fcc803578fd8ec1abae41c3b1b7e84ce5f",
      "Links" : null,
      "GlobalIPv6Address" : ""
   }
}
ตัวอย่าง bridge information

“bridge” เป็นชื่อของ default bridge ฮะ และมันแปลว่า container ตัวนี้มี IP เป็น 172.17.0.4 ภายใน bridge นี้ เราสามารถใช้ container ตัวอื่นที่อยู่ใน bridge เดียวกัน ping หา IP นี้เจอได้ฮะ

เข้าถึงได้ด้วย IP

User-defined bridge

อย่างที่เล่าไปแล้วว่า เราสามารถสร้าง bridge เองได้ เพื่อความสะดวกและความปลอดภัยของการจัดการ container network ทีนี้ ถ้าเราต้องการสร้าง user-defined bridge เอง สามารถใช้คำสั่งพวกนี้ได้ฮะ

docker network create bridge_name

และลองดู bridge ทั้งหมด ด้วยคำสั่ง

docker network list

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

docker network connect bridge_name container_name
docker network disconnect bridge_name container_name

และใช้คำสั่งนี้ เพื่อดูข้อมูลของ bridge

docker network inspect bridge_name

เราจะรู้ได้เลยว่ามี container อะไรบ้างที่อยู่ใน bridge นี้ และมี IP เป็นอะไร

[
    {
        "Name": "test",
        "Id": "f8a27b4a91f1009aaaa123e193fde235524e5f47c139eb0ef4d7fde7845bc9ed",
        "Created": "2020-11-01T11:08:49.3282456Z",
        "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": {
            "9f149d228c696dc59ac5e3f36a472fb3ad3718fe6f430f8be9905fabdcd13161": {
                "Name": "cent02",
                "EndpointID": "d83a77953ef70310fb32ed4c80da8111390f4176c8958a1bc1985c60a2f430e4",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "f9a4d56b6f1c1316ad7f450c8bc1fc678bde07f495d2b363a839a49b8fd9601d": {
                "Name": "cent01",
                "EndpointID": "4853528b9c8883770276d68edd57be11fc4f8bdf25154011929662f5d3a789a9",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
ตัวอย่างผลลัพท์ docker network inspect

และแน่นอน ใน user-defined bridge เราสามารถติดต่อกันด้วย container name ได้แล้ว ไม่ต้องใช้ IP ตามรูปนี้ฮะ ซึ่งเราจะลอง ping ไปหา docker “cent01”

Container name can be reached now

และสุดท้ายถ้าเราไม่ใช้ bridge ตัวนี้แล้ว ก็ใช้คำสั่ง

docker network rm bridge_name

ก็เป็นอันเสร็จสิ้นฮะ


สำหรับงานไหนที่เราต้องการ run container หลายๆ ตัวมาเชื่อมต่อกัน ก็ใช้ bridge มาช่วยเบางานเราได้นะฮะ

References: