Docker thêm lớp network abstraction
Mỗi container mặc định có network namespace riêng, một không gian mạng cô lập với host và với container khác. Kernel tạo “interface ảo” nối container vào bridge.
eth0 10.0.1.50/24
│ (ra ngoài internet)
▼
Internetdocker0 là L2 bridge, các container cùng bridge thấy nhau như cùng LAN.
Bridge network, chế độ mặc định
Khi chạy docker run không chỉ định network, container gắn vào default bridge (docker0):
docker run -d nginx
docker inspect <id> | grep IPAddress
# "IPAddress": "172.17.0.2"
Container có thể nói chuyện với nhau qua IP nội bộ, nhưng không resolve được tên container, đây là hạn chế của default bridge.
Publish port: -p host_port:container_port
docker run -d -p 8080:80 nginx
Docker thêm rule iptables DNAT:
Internet
│ TCP :8080
▼
Host (iptables DNAT/SNAT)
│ DNAT → 172.17.0.2:80
▼
Container 172.17.0.2:80
│ phản hồi
▼
Host (MASQUERADE / SNAT — IP host ví dụ 10.0.1.50)
│
▼
InternetXung đột cổng:
docker run -p 8080:80 app1 # OK
docker run -p 8080:80 app2 # Error: address already in use
Mỗi (host_ip, host_port, protocol) chỉ có một process giữ. Dùng ss -lntp | grep 8080 để tìm ai đang giữ.
User-defined bridge, tốt hơn cho compose
Docker Compose tự tạo user-defined bridge riêng cho mỗi project:
# docker-compose.yml
services:
api:
image: my-api
db:
image: postgres
┌──────────────────────────────────────┐
│ bridge: my-project_default │
│ api ◄────── DNS nội bộ ──────► db │
└──────────────────────────────────────┘Container trong cùng user-defined bridge resolve được tên service qua DNS nội bộ Docker, khác với default bridge.
Cô lập giữa compose project:
project-a_default (172.20.0.0/16) project-b_default (172.21.0.0/16)
│ │
└── mặc định cô lập — không reach tới nhau ──┘Mặc định, container project A không reach được container project B trừ khi thêm shared network.
Network modes đặc biệt
# Host network: container dùng chung stack mạng với host
docker run --network host nginx
# nginx sẽ listen trực tiếp trên host:80, không qua NAT
# Lợi: không overhead NAT | Rủi ro: mất cô lập cổng
# None: container không có network interface (trừ loopback)
docker run --network none my-job
# Dùng cho build job cần hoàn toàn offline
MTU, điểm hay bị bỏ qua
Khi chạy Docker bên trong VPC hoặc qua VPN:
VPN tunnel MTU: 1400 byte
Docker default MTU: 1500 byte (kế thừa từ host Ethernet)
Kết quả: gói TCP lớn hơn 1400 byte bị drop hoặc fragment
Triệu chứng: ping nhỏ OK, curl download lớn treo / kết nối ngắt giữa chừng
Xem MTU hiện tại:
ip link show docker0
# 3: docker0: mtu 1500
Cấu hình MTU cho Docker daemon:
// /etc/docker/daemon.json
{
"mtu": 1450
}
Inspect và debug network
# Liệt kê network
docker network ls
# Xem chi tiết: subnet, gateway, container kết nối
docker network inspect bridge
# Xem interface trong container
docker exec <container> ip addr
docker exec <container> ip route
# Test kết nối từ trong container
docker exec <container> nc -vz db 5432
docker exec <container> curl -v http://api:8080/health
Tóm tắt
- Bridge + NAT là mô hình mặc định: container có IP riêng, ra internet qua SNAT.
- Publish port = DNAT rule trên host; xung đột khi hai container cùng port.
- User-defined bridge (Compose) cho DNS tên service, nên dùng thay default bridge.
- MTU là nguyên nhân hay bị bỏ qua khi kết nối kỳ lạ trong VPN/VPC.
Câu hỏi hay gặp
Ping được IP nhưng curl http://tên-service không resolve trên default bridge, vì sao?
Trả lời: Default bridge không có DNS tên container như user-defined network. Dùng docker network create + attach container, hoặc link (lỗi thời), hoặc gọi bằng container name trên user-defined bridge / Compose.
-p 0.0.0.0:5432:5432 vs -p 127.0.0.1:5432:5432 khác nhau thế nào về bảo mật?
Trả lời: 0.0.0.0 publish ra mọi interface (mạng LAN/VPC có thể vào được). 127.0.0.1 chỉ localhost host, an toàn hơn nếu chỉ cần tunnel/port-forward cục bộ.
SSH vào container OK nhưng upload lớn treo (VPN MTU 1400), kiểm tra gì đầu tiên?
Trả lời: MTU đường đi (host, bridge, VPN): thử giảm MTU Docker/daemon.json, hoặc kiểm tra PMTUD/black hole, triệu chứng điển hình của gói lớn bị drop.
Bài tiếp theo (Giai đoạn III): Mạng trong Kubernetes, container ở quy mô cluster với Service, Ingress và DNS riêng.