Docker Networking เป็นหัวข้อที่หลายคนมองข้าม แต่เป็น พื้นฐานที่สำคัญที่สุด ของการใช้ Docker ใน Production เพราะ Container ที่สื่อสารกันไม่ได้ก็ไม่มีประโยชน์ ในปี 2026 การเข้าใจ Docker network drivers ทั้งหมดจะช่วยให้คุณ Design ระบบที่ ปลอดภัย, มีประสิทธิภาพ และ Scalable
Docker Network Drivers — ภาพรวม
Docker มี Network drivers หลายประเภท แต่ละแบบเหมาะกับ Use case ที่ต่างกัน:
| Driver | คำอธิบาย | Isolation | เหมาะกับ |
|---|---|---|---|
| bridge | Default driver สร้าง Virtual bridge บน Host container สื่อสารกันผ่าน Bridge | ดี | Single-host, Development, Production ทั่วไป |
| host | Container ใช้ Network stack ของ Host โดยตรง ไม่มี Network isolation | ไม่มี | Performance-critical apps (ลด overhead) |
| none | ไม่มี Network เลย Container ไม่สามารถสื่อสารกับภายนอก | สูงสุด | Security-sensitive containers, Batch jobs |
| overlay | สร้าง Network ข้าม Host หลายเครื่อง (Multi-host) ใช้ VXLAN | ดี | Docker Swarm, Multi-host clusters |
| macvlan | Container ได้ MAC address ของตัวเอง เหมือนเป็น Physical device บน LAN | ดี | Legacy apps ที่ต้องการ Direct LAN access |
| ipvlan | คล้าย macvlan แต่ Share MAC address กับ Host Container ได้ IP ของตัวเอง | ดี | Environments ที่จำกัด MAC addresses |
# ดู Network ทั้งหมด
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# abc123 bridge bridge local
# def456 host host local
# ghi789 none null local
Default Bridge vs Custom Bridge — ความแตกต่างสำคัญ
นี่คือสิ่งที่หลายคนไม่รู้: Default bridge กับ Custom bridge ทำงานต่างกันมาก
| คุณสมบัติ | Default Bridge (docker0) | Custom Bridge |
|---|---|---|
| DNS Resolution | ไม่มี! ต้องใช้ IP address หรือ --link | มี! ใช้ Container name เป็น Hostname ได้ |
| Auto-connect | Container ใหม่เชื่อมอัตโนมัติ | ต้องระบุ --network |
| Isolation | ทุก Container คุยกันได้หมด | เฉพาะ Container ใน Network เดียวกัน |
| Hot-connect | ไม่ได้ (ต้อง Restart) | เพิ่ม/ลบ Container ได้ตลอดเวลา |
| แนะนำสำหรับ Production | ไม่แนะนำ | แนะนำ! |
# สร้าง Custom bridge network
docker network create --driver bridge my-app-network
# รัน Container ใน Custom network
docker run -d --name web --network my-app-network nginx:alpine
docker run -d --name api --network my-app-network node:20-alpine
# ใน Custom bridge: web สามารถเข้าถึง api ด้วยชื่อ "api" ได้!
docker exec web ping api # สำเร็จ!
docker exec web curl http://api:3000 # สำเร็จ!
# ใน Default bridge: ต้องใช้ IP address
docker run -d --name old-web nginx:alpine # อยู่บน Default bridge
docker run -d --name old-api node:20-alpine # อยู่บน Default bridge
docker exec old-web ping old-api # ล้มเหลว! DNS ไม่ทำงาน
Container-to-Container Communication
วิธีที่ Container สื่อสารกันขึ้นอยู่กับ Network driver ที่ใช้:
# Scenario: Web app + API + Database
# ใช้ Custom bridge — Best practice
# สร้าง Networks แยกตาม Function
docker network create frontend
docker network create backend
# Web server — เชื่อมทั้ง frontend + backend
docker run -d --name web --network frontend -p 80:80 nginx:alpine
docker network connect backend web
# API server — เชื่อมแค่ backend
docker run -d --name api --network backend myapi:v1
# Database — เชื่อมแค่ backend
docker run -d --name db --network backend postgres:16-alpine
# ผลลัพธ์:
# - web สามารถเข้าถึง api ได้ (ผ่าน backend)
# - api สามารถเข้าถึง db ได้ (ผ่าน backend)
# - web ไม่สามารถเข้าถึง db ได้โดยตรง! (ไม่ได้อยู่ Network เดียวกัน)
# - ภายนอกเข้าถึงได้แค่ web ผ่าน port 80
Port Mapping — เปิด Port ให้ภายนอกเข้าถึง
# Basic port mapping
docker run -d -p 8080:80 nginx:alpine
# Host port 8080 → Container port 80
# Map หลาย Ports
docker run -d -p 80:80 -p 443:443 nginx:alpine
# Map เฉพาะ IP (Bind to specific interface)
docker run -d -p 127.0.0.1:8080:80 nginx:alpine
# เข้าถึงได้เฉพาะจาก localhost
# Random host port
docker run -d -p 80 nginx:alpine
# Docker เลือก Port ให้อัตโนมัติ
docker port container_name
# 80/tcp -> 0.0.0.0:32768
# UDP port
docker run -d -p 53:53/udp dns-server:latest
# ดู Port mapping ทั้งหมด
docker ps --format "table {{.Names}} {{.Ports}}"
Docker DNS — Embedded DNS Server
Docker มี Embedded DNS server ที่ทำงานบน Custom bridge networks ทำให้ Container ค้นหากันด้วย ชื่อ แทน IP address:
# Docker DNS ทำงานอย่างไร
#
# 1. Container ถูกสร้างใน Custom bridge network
# 2. Docker DNS server (127.0.0.11) ถูกตั้งเป็น Resolver
# 3. เมื่อ Container A ค้นหา "container-b"
# → DNS server ตอบกลับด้วย IP ของ Container B
# 4. IP เปลี่ยนได้ตลอด (Container restart) แต่ชื่อเดิม
# ตรวจสอบ DNS config ใน Container
docker exec my-container cat /etc/resolv.conf
# nameserver 127.0.0.11
# ใช้ Network alias (หลายชื่อสำหรับ Container เดียว)
docker run -d --name db --network backend --network-alias database --network-alias postgres postgres:16
# Container อื่นเข้าถึง db ได้ทั้ง 3 ชื่อ:
# db, database, postgres
# Docker Compose — DNS อัตโนมัติ
# services:
# web:
# image: nginx
# api:
# image: myapi
# db:
# image: postgres
#
# web สามารถ curl http://api:3000 ได้ทันที
# api สามารถ connect postgres://db:5432 ได้ทันที
Overlay Network — Multi-Host Networking
Overlay network สร้าง Virtual network ที่ครอบคลุม หลาย Docker hosts ทำให้ Container บน Host ต่างเครื่องสื่อสารกันได้เหมือนอยู่ Network เดียวกัน:
# Overlay network ใช้กับ Docker Swarm
# ต้องเปิด Swarm mode ก่อน
docker swarm init
# สร้าง Overlay network
docker network create --driver overlay --attachable my-overlay
# --attachable ทำให้ Standalone containers เข้าร่วมได้
# Deploy Service บน Overlay
docker service create --name web --network my-overlay --replicas 3 nginx:alpine
# ทุก Replica (แม้อยู่คนละ Host) สื่อสารกันได้ผ่าน Overlay
# Overlay ทำงานอย่างไร:
# 1. ใช้ VXLAN (Virtual Extensible LAN) encapsulation
# 2. สร้าง Tunnel ระหว่าง Hosts
# 3. Packet ถูก Encapsulate ก่อนส่งข้าม Network
# 4. ปลายทาง Decapsulate แล้วส่งให้ Container
# Ports ที่ต้องเปิดสำหรับ Overlay:
# TCP 2377 — Cluster management
# TCP/UDP 7946 — Node communication
# UDP 4789 — Overlay network (VXLAN)
Macvlan — Direct LAN Access
Macvlan ทำให้ Container ได้ MAC address ของตัวเอง และเข้าร่วม Physical LAN ได้โดยตรง เหมือนเป็นอุปกรณ์จริงบน Network:
# สร้าง Macvlan network
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my-macvlan
# รัน Container ด้วย IP จาก LAN จริง
docker run -d --name legacy-app --network my-macvlan --ip 192.168.1.100 my-legacy-app:v1
# Container นี้จะ:
# - มี MAC address เป็นของตัวเอง
# - มี IP 192.168.1.100 บน LAN จริง
# - อุปกรณ์อื่นบน LAN เข้าถึงได้โดยตรง
# - ไม่ต้อง Port mapping
# เหมาะกับ:
# - Legacy applications ที่ต้องอยู่บน LAN
# - Applications ที่ต้องการ Broadcast/Multicast
# - IoT gateways
# - Network monitoring tools
# ข้อจำกัด:
# - Container ไม่สามารถคุยกับ Host ได้! (ข้อจำกัดของ macvlan)
# - Workaround: สร้าง macvlan sub-interface บน Host
Network Isolation — แยก Network ตาม Function
# Docker Compose — Network isolation best practice
version: '3.8'
services:
# Reverse proxy — เชื่อม Frontend + Backend
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
networks:
- frontend
- backend
# Web app — เชื่อม Frontend + Backend
web:
image: myapp:v1
networks:
- frontend
- backend
# API — เชื่อม Backend + Database
api:
image: myapi:v1
networks:
- backend
- database
# Database — เชื่อมแค่ Database network
postgres:
image: postgres:16-alpine
networks:
- database
# Redis — เชื่อมแค่ Database network
redis:
image: redis:7-alpine
networks:
- database
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # ไม่มี Internet access!
database:
driver: bridge
internal: true # ไม่มี Internet access!
# ผลลัพธ์:
# - nginx: เข้าจากภายนอก → frontend → backend
# - web: frontend + backend (ไม่เข้า database ตรง)
# - api: backend + database
# - postgres: database เท่านั้น (ไม่มี Internet!)
# - redis: database เท่านั้น
Docker Compose Networking
Docker Compose สร้าง Default network ให้อัตโนมัติสำหรับทุก Service:
# docker-compose.yml
services:
web:
image: nginx
api:
image: myapi
db:
image: postgres
# Docker Compose สร้าง Network ชื่อ "projectname_default" ให้อัตโนมัติ
# ทุก Service คุยกันได้ด้วยชื่อ Service (web, api, db)
# เชื่อม Container ข้าม Compose files
# compose-A.yml
services:
api:
networks:
- shared
networks:
shared:
name: my-shared-network # ตั้งชื่อ Fixed
# compose-B.yml
services:
web:
networks:
- shared
networks:
shared:
external: true # ใช้ Network ที่มีอยู่แล้ว
name: my-shared-network
Network Troubleshooting
# ตรวจสอบ Network details
docker network inspect my-network
# แสดง: Subnet, Gateway, Containers ที่เชื่อมอยู่
# ตรวจสอบ Container network config
docker inspect --format='{{json .NetworkSettings.Networks}}' container_name | python3 -m json.tool
# Exec เข้า Container เพื่อ Debug
docker exec -it container_name sh
# ping Container อื่น (ต้องอยู่ Network เดียวกัน)
docker exec container_name ping other_container
# curl ทดสอบ HTTP
docker exec container_name curl -s http://api:3000/health
# ดู DNS resolution
docker exec container_name nslookup api
docker exec container_name getent hosts api
# ดู Routing table ใน Container
docker exec container_name ip route
# ดู Open ports
docker exec container_name netstat -tlnp
docker exec container_name ss -tlnp
# ตรวจสอบ iptables rules (บน Host)
sudo iptables -L -n -t nat | grep DOCKER
sudo iptables -L -n | grep DOCKER
# Debug network ด้วย nicolaka/netshoot
docker run -it --network container:target_container nicolaka/netshoot
# มีเครื่องมือครบ: tcpdump, netstat, nmap, dig, curl, iperf
IPv6 ใน Docker
# เปิด IPv6 ใน Docker daemon
# /etc/docker/daemon.json
{
"ipv6": true,
"fixed-cidr-v6": "fd00:dead:beef::/48"
}
# Restart Docker
sudo systemctl restart docker
# สร้าง Dual-stack network
docker network create --ipv6 --subnet=172.28.0.0/16 --subnet=fd00::/80 my-ipv6-network
# Container ได้ทั้ง IPv4 + IPv6
docker run -d --name web --network my-ipv6-network nginx:alpine
docker exec web ip addr
# inet 172.28.0.2/16
# inet6 fd00::2/80
Container Network Security
# 1. ใช้ internal network สำหรับ Backend
docker network create --internal backend-secure
# Container ใน Network นี้ไม่มี Internet access
# 2. จำกัด ICC (Inter-Container Communication)
# /etc/docker/daemon.json
{
"icc": false # ปิด Communication ระหว่าง Container บน Default bridge
}
# 3. ใช้ --link เฉพาะที่จำเป็น (Legacy — ไม่แนะนำ)
# ใช้ Custom bridge network แทน
# 4. ไม่ใช้ --net=host ใน Production
# Container จะ Share Network stack กับ Host
# ไม่มี Isolation เลย
# 5. ใช้ Network policies (Docker Swarm)
# จำกัดว่า Service ไหนคุยกับ Service ไหนได้
# 6. Encrypt overlay networks
docker network create --driver overlay --opt encrypted secure-overlay
# ข้อมูลระหว่าง Hosts จะถูก Encrypt ด้วย IPsec
Performance Considerations — ประสิทธิภาพตาม Driver
| Driver | Latency | Throughput | เหมาะกับ |
|---|---|---|---|
| host | ต่ำที่สุด (= Host) | สูงที่สุด (= Host) | High-performance apps, Networking tools |
| macvlan | ต่ำ (ใกล้ Host) | สูง | Apps ที่ต้องการ Near-native performance |
| bridge (custom) | ต่ำ-ปานกลาง | สูง | Production ทั่วไป (แนะนำ) |
| bridge (default) | ปานกลาง | สูง | Development |
| overlay | สูงกว่า (VXLAN overhead) | ปานกลาง | Multi-host (ยอมรับ overhead ได้) |
# ทดสอบ Network performance ระหว่าง Containers
# ใช้ iperf3
# Container 1: Server
docker run -d --name iperf-server --network my-network networkstatic/iperf3 -s
# Container 2: Client
docker run -it --rm --network my-network networkstatic/iperf3 -c iperf-server
# เปรียบเทียบ: Bridge vs Host
# Bridge: ~20-40 Gbps (ขึ้นกับ Hardware)
# Host: ~40-100 Gbps (ไม่มี Overhead)
สรุป — Docker Networking Best Practices 2026
- ใช้ Custom bridge เสมอ: อย่าใช้ Default bridge ใน Production เพราะไม่มี DNS resolution
- แยก Network ตาม Function: Frontend, Backend, Database ต้องอยู่คนละ Network
- ใช้ internal network สำหรับ Backend: Database และ Cache ไม่ควรมี Internet access
- ไม่ใช้ --net=host: ยกเว้นมีเหตุผลด้าน Performance ที่ชัดเจน
- ใช้ Overlay สำหรับ Multi-host: Docker Swarm หรือ Cluster ที่ต้องการข้าม Host
- ใช้ Macvlan สำหรับ Legacy: เมื่อ Application ต้องการ Direct LAN access
- Debug ด้วย netshoot: Container nicolaka/netshoot มีเครื่องมือ Network ครบ
- Monitor Network: ตรวจสอบ Bandwidth, Latency, Packet loss ระหว่าง Containers
การเข้าใจ Docker networking อย่างลึกซึ้งจะช่วยให้คุณ Design ระบบที่ ปลอดภัย, มีประสิทธิภาพ และ Debug ได้เร็ว เมื่อเกิดปัญหา เริ่มจาก Custom bridge สำหรับ Single-host และ Overlay สำหรับ Multi-host แล้วค่อยปรับตาม Use case ของคุณ
