Custom Networks และการแยก Container
ทำไมต้องแยก Network
หัวข้อที่มีชื่อว่า “ทำไมต้องแยก Network”การใส่ container ทั้งหมดไว้บน network เดียวกันหมายความว่าพวกเขาสามารถสื่อสารกันได้ทั้งหมด — ไม่ว่าจะเป็น frontend กับ database หรือ microservice กับ microservice อื่นที่ไม่ควรรู้จักกัน
การสร้าง network แยกสำหรับแต่ละ tier ของ application ช่วยให้คุณ:
- จำกัดการสื่อสารเฉพาะที่จำเป็น
- ลดพื้นที่การโจมตีหากมี container ถูก compromise
- สร้างสถาปัตยกรรมที่ชัดเจนและ document ตัวเองได้
สร้าง Network ที่แยกกัน
หัวข้อที่มีชื่อว่า “สร้าง Network ที่แยกกัน”สร้าง network สอง network สำหรับ frontend และ backend:
docker network create frontend-netdocker network create backend-netรัน Container บน Network ที่ต่างกัน
หัวข้อที่มีชื่อว่า “รัน Container บน Network ที่ต่างกัน”docker run -d --name frontend --network frontend-net nginx:alpinedocker run -d --name database --network backend-net postgres:alpinefrontend และ database อยู่คนละ network จึงสื่อสารกันไม่ได้โดยค่าเริ่มต้น
ตรวจสอบว่า Container ไม่สามารถสื่อสารกันได้
หัวข้อที่มีชื่อว่า “ตรวจสอบว่า Container ไม่สามารถสื่อสารกันได้”docker exec frontend ping -c 2 database || echo "Cannot reach database"การ ping ล้มเหลวตามที่คาดหวัง เพราะ frontend อยู่บน frontend-net และ database อยู่บน backend-net
เชื่อมต่อ Container กับ Network เพิ่มเติม
หัวข้อที่มีชื่อว่า “เชื่อมต่อ Container กับ Network เพิ่มเติม”หากต้องการให้ frontend เข้าถึง database ได้ ให้เชื่อมต่อ frontend เข้ากับ backend-net:
docker network connect backend-net frontendตอนนี้ frontend อยู่บนทั้งสอง network และสามารถ ping database ได้
ตัดการเชื่อมต่อ Container จาก Network
หัวข้อที่มีชื่อว่า “ตัดการเชื่อมต่อ Container จาก Network”docker network disconnect backend-net frontendล้างข้อมูล
หัวข้อที่มีชื่อว่า “ล้างข้อมูล”docker stop frontend databasedocker rm frontend databasedocker network rm frontend-net backend-netลงมือปฏิบัติ: Custom Networks
หัวข้อที่มีชื่อว่า “ลงมือปฏิบัติ: Custom Networks”# 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ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| รวม container ทั้งหมดไว้บน network เดียว | ตั้งค่าเร็ว ไม่ต้องคิดเรื่อง network topology | container ทุกตัวมองเห็นและเข้าถึงกันได้หมด เพิ่มพื้นที่การโจมตีโดยไม่จำเป็น |
| แยก 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