Docker Network: Kết nối các Container

Photo of author

Văn Ngọc Tân

Bạn có biết?

Hãy tưởng tượng bạn có nhiều container chạy cùng lúc — một web server, một database, và một cache server. Làm sao để chúng “nói chuyện” với nhau? Đó chính là vai trò của Docker Network.

Giống như hệ thống đường sá kết nối các tòa nhà trong thành phố, Docker Network tạo ra các kênh liên lạc giữa các container — an toàn, cô lập và dễ quản lý.

Docker Network là gì?

Docker Network là cơ chế cho phép các container giao tiếp với nhau và với thế giới bên ngoài. Docker cung cấp nhiều loại network driver khác nhau:

  • Bridge — mạng mặc định, container giao tiếp nội bộ
  • Host — container dùng trực tiếp network của host
  • None — container hoàn toàn bị cô lập
  • Overlay — kết nối container qua nhiều host (Docker Swarm)
  • Macvlan — container có IP riêng trên mạng LAN

Các loại Network Driver

1. Bridge Network (mặc định)

Đây là loại network phổ biến nhất. Khi chạy docker run mà không chỉ định network, container sẽ nằm trong bridge network.

# Xem bridge network mặc định
$ docker network ls
# NETWORK ID     NAME      DRIVER    SCOPE
# a1b2c3d4e5f6   bridge    bridge    local
# f6e5d4c3b2a1   host      host      local
# 1a2b3c4d5e6f   none      null      local

# Chạy container trong bridge network mặc định
$ docker run -d --name web nginx
$ docker run -d --name db mysql

# Kiểm tra IP của container
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' web
# 172.17.0.2

2. Custom Bridge Network

Nên tạo custom bridge network thay vì dùng mặc định — vì nó hỗ trợ DNS tự động giữa các container.

# Tạo custom bridge network
$ docker network create my-network

# Chạy container trong custom network
$ docker run -d --name web --network my-network nginx
$ docker run -d --name db --network my-network mysql

# Từ container "web", ping "db" bằng tên — DNS tự động!
$ docker exec web ping db
# PING db (172.18.0.3): 56 data bytes
# 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.098 ms

3. Host Network

Container chia sẻ trực tiếp network stack với host — không có sự cô lập mạng.

# Chạy container với host network
$ docker run -d --network host nginx

# Nginx sẽ listen trực tiếp trên port 80 của host
# KHÔNG cần -p flag vì không có port mapping

⚠️ Lưu ý: Host network chỉ hoạt động trên Linux. Trên macOS/Windows, nó chạy trong VM nên không hoàn toàn giống host thật.

4. None Network

Container hoàn toàn bị cô lập — không có network interface nào ngoại trừ loopback.

# Chạy container không có network
$ docker run -d --network none --name isolated alpine

# Kiểm tra — chỉ có loopback
$ docker exec isolated ip addr
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
#     inet 127.0.0.1/8 scope host lo

Các lệnh quản lý Network

docker network create

# Tạo bridge network đơn giản
$ docker network create my-net

# Tạo với subnet cụ thể
$ docker network create --subnet=192.168.100.0/24 my-net

# Tạo với gateway
$ docker network create --subnet=192.168.100.0/24 --gateway=192.168.100.1 my-net

# Tạo network với driver cụ thể
$ docker network create --driver bridge my-net

docker network ls

# Liệt kê tất cả networks
$ docker network ls

# Lọc theo driver
$ docker network ls --filter driver=bridge

# Xem chi tiết hơn
$ docker network ls --no-trunc

docker network inspect

# Xem chi tiết network
$ docker network inspect bridge

# Xem containers trong network
$ docker network inspect --format='{{range .Containers}}{{.Name}} {{.IPv4Address}}{{println}}{{end}}' my-net

docker network connect / disconnect

# Kết nối container đang chạy vào network mới
$ docker network connect my-net existing-container

# Ngắt kết nối
$ docker network disconnect my-net existing-container

# Container có thể nằm trong nhiều network cùng lúc!
$ docker network connect net-a my-container
$ docker network connect net-b my-container

docker network rm / prune

# Xóa network
$ docker network rm my-net

# Xóa tất cả network không dùng
$ docker network prune

DNS và Service Discovery

Tại sao Custom Bridge Network quan trọng?

Với custom bridge network, Docker tích hợp DNS server tự động. Mỗi container có thể tìm thấy container khác bằng tên thay vì IP:

# ❌ Bridge mặc định — phải dùng IP (có thể thay đổi!)
$ docker exec web ping 172.17.0.3

# ✅ Custom bridge — dùng tên (ổn định!)
$ docker exec web ping db
$ docker exec web curl http://api:3000/health

Network Aliases

Bạn có thể đặt alias cho container trong network:

# Đặt alias khi chạy container
$ docker run -d --name api-server --network my-net --network-alias api nginx

# Từ container khác, dùng alias để truy cập
$ docker exec web curl http://api:80

Port Mapping

Expose port ra ngoài host

# Map port cụ thể: host:container
$ docker run -d -p 8080:80 nginx

# Map trên IP cụ thể
$ docker run -d -p 127.0.0.1:8080:80 nginx

# Map port ngẫu nhiên
$ docker run -d -P nginx

# Xem port mapping
$ docker port my-nginx
# 80/tcp -> 0.0.0.0:8080

EXPOSE trong Dockerfile vs -p flag

# EXPOSE chỉ là tài liệu — KHÔNG mở port thật
EXPOSE 80

# -p flag mới thực sự mở port ra host
$ docker run -d -p 8080:80 nginx

Use Cases thực tế

1. Web App + Database

# Tạo network
$ docker network create app-net

# Chạy database
$ docker run -d --name db --network app-net \
    -e POSTGRES_PASSWORD=secret postgres:15

# Chạy web app kết nối tới db bằng tên
$ docker run -d --name web --network app-net \
    -p 8080:3000 \
    -e DATABASE_URL=postgres://postgres:secret@db:5432/myapp \
    my-web-app

2. Microservices với nhiều network

# Tạo networks
$ docker network create frontend
$ docker network create backend

# API Gateway — nằm cả 2 network
$ docker run -d --name gateway -p 80:80 api-gateway
$ docker network connect frontend gateway
$ docker network connect backend gateway

# Services — chỉ nằm backend
$ docker run -d --name user-service --network backend user-svc
$ docker run -d --name order-service --network backend order-svc

# Gateway truy cập được user-service, order-service
# Nhưng user-service KHÔNG truy cập được gateway qua frontend

3. Isolated environment cho testing

# Tạo network cô lập cho test
$ docker network create test-net

# Chạy test database
$ docker run -d --name test-db --network test-net postgres:15

# Chạy tests
$ docker run --rm --network test-net \
    -e DB_HOST=test-db my-test-suite

# Dọn dẹp
$ docker rm -f test-db
$ docker network rm test-net

So sánh các loại Network

Tiêu chí Bridge Host None Overlay
Cô lập mạng Không Hoàn toàn
DNS tự động Custom only Không Không
Port mapping Cần -p Không cần N/A Cần -p
Multi-host Không Không Không
Use case Ứng dụng đơn host Hiệu năng cao Bảo mật tối đa Swarm/K8s

Best Practices

  1. Luôn dùng custom bridge network — DNS tự động, cô lập tốt hơn bridge mặc định
  2. Mỗi ứng dụng một network — Tách biệt rõ ràng giữa các project
  3. Tránh dùng host network — Trừ khi cần hiệu năng tối đa
  4. Không hardcode IP — Dùng tên container hoặc network alias
  5. Expose port tối thiểu — Chỉ map port thực sự cần truy cập từ ngoài
  6. Dùng network cho multi-container — Thay vì --link (đã deprecated)
  7. Dọn dẹp network không dùngdocker network prune

Bước tiếp theo

Bạn đã nắm vững cách kết nối các container! Tiếp theo, hãy học cách tạo Dockerfile — viết bản thiết kế Image của riêng bạn với các lệnh như FROM, RUN, COPY, CMD.

👉 Đọc tiếp: Dockerfile cơ bản: Tạo Image của riêng bạn

0 0 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest
0 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận