Network namespace, bridge, DNS và published ports
localhost bên trong một container trỏ về chính network namespace của container đó. Muốn gọi service khác, hãy đi qua DNS/IP trên network chung; muốn traffic từ ngoài host vào container, hãy hiểu rõ published port, firewall và phạm vi bind.
1. Networking
Container networking là lớp cho phép container giao tiếp với nhau và với service ngoài Docker. Trên Docker Engine, mỗi container thường có network namespace riêng. Nếu không chỉ định network, container Linux thường được gắn vào default bridge; trong production, user-defined bridge thường dễ quản lý hơn vì có isolation rõ hơn và name resolution thuận tiện giữa các container cùng network.
Ba khái niệm cần tách biệt: container port là port process đang listen trong namespace; published host port là cổng host được map/forward vào container; EXPOSE chỉ là metadata/documentation của image, không tự mở firewall hay publish port.
2. Packet path
Với bridge networking trên Linux, container có interface trong namespace riêng, thường nối tới software bridge của host qua cặp virtual Ethernet. Traffic outbound thường được masquerade/SNAT khi rời Docker host; traffic inbound chỉ đi vào container khi routing/firewall/publishing cho phép.
- Container → Internet: route mặc định của container đi qua gateway của Docker network; bridge networking thường dùng masquerading cho traffic ra ngoài.
- Container A → Container B cùng user-defined bridge: gọi bằng service/container name hoặc IP hiện tại; không cần publish host port chỉ để hai container cùng network nói chuyện.
- Host/remote client → container: dùng
-p HOST_IP:HOST_PORT:CONTAINER_PORThoặc cơ chế direct routing phù hợp. Published port mặc định không đồng nghĩa “chỉ localhost”.
docker network create app-net
docker run -d --name api --network app-net -p 127.0.0.1:8080:8080 my-api
127.0.0.1:5432:5432, reverse proxy có auth/TLS, hoặc không publish nếu chỉ internal.3. Drivers
| Driver | Khi dùng | Trade-off / caveat chính |
|---|---|---|
bridge | Multi-container trên một Docker host | User-defined bridge cho isolation/name resolution tốt; host publishing/firewall vẫn phải cấu hình đúng. |
host | Cần tránh NAT hoặc dùng rất nhiều port | Container chia sẻ network stack với host, giảm isolation; port conflict xảy ra trực tiếp trên host. |
none | Cần container không có network connectivity thông thường | Không giao tiếp host/container khác qua network driver. |
overlay | Multi-host Docker/Swarm | Có encapsulation/routing cross-host; standalone multi-host overlay vẫn cần Swarm mode thiết lập network. |
macvlan | Container cần xuất hiện như thiết bị riêng trên L2 | Cần hạ tầng hỗ trợ nhiều MAC/promiscuous mode; host↔container trực tiếp có kernel caveat. |
ipvlan | Tích hợp underlay/VLAN nhưng muốn giảm số MAC | Phụ thuộc topology/routing của hạ tầng; cần thiết kế IP/subnet cẩn thận. |
Chọn driver theo scope giao tiếp, topology vật lý, isolation, performance và khả năng vận hành. Không dùng host chỉ để “network nhanh hơn” nếu sự đánh đổi isolation và port ownership chưa được chấp nhận.
4. DNS and connections
Container IP là implementation detail và có thể thay đổi sau recreate. Với các container cùng user-defined network, ưu tiên tên service/container làm endpoint ổn định hơn. Client vẫn cần xử lý reconnect vì DNS resolve đúng không bảo đảm peer đang healthy.
localhost/127.0.0.1trong container chỉ loopback của chính container đó.- Nếu app chỉ bind
127.0.0.1bên trong container, process khác qua network interface của container thường không kết nối được. Server container thường cần bind0.0.0.0hoặc interface phù hợp. - JVM/client resolver hoặc connection pool có thể giữ DNS/IP cũ. Khi backend recreate, cần timeout, reconnect, DNS refresh và retry policy có giới hạn.
- Port conflict ở bridge mode thường nằm ở host-published port; nhiều container có thể cùng listen port nội bộ giống nhau nếu không cùng bind một host port.
web gọi http://api:8080 trên cùng user-defined network. Không gọi http://localhost:8080 trừ khi API process thực sự nằm trong cùng network namespace.5. Debug flow
Debug theo từng hop, từ gần ứng dụng ra ngoài. Đừng bắt đầu bằng việc đổi firewall/NAT ngẫu nhiên vì có thể che mất nguyên nhân gốc.
- Resolve: tên service có resolve từ đúng namespace không? Dùng
getent hosts apihoặc công cụ DNS phù hợp. - Inspect endpoint/network: container có gắn đúng network, IP/subnet/gateway đúng không? Kiểm tra bằng
docker network inspectvàdocker inspect. - Listener: process có thực sự listen đúng port/address? Dùng
ss -lntphoặc công cụ tương đương trong namespace/container. - East-west test: thử từ container caller tới target name/IP/port trước khi xét host publishing.
- North-south path: nếu container-to-container chạy nhưng client ngoài host fail, kiểm tra published port, host bind address, Docker firewall rules, upstream firewall/security group.
- Application layer: sau TCP là proxy, HTTP host/path, TLS/SNI/certificate, auth và timeout.
# Network membership / endpoint
Docker network inspect app-net
Docker inspect api
# DNS + connectivity từ đúng namespace/toolbox
getent hosts api
curl -v http://api:8080/health
# Listener
ss -lntp
Runtime image tối giản không nhất thiết chứa curl, dig, ss. Ưu tiên ephemeral debug toolbox/container hoặc namespace attach thay vì cài debug packages vĩnh viễn vào production image.
6. Failure windows và operational signals
| Triệu chứng | Khả năng nguyên nhân | Signal nên xem |
|---|---|---|
| Connection refused | Không có listener, bind sai address, process chưa ready | Listener socket, container health, restart count |
| Timeout | Routing/firewall/drop, target treo, SYN không tới/không reply | Packet counters, host firewall, network path, app latency |
| DNS resolve nhưng vẫn fail sau deploy | Stale resolver/connection pool hoặc app endpoint chưa ready | DNS answer, connection age, retry/reconnect rate |
| Chỉ external fail | Publish/bind/firewall/NAT/upstream policy | docker ps port mapping, host listener, firewall rules |
| Chỉ một host bị lỗi | Bridge/firewall/route state cục bộ, port conflict, resource pressure | Per-host network errors, conntrack/socket pressure, daemon events |
Capacity không chỉ là bandwidth. Theo dõi connection count, connection churn, TCP retransmit/reset, DNS error/latency, socket/file-descriptor pressure, packet drops, host CPU cho packet processing, và latency/error theo từng dependency. Recovery phải tránh retry storm: dùng timeout hữu hạn, exponential backoff có jitter, circuit breaking khi cần và health/readiness phân biệt rõ.
7. Security, rollback và recovery
- Chỉ publish port cần thiết; bind host IP hẹp nhất có thể và để database/internal service ở private network.
- Dùng TLS/auth ở application hoặc proxy phù hợp; network isolation không thay thế authentication/authorization.
- Review firewall, cloud security group và Docker-created rules cùng nhau; tránh chỉnh trực tiếp rule Docker quản lý nếu không hiểu lifecycle.
- Khi thay network/driver/subnet/publish rule, rollout canary và giữ cấu hình cũ để rollback nhanh. Test cả traffic nội bộ lẫn external trước khi cắt hoàn toàn.
- Nếu DNS/service endpoint thay đổi, đảm bảo client reconnect được; đừng coi một TCP connection sống lâu là “service discovery”.