ข้ามไปยังเนื้อหา

network Bridge เริ่มต้น

เมื่อ Docker daemon เริ่มต้น จะสร้าง virtual Ethernet switch ชื่อ docker0 บน host นี่คือ default bridge network ทุก container ที่คุณเริ่มต้นโดยไม่ระบุ --network จะถูกเชื่อมต่อกับ docker0 โดยอัตโนมัติ

Container บน default bridge จะได้รับ IP address จาก subnet 172.17.0.0/16 โดย gateway — และ host เอง — อยู่ที่ 172.17.0.1

flowchart TB
  host["Host"]
  bridge["docker0 (172.17.0.1)"]
  c1["container c1 (172.17.0.2)"]
  c2["container c2 (172.17.0.3)"]
  host --> bridge
  bridge --> c1
  bridge --> c2
Containers attached to the default docker0 bridge

เริ่มต้น nginx container ชื่อ c1 และ Alpine container ชื่อ c2:

Terminal window
docker run -d --name c1 nginx:alpine
docker run -d --name c2 alpine sleep 300

ตรวจสอบ IP address ที่ถูกกำหนดให้แต่ละ container:

Terminal window
docker inspect c1 --format '{{.NetworkSettings.IPAddress}}'
docker inspect c2 --format '{{.NetworkSettings.IPAddress}}'

คุณจะเห็น address เช่น 172.17.0.2 และ 172.17.0.3

เนื่องจากทั้งสอง container อยู่บน bridge docker0 เดียวกัน การ routing layer-3 ระหว่างพวกเขาจึงทำงานได้ จาก c2 ให้ ping c1 ด้วย IP address:

Terminal window
docker exec c2 ping -c 3 172.17.0.2

การ ping สำเร็จ traffic ไหลผ่าน docker0 บน host

ลองทำ ping เดิมโดยใช้ชื่อ container แทน IP:

Terminal window
docker exec c2 ping c1

คำสั่งนี้จะล้มเหลวด้วยข้อความ bad address 'c1' หรือ DNS error ที่คล้ายกัน Default bridge network ไม่มี embedded DNS resolver ดังนั้นจึงไม่สามารถ resolve ชื่อ container ได้ เฉพาะ user-defined network (ครอบคลุมในบทเรียนถัดไป) เท่านั้นที่ให้ DNS อัตโนมัติ

หยุดและลบทั้งสอง container เมื่อเสร็จสิ้น:

Terminal window
docker stop c1 c2
docker rm c1 c2
# Start two containers on the default bridge
docker run -d --name c1 alpine sleep 300
docker run -d --name c2 alpine sleep 300

# Find their IPs
C1_IP=$(docker inspect c1 --format '{{.NetworkSettings.IPAddress}}')
C2_IP=$(docker inspect c2 --format '{{.NetworkSettings.IPAddress}}')
echo "c1 IP: $C1_IP"
echo "c2 IP: $C2_IP"

# Ping c2 from c1 by IP (succeeds)
docker exec c1 ping -c 3 $C2_IP

# Try to ping by name (fails — no DNS on default bridge)
docker exec c1 ping -c 1 c2 || echo "Name resolution failed as expected"

# Cleanup
docker stop c1 c2 && docker rm c1 c2
ตัวเลือกBenefitCost
Default bridge (docker0)ใช้งานได้ทันทีโดยไม่ต้องตั้งค่าอะไรเพิ่มไม่มี DNS resolver ในตัว ต้องต่อกันด้วย IP address ล้วน ๆ
User-defined bridge networkมี embedded DNS resolver ให้ resolve ชื่อ container ได้ทันทีต้องรัน docker network create เพิ่มอีกขั้นก่อนใช้งาน
Host network modeperformance สูงสุด ไม่มี NAT overhead ระหว่าง container กับ hostไม่มี network isolation จาก host เลย container ใช้ network stack เดียวกับ host ตรง ๆ
  • Hardcode IP address ที่ได้จาก docker inspect ไว้ใน config เพราะคิดว่า IP จะคงที่ ทั้งที่ IP เปลี่ยนได้ทันทีเมื่อ container ถูก restart หรือสร้างใหม่
  • ใช้งาน default bridge ต่อไปแล้วพยายาม ping container ด้วยชื่อ โดยไม่รู้ว่า default bridge ไม่มี DNS resolver ให้ใช้
  • โยน container จากหลายโปรเจกต์ไว้บน default bridge เดียวกันโดยไม่แยก ทำให้ container ทุกตัวมองเห็นและเข้าถึงกันได้หมดโดยไม่ตั้งใจ

💡 ตัวอย่างจากของจริง

GitLab CI และ Jenkins ที่รัน Docker executor จะสร้าง bridge network แยกให้แต่ละ job แทนที่จะใช้ default bridge เพื่อให้ container หลักและ service container (เช่น database สำหรับเทส) resolve ชื่อกันได้ผ่าน DNS โดยไม่ชนกับ job อื่นที่รันขนานกันบน runner เดียวกัน

Default bridge network ของ Docker ใช้ subnet ใดสำหรับ IP address ของ container?
ทำไมการ ping container ด้วยชื่อถึงล้มเหลวบน default bridge network?
virtual Ethernet switch ที่ Docker สร้างขึ้นสำหรับ default bridge network มีชื่อว่าอะไร?
Container สองตัวอยู่บน default bridge network ข้อใดต่อไปนี้ถูกต้อง?