Docker Networking คืออะไร? สอน Bridge, Host, Overlay, Macvlan อย่างละเอียด 2026
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 ของคุณ
