container đã cách mạng hóa cách chúng tôi triển khai các ứng dụng, nhưng chúng cũng đưa ra những vấn đề phức tạp về mạng mới. Hiểu mạng container giúp bạn khắc phục sự cố kết nối, tối ưu hóa hiệu suất và thiết kế các ứng dụng đa container an toàn.

Điều kiện tiên quyết

  • Docker được cài đặt và chạy
  • Hiểu biết cơ bản về container và vòng đời của chúng
  • Kiến thức cơ bản về mạng từ các phần trước

Cơ bản về mạng Docker

Khi bạn chạy container, Docker sẽ tự động xử lý kết nối mạng. Nhưng điều gì thực sự đang xảy ra đằng sau hậu trường?

Host Machine (192.168.1.100)
│
├── Docker Bridge Network (172.17.0.0/16)
│   │
│   ├── Container 1 (nginx)
│   │   ├── IP: 172.17.0.2
│   │   └── Port: 80 → Host:8080
│   │
│   ├── Container 2 (api)
│   │   ├── IP: 172.17.0.3
│   │   └── Port: 3000 (internal only)
│   │
│   └── Container 3 (db)
│       ├── IP: 172.17.0.4
│       └── Port: 5432 (internal only)
│
└── Host Network Interface
    ├── eth0: 192.168.1.100
    └── docker0: 172.17.0.1 (bridge)

Communication Flow:
Internet → Host:8080 → docker0 → nginx:80
nginx:80 → api:3000 (direct container communication)
api:3000 → db:5432 (direct container communication)

Hãy kiểm tra thiết lập mạng mặc định của Docker:

# List Docker networks
docker network ls

# Inspect the default bridge network
docker network inspect bridge

Bạn sẽ thấy đầu ra hiển thị mạng cầu nối có mạng con như 172.17.0.0/16. Đây là mạng mặc định của Docker nơi container giao tiếp.

Các loại mạng Docker

Bridge Network (Mặc định): container trên cùng một máy chủ có thể giao tiếp

# Run containers on default bridge network
docker run -d --name web nginx
docker run -d --name api node:alpine sleep 3600

# Check their IP addresses
docker inspect web | grep IPAddress
docker inspect api | grep IPAddress

Host Network: container sử dụng trực tiếp mạng của máy chủ

# Container uses host networking
docker run -d --network host --name host-web nginx

# This container is accessible on the host's IP address

None Network: container không có quyền truy cập mạng

# Isolated container with no networking
docker run -d --network none --name isolated alpine sleep 3600

Mạng Docker tùy chỉnh

Mạng cầu nối mặc định có những hạn chế. Mạng tùy chỉnh cung cấp các tính năng và cách ly tốt hơn:

# Create a custom bridge network
docker network create --driver bridge ecommerce-network

# Inspect the new network
docker network inspect ecommerce-network

Chạy container trên mạng tùy chỉnh của bạn:

# Run containers on the custom network
docker run -d --network ecommerce-network --name frontend nginx
docker run -d --network ecommerce-network --name backend node:alpine sleep 3600
docker run -d --network ecommerce-network --name database postgres:13

# Test connectivity between containers
docker exec frontend ping backend
docker exec backend ping database

Độ phân giải tên container

container trên các mạng tùy chỉnh có thể liên lạc với nhau theo tên:

# From inside the frontend container
docker exec -it frontend sh
# ping backend    # This works!
# ping database   # This also works!

Độ phân giải DNS tự động này không hoạt động trên mạng cầu nối mặc định - bạn cần sử dụng địa chỉ IP hoặc liên kết container.

Ứng dụng Multi-container

Các ứng dụng thực tế thường liên quan đến nhiều container hoạt động cùng nhau.

Mạng Docker Compose

Docker Compose tự động tạo mạng cho ứng dụng của bạn:

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    ports:
      - '80:80'
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - api

  api:
    image: node:alpine
    command: node server.js
    volumes:
      - ./api:/app
    working_dir: /app
    environment:
      - DATABASE_URL=postgresql://user:pass@database:5432/app
    depends_on:
      - database

  database:
    image: postgres:13
    environment:
      - POSTGRES_DB=app
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Bắt đầu ứng dụng:

# Start all services
docker-compose up -d

# Check the network Docker Compose created
docker network ls
docker network inspect $(basename $(pwd))_default

Khám phá dịch vụ trong Compose

Các dịch vụ có thể liên lạc với nhau bằng tên dịch vụ:

// api/server.js - connecting to database
const { Client } = require('pg');

const client = new Client({
  connectionString: 'postgresql://user:pass@database:5432/app',
  // Note: 'database' resolves to the database container
});

Bản đồ và hiển thị cổng

container chạy trong các mạng bị cô lập. Để truy cập chúng từ bên ngoài, bạn cần ánh xạ các cổng:

# Map container port 8080 to host port 3000
docker run -d -p 3000:8080 --name api-server node:alpine

# Map to specific host interface
docker run -d -p 127.0.0.1:3000:8080 --name local-api node:alpine

# Map to random host port
docker run -d -P --name random-ports nginx

Kiểm tra cổng nào được ánh xạ:

# Show port mappings
docker port api-server

# See all container details including ports
docker ps

Truyền thông nội bộ và bên ngoài

Thiết kế chiến lược cảng của bạn một cách cẩn thận:

# External services (accessible from outside)
docker run -d -p 80:80 --name web nginx        # Web server
docker run -d -p 443:443 --name web-ssl nginx  # HTTPS

# Internal services (no port mapping needed)
docker run -d --name database postgres         # Database
docker run -d --name cache redis               # Cache
docker run -d --name queue rabbitmq            # Message queue

Các dịch vụ nội bộ giao tiếp qua mạng Docker mà không để lộ cổng tới máy chủ.

Mạng Kubernetes

Mạng Kubernetes phức tạp hơn nhưng cung cấp các tính năng mạnh mẽ cho việc điều phối container.

Mạng pod

Trong Kubernetes, đơn vị nhỏ nhất là pod, có thể chứa nhiều container:

# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80
    - name: app
      image: node:alpine
      command: ['node', 'server.js']
      ports:
        - containerPort: 3000

container trong cùng một pod có chung giao diện mạng:

# Deploy the pod
kubectl apply -f pod-example.yaml

# Get pod IP address
kubectl get pod web-pod -o wide

# Containers in the pod can reach each other via localhost
kubectl exec web-pod -c nginx -- curl localhost:3000

Dịch vụ cân bằng tải

Dịch vụ Kubernetes cung cấp khả năng cân bằng tải và khám phá dịch vụ:

# service-example.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

Triển khai và thử nghiệm dịch vụ:

# Deploy the service and deployment
kubectl apply -f service-example.yaml

# Check service endpoints
kubectl get endpoints web-service

# Test service from another pod
kubectl run test-pod --image=busybox --rm -it -- sh
# wget -qO- http://web-service

Loại dịch vụ

ClusterIP: Chỉ dịch vụ nội bộ

spec:
  type: ClusterIP # Default, accessible only within cluster
  ports:
    - port: 80
      targetPort: 8080

NodePort: Có thể truy cập từ bên ngoài cụm

spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080 # Accessible on any node's IP:30080

LoadBalancer: Nhà cung cấp đám mây tạo bộ cân bằng tải bên ngoài

spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
  # Cloud provider creates external load balancer

Chính sách mạng

Kubernetes cho phép các chính sách bảo mật mạng chi tiết:

# network-policy-example.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: web
      ports:
        - protocol: TCP
          port: 8080

Áp dụng chính sách mạng:

# Apply policies
kubectl apply -f network-policy-example.yaml

# Verify policies are active
kubectl get networkpolicies -n production

Mạng lưới dịch vụ

Đối với các kiến trúc vi dịch vụ phức tạp, lưới dịch vụ cung cấp các tính năng mạng nâng cao.

Lưới dịch vụ Istio

Istio bổ sung proxy sidecar cho mỗi pod để quản lý lưu lượng nâng cao:

# istio-example.yaml
apiVersion: v1
kind: Service
metadata:
  name: productpage
spec:
  ports:
    - port: 9080
      name: http
  selector:
    app: productpage

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
      annotations:
        sidecar.istio.io/inject: 'true' # Enable Istio sidecar
    spec:
      containers:
        - name: productpage
          image: istio/examples-bookinfo-productpage-v1:1.16.2
          ports:
            - containerPort: 9080

Định tuyến lưu lượng truy cập với Istio

Kiểm soát luồng lưu lượng giữa các phiên bản dịch vụ:

# virtual-service-example.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  http:
    - match:
        - headers:
            canary:
              exact: 'true'
      route:
        - destination:
            host: productpage
            subset: v2
          weight: 100
    - route:
        - destination:
            host: productpage
            subset: v1
          weight: 90
        - destination:
            host: productpage
            subset: v2
          weight: 10

---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  host: productpage
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

Khắc phục sự cố mạng container

Khi mạng container không hoạt động, việc khắc phục sự cố có hệ thống sẽ giúp xác định sự cố.

Gỡ lỗi mạng Docker

Kiểm tra kết nối container:

# Inspect container network settings
docker inspect container-name | grep -A 20 NetworkSettings

# Test connectivity between containers
docker exec container1 ping container2

# Check if ports are listening
docker exec container-name netstat -tuln

# View container logs for network errors
docker logs container-name

Gỡ lỗi mạng Kubernetes

Gỡ lỗi các sự cố mạng pod:

# Check pod network configuration
kubectl describe pod pod-name

# Get detailed network information
kubectl get pod pod-name -o yaml | grep -A 10 status

# Test connectivity from within a pod
kubectl exec -it pod-name -- nslookup service-name
kubectl exec -it pod-name -- wget -qO- http://service-name

# Check service endpoints
kubectl get endpoints service-name

Vấn đề về độ phân giải DNS

Các sự cố DNS của container thường gặp:

# Test DNS resolution in Docker
docker exec container-name nslookup google.com

# Test DNS in Kubernetes
kubectl exec -it pod-name -- nslookup kubernetes.default

# Check DNS configuration
kubectl get configmap coredns -n kube-system -o yaml

Tối ưu hóa hiệu suất

Mạng container có thể ảnh hưởng đến hiệu suất ứng dụng.

Chi phí không gian tên mạng

Mỗi container có không gian tên mạng riêng, bổ sung thêm một số chi phí:

# Compare performance with and without network namespace
# Host networking (less overhead)
docker run --network host --rm nginx

# Bridge networking (more overhead but better isolation)
docker run --rm nginx

Nhóm kết nối

container thực hiện nhiều yêu cầu mạng nên sử dụng kết nối tổng hợp:

// Node.js example with connection pooling
const http = require('http');

const agent = new http.Agent({
  keepAlive: true,
  maxSockets: 50,
});

const options = {
  hostname: 'api-service',
  port: 8080,
  path: '/data',
  agent: agent,
};

Tác động của chính sách mạng

Chính sách mạng thêm chi phí xử lý:

# Monitor network policy performance
kubectl top nodes
kubectl describe node node-name | grep -A 5 "System Info"

Các chính sách mạng quá mức có thể làm chậm quá trình giao tiếp pod-to-pod.

Mạng đa cụm

Các tổ chức lớn thường chạy nhiều cụm Kubernetes.

Liên đoàn cụm

Kết nối nhiều cụm để chuyển đổi dự phòng và phân phối tải:

# cluster-federation-example.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: cross-cluster-gateway
spec:
  selector:
    istio: eastwestgateway
  servers:
    - port:
        number: 15443
        name: tls
        protocol: TLS
      tls:
        mode: ISTIO_MUTUAL
      hosts:
        - '*.local'

Phản ánh dịch vụ

Phản chiếu lưu lượng giữa các cụm để thử nghiệm:

# traffic-mirroring-example.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: mirror-traffic
spec:
  http:
    - match:
        - uri:
            prefix: '/api'
      route:
        - destination:
            host: api-service
      mirror:
        host: api-service.test-cluster.local
      mirrorPercentage:
        value: 10.0

Trong phần tiếp theo, chúng ta sẽ khám phá mạng đám mây - cách các nhà cung cấp đám mây lớn xử lý mạng trên quy mô lớn và tích hợp với nền tảng container.

Mạng container loại bỏ nhiều vấn đề phức tạp về mạng, nhưng việc hiểu các cơ chế cơ bản sẽ giúp bạn thiết kế các ứng dụng tốt hơn và khắc phục sự cố một cách hiệu quả.

Chúc bạn container vui vẻ!