เนื้อหาในบทความนี้
บทนำ
ทำความเข้าใจพื้นฐาน Docker Compose Networking
Network Types
ประเภทของ networks ที่ใช้ใน Docker Compose
Configuration
การกำหนดค่า networks ใน docker-compose.yml
Examples
ตัวอย่างจริงในการใช้งาน networking
Security
Best practices ด้านความปลอดภัย
Troubleshooting
แก้ไขปัญหาที่พบบ่อย
บทนำสู่ Docker Compose Networking
การจัดการเครือข่าย (Networking) เป็นหัวใจสำคัญของ Docker Compose ที่ช่วยให้บริการต่างๆ สามารถสื่อสารกันได้อย่างมีประสิทธิภาพและปลอดภัย
ปัญหาที่มักเกิดขึ้นกับ Networking
- Service ไม่สามารถเชื่อมต่อหากันได้ (Connection refused)
- DNS ไม่ทำงาน ทำให้ไม่สามารถหา service ด้วยชื่อได้
- การ expose port ที่ไม่ควร expose ทำให้เกิดช่องโหว่ด้านความปลอดภัย
- IP Address conflicts ใน network ที่มีหลาย services
สิ่งที่คุณจะได้เรียนรู้
- แนวทางการสร้างและจัดการ networks อย่างถูกต้อง
- Service Discovery กับ DNS names
- Network isolation เพื่อความปลอดภัย
- Best practices สำหรับ production environments
โครงสร้างเครือข่ายใน Docker Compose
การทำงานของ Network ใน Docker Compose
Docker Compose จะสร้าง default network ให้อัตโนมัติสำหรับทุก services ในไฟล์ docker-compose.yml โดย services ที่อยู่ใน network เดียวกันจะสามารถเชื่อมต่อหากันได้ผ่านชื่อ service ที่กำหนด
Service Discovery
Services สามารถค้นหาและเชื่อมต่อกันผ่านชื่อได้โดยอัตโนมัติ
Network Isolation
แยก network สำหรับ services ที่ต้องการความปลอดภัยสูง
Port Management
ควบคุม port exposure เพื่อป้องกันช่องโหว่ด้านความปลอดภัย
ประเภทของ Networks ใน Docker Compose
Default Network
เมื่อคุณไม่ได้กำหนด network ใน docker-compose.yml Docker Compose จะสร้าง default bridge network ให้อัตโนมัติ Services ทั้งหมดจะอยู่ใน network เดียวกันและสามารถเชื่อมต่อกันได้
version: '3.8'
services:
web:
image: nginx
api:
image: node:18
ทั้ง web และ api services จะอยู่ใน network เดียวกันโดยอัตโนมัติ
Custom Networks
คุณสามารถกำหนด custom networks เพื่อแยก services ออกเป็นหลาย networks ตามความต้องการ ซึ่งช่วยให้สามารถควบคุมการเข้าถึงและความปลอดภัยได้ดีขึ้น
version: '3.8'
networks:
frontend:
backend:
services:
web:
image: nginx
networks:
- frontend
api:
image: node:18
networks:
- frontend
- backend
db:
image: postgres:15
networks:
- backend
External Networks
การใช้ external networks ช่วยให้ services จากหลาย docker-compose.yml files สามารถเชื่อมต่อกันได้ผ่าน network เดียวกัน
# สร้าง network ก่อน
$ docker network create shared-network
version: '3.8'
networks:
shared-network:
external: true
services:
web:
image: nginx
networks:
- shared-network
Network Drivers
Docker Compose รองรับหลาย network drivers ที่เหมาะสมกับ use cases ต่างๆ
- bridge - Default driver สำหรับ network ภายใน single host
- host - ใช้ network stack ของ host โดยตรง (ไม่มี network isolation)
- none - ไม่มี network interface (isolated completely)
การกำหนดค่า Networks ใน Docker Compose
Syntax พื้นฐาน
การกำหนดค่า networks ใน docker-compose.yml มีรูปแบบดังนี้:
version: '3.8'
networks:
# ชื่อของ network
my-network:
# กำหนดค่าเพิ่มเติม
driver: bridge
driver_opts:
com.docker.network.bridge.name: my-net-bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
# ทำให้ network ใช้งานได้จากภายนอก
external: false
# กำหนดชื่อ network ที่จะสร้าง
name: my-app-network
Network Options
-
driver- กำหนด network driver (bridge, host, etc.) -
driver_opts- กำหนดตัวเลือกเพิ่มเติมสำหรับ driver -
ipam- กำหนด IP Address Management
IPAM Configuration
-
subnet- กำหนด subnet สำหรับ network -
gateway- กำหนด gateway สำหรับ network -
ip_range- กำหนด range ของ IP addresses
Tip: Network Aliases
คุณสามารถกำหนด alias สำหรับ service ได้ เพื่อให้ service อื่นสามารถเรียกชื่ออื่นแทนชื่อ service ได้:
services:
database:
image: postgres:15
networks:
backend:
aliases:
- db
- database.local
networks:
backend:
ตัวอย่างการใช้งานจริง
Microservices Architecture
ตัวอย่าง Microservices ที่มี frontend, API, และ database services แยกจากกัน:
version: '3.8'
services:
frontend:
image: nginx:alpine
ports:
- "80:80"
networks:
- frontend
depends_on:
- api
api:
build: ./api
ports:
- "3000"
networks:
- frontend
- backend
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
db_data:
Secure Multi-Tier Application
ตัวอย่างการแยก network เพื่อความปลอดภัย โดยแยก public services จาก private services:
version: '3.8'
services:
proxy:
image: traefik:v2.9
command: --api.insecure=true --providers.docker
ports:
- "80:80"
- "8080:8080"
networks:
- public
- internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
webapp:
image: my-web-app:latest
networks:
- internal
expose:
- "8080"
database:
image: postgres:15
environment:
- POSTGRES_PASSWORD=supersecretpassword
volumes:
- db_data:/var/lib/postgresql/data
networks:
- internal
expose:
- "5432"
redis:
image: redis:7-alpine
networks:
- internal
expose:
- "6379"
networks:
public:
driver: bridge
internal:
driver: bridge
internal: true
volumes:
db_data:
Security Best Practices
Network Isolation
ใช้ custom networks เพื่อแยก services ตามระดับความสำคัญและความต้องการด้านความปลอดภัย
Internal Networks
ใช้ internal networks สำหรับ services ที่ไม่ต้องการเชื่อมต่อออก Internet
Port Exposure
ใช้ expose แทน ports เมื่อต้องการให้ service สามารถเข้าถึงได้เฉพาะภายใน network
Secrets Management
ใช้ Docker secrets หรือ external secrets management systems สำหรับ credentials
Network Segmentation
แยก network ตาม business functions เช่น frontend, backend, database
TLS Encryption
เปิดใช้งาน TLS encryption สำหรับ service ที่สื่อสารผ่าน network
ข้อควรระวังด้านความปลอดภัย
- อย่า expose ports ที่ไม่จำเป็นต้องเข้าถึงจากภายนอก
- หลีกเลี่ยงการใช้ default bridge network สำหรับ production
- อย่าใช้ privileged mode หากไม่จำเป็น
- ตรวจสอบและ update images เป็นประจำ
แก้ไขปัญหาที่พบบ่อย
Connection Refused Errors
ปัญหานี้มักเกิดจากการที่ service ยังไม่พร้อมให้บริการ หรือ port ไม่ถูก expose properly
Symptoms:
- • "Connection refused" หรือ "Connection timed out"
- • Service ไม่สามารถเชื่อมต่อ database หรือ API อื่น
Solution:
- • ใช้ depends_on เพื่อให้แน่ใจว่า service เริ่มต้นตามลำดับ
- • ตรวจสอบว่า port ถูก expose หรือ publish อย่างถูกต้อง
- • ใช้ healthchecks เพื่อตรวจสอบว่า service พร้อมให้บริการ
services:
api:
image: my-api
depends_on:
db:
condition: service_healthy
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
DNS Resolution Failures
ปัญหาที่ services ไม่สามารถหา service อื่นผ่านชื่อ service ได้
Symptoms:
- • "Name or service not known" หรือ "hostname not found"
- • ping ชื่อ service ไม่ได้
Solution:
- • ตรวจสอบว่า services อยู่ใน network เดียวกัน
- • ใช้ชื่อ service ให้ตรงกับที่กำหนดใน docker-compose.yml
- • ใช้ command เพื่อตรวจสอบ network connections
# ตรวจสอบ networks
$ docker network ls
# ตรวจสอบ containers ใน network
$ docker network inspect [network-name]
# ทดสอบการเชื่อมต่อระหว่าง services
$ docker exec -it [container-id] ping [service-name]
External Network Connection Issues
ปัญหาการเชื่อมต่อไปยังบริการภายนอก (เช่น database บน cloud)
Symptoms:
- • ไม่สามารถเชื่อมต่อ database หรือ API ภายนอก
- • Timeout หรือ connection refused จาก services ภายนอก
Solution:
- • ตรวจสอบ firewall rules และ security groups
- • ตรวจสอบว่า containers มี internet access
- • ใช้ host network mode ถ้าจำเป็น (ควรใช้ด้วยความระมัดระวัง)
# ทดสอบ internet connectivity จาก container
$ docker run --rm alpine ping -c 4 google.com
# ตรวจสอบ routes จาก container
$ docker run --rm alpine ip route
สรุป
การจัดการ Docker Compose Networking อย่างมืออาชีพ
การทำความเข้าใจ Docker Compose Networking อย่างลึกซึ้งจะช่วยให้คุณสามารถออกแบบ สร้าง และจัดการ microservices applications ได้อย่างมีประสิทธิภาพและปลอดภัย
ขั้นตอนถัดไป
- ศึกษา Docker Security Hardening
- เรียนรู้ Service Mesh สำหรับ Microservices
- ทำความเข้าใจ Kubernetes Networking
Key Takeaways
- ใช้ custom networks เพื่อแยก services และเพิ่มความปลอดภัย
- ใช้ internal networks สำหรับ services ที่ไม่ต้องการ Internet access
- ตรวจสอบ connection และ DNS resolution อย่างสม่ำเสมอ
พร้อมจะเป็น Expert ด้าน Docker Compose แล้วหรือยัง?
ดาวน์โหลด Checklist สำหรับตรวจสอบ Docker Compose Networking Best Practices