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

Custom Networks และการแยก Container

การใส่ container ทั้งหมดไว้บน network เดียวกันหมายความว่าพวกเขาสามารถสื่อสารกันได้ทั้งหมด — ไม่ว่าจะเป็น frontend กับ database หรือ microservice กับ microservice อื่นที่ไม่ควรรู้จักกัน

การสร้าง network แยกสำหรับแต่ละ tier ของ application ช่วยให้คุณ:

  • จำกัดการสื่อสารเฉพาะที่จำเป็น
  • ลดพื้นที่การโจมตีหากมี container ถูก compromise
  • สร้างสถาปัตยกรรมที่ชัดเจนและ document ตัวเองได้

สร้าง network สอง network สำหรับ frontend และ backend:

Terminal window
docker network create frontend-net
docker network create backend-net
Terminal window
docker run -d --name frontend --network frontend-net nginx:alpine
docker run -d --name database --network backend-net postgres:alpine

frontend และ database อยู่คนละ network จึงสื่อสารกันไม่ได้โดยค่าเริ่มต้น

Terminal window
docker exec frontend ping -c 2 database || echo "Cannot reach database"

การ ping ล้มเหลวตามที่คาดหวัง เพราะ frontend อยู่บน frontend-net และ database อยู่บน backend-net

หากต้องการให้ frontend เข้าถึง database ได้ ให้เชื่อมต่อ frontend เข้ากับ backend-net:

Terminal window
docker network connect backend-net frontend

ตอนนี้ frontend อยู่บนทั้งสอง network และสามารถ ping database ได้

Terminal window
docker network disconnect backend-net frontend
Terminal window
docker stop frontend database
docker rm frontend database
docker network rm frontend-net backend-net
# Create two isolated networks
docker network create frontend-net
docker network create backend-net

# Run containers on separate networks
docker run -d --name frontend --network frontend-net nginx:alpine
docker run -d --name database --network backend-net postgres:alpine

# frontend cannot reach database (different networks)
docker exec frontend ping -c 2 database || echo "Cannot reach database"

# Connect frontend to backend-net so it can reach the database
docker network connect backend-net frontend

# Now frontend can reach database
docker exec frontend ping -c 2 database

# Inspect a network
docker network inspect frontend-net

# Disconnect
docker network disconnect backend-net frontend

# Cleanup
docker stop frontend database && docker rm frontend database
docker network rm frontend-net backend-net
ตัวเลือกBenefitCost
รวม container ทั้งหมดไว้บน network เดียวตั้งค่าเร็ว ไม่ต้องคิดเรื่อง network topologycontainer ทุกตัวมองเห็นและเข้าถึงกันได้หมด เพิ่มพื้นที่การโจมตีโดยไม่จำเป็น
แยก network ตาม tier (frontend/backend/data)จำกัดการสื่อสารเฉพาะที่จำเป็น ลดผลกระทบหากมี container ถูก compromiseต้องบริหารจัดการหลาย network และ connect/disconnect container เอง
  • ใส่ container ที่ไม่เกี่ยวข้องกันทั้งหมดไว้บน network เดียว (หรือปล่อยไว้บน default bridge) ทำให้ database ถูกเข้าถึงได้จาก container ไหนก็ได้ที่รันอยู่บนเครื่องเดียวกัน
  • ลืมว่า docker network connect เชื่อม container เข้ากับ network เพิ่มได้ แต่ต้อง docker network disconnect ออกเองด้วยเหมือนกัน ไม่ได้หลุดออกเองเมื่อ container หยุดทำงาน
  • ใช้ network เดียวกันสำหรับทุก environment (dev/staging/prod) ทำให้ container จากคนละ environment ปนกันโดยไม่ได้ตั้งใจ

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

Docker Compose สร้าง user-defined network แยกให้แต่ละโปรเจกต์โดยอัตโนมัติ (ตั้งชื่อตาม project directory เช่น myapp_default) เพื่อให้ service ในโปรเจกต์หนึ่งไม่ชนหรือมองเห็น container ของอีกโปรเจกต์บนเครื่อง dev เดียวกัน — เป็น pattern มาตรฐานสำหรับ multi-project local development

Container สองตัวอยู่บน user-defined bridge network ที่ต่างกัน สามารถสื่อสารกันได้โดยค่าเริ่มต้นหรือไม่?
คุณมี container ชื่อ 'api' ที่กำลังรันอยู่และต้องการเชื่อมต่อกับ network ชื่อ 'data-net' โดยไม่รีสตาร์ท คำสั่งใดที่ใช้?
คุณลอง docker network rm mynet แต่ได้รับ error ว่า network มี active endpoints สิ่งที่ต้องทำก่อนคืออะไร?
ใน three-tier app คุณต้องการให้ database container เข้าถึงได้โดย API server แต่ไม่ใช่ frontend proxy การออกแบบ network ที่ถูกต้องคืออะไร?