第17章 Docker网络实战与高级管理

在前两章掌握网络基础与进阶能力后,本章聚焦实战:复杂网络拓扑设计、服务发现与DNS、负载均衡、网络监控与安全策略。

17.1 复杂网络拓扑设计

17.1.1 三层网络拓扑

text 复制代码
三层拓扑(前端 / 应用 / 数据库):

Internet
   │
┌──▼──┐
│Nginx│  (public网络)
└──┬──┘
   │
┌──▼──┐
│ API │  (public + private网络)
└──┬──┘
   │
┌──▼──┐
│ DB  │  (private网络)
└─────┘

访问关系:Internet -> Nginx -> API -> DB
yaml 复制代码
# docker-compose.yml
version: '3.8'

networks:
  public:
  private:
    internal: true

services:
  nginx:
    image: nginx:alpine
    networks:
      - public
    ports:
      - "80:80"
    depends_on:
      - api

  api:
    image: myapi
    networks:
      - public
      - private
    environment:
      - DB_HOST=db

  db:
    image: postgres:13
    networks:
      - private
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

17.1.2 双网卡容器(接入多个网络)

bash 复制代码
# 创建两个网络
docker network create frontend-net
docker network create backend-net

# 启动容器并加入frontend网络
docker run -d --name api --network frontend-net myapi

# 再连接到backend网络
docker network connect backend-net api

# 查看容器IP
# docker inspect api -f '{{json .NetworkSettings.Networks}}'

适用场景:API网关、双向代理、应用层安全隔离。

17.1.3 仅内部可访问的网络

bash 复制代码
# 创建internal网络(无外网访问)
docker network create --internal internal-net

# 仅内部服务加入
docker run -d --name db --network internal-net postgres

# 其他服务也需加入内部网络才能访问
docker run -d --name api --network internal-net myapi

17.2 服务发现与DNS

17.2.1 Docker内置DNS

Docker自定义网络默认启用内置DNS(127.0.0.11)。

bash 复制代码
# 创建网络
docker network create app-net

# 启动容器
docker run -d --name api --network app-net myapi
docker run -d --name web --network app-net nginx

# 容器内通过服务名访问
# curl http://api:8080

17.2.2 网络别名(Service Alias)

bash 复制代码
# 使用网络别名
docker run -d \
  --name api-v1 \
  --network app-net \
  --network-alias api \
  myapi:v1

docker run -d \
  --name api-v2 \
  --network app-net \
  --network-alias api \
  myapi:v2

# 访问 api 触发轮询解析
# nslookup api

17.2.3 自定义DNS服务器

bash 复制代码
# 运行时指定DNS
docker run -d \
  --dns 10.10.0.2 \
  --dns-search example.local \
  nginx

# daemon级别配置 /etc/docker/daemon.json
{
  "dns": ["10.10.0.2", "8.8.8.8"],
  "dns-search": ["example.local"]
}

17.3 负载均衡与服务暴露

17.3.1 Docker内置轮询解析

自定义网络中,同一别名会解析到多个IP,实现简单轮询。

bash 复制代码
# 创建3个副本
for i in 1 2 3; do
  docker run -d --name api-$i --network app-net --network-alias api myapi
  done

# 在容器内测试
# nslookup api
# 结果返回多个IP

17.3.2 Nginx反向代理负载均衡

nginx 复制代码
# nginx.conf
upstream backend {
    server api-1:8080;
    server api-2:8080;
    server api-3:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}
bash 复制代码
# 启动Nginx并挂载配置
docker run -d \
  --name gateway \
  --network app-net \
  -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
  -p 80:80 \
  nginx

17.3.3 Swarm服务负载均衡

bash 复制代码
# 创建Swarm服务(内置负载均衡)
docker service create \
  --name api \
  --replicas 3 \
  --network my-overlay \
  myapi

# 服务VIP自动负载均衡
# 访问 api 即可

17.4 网络监控与可观测性

17.4.1 监控指标

  • 容器网络吞吐量(rx/tx bytes)
  • 连接数(ESTABLISHED)
  • DNS解析失败率
  • 端口可达性

17.4.2 快速监控脚本

bash 复制代码
#!/bin/bash
# docker-net-stats.sh

printf "%-20s %-12s %-12s\n" "CONTAINER" "RX" "TX"
for c in $(docker ps -q); do
  name=$(docker inspect $c -f '{{.Name}}' | sed 's/\///')
  stats=$(docker exec $c cat /proc/net/dev | awk '/eth0/ {print $2" "$10}')
  rx=$(echo $stats | awk '{print $1}')
  tx=$(echo $stats | awk '{print $2}')
  printf "%-20s %-12s %-12s\n" "$name" "$rx" "$tx"
done

17.4.3 Netshoot诊断容器

bash 复制代码
# 进入目标容器网络空间进行诊断
docker run -it --rm \
  --network container:mycontainer \
  nicolaka/netshoot

# 常用命令:
# ping, dig, traceroute, tcpdump, ss, netstat

17.4.4 Prometheus + cAdvisor(可选)

yaml 复制代码
# 简化监控栈(示例)
version: '3.8'
services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker:/var/lib/docker:ro

  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro

17.5 网络安全策略

17.5.1 最小暴露原则

bash 复制代码
# 仅绑定到本地
docker run -d -p 127.0.0.1:8080:80 nginx

# 仅开放必要端口
docker run -d -p 80:80 nginx

17.5.2 DOCKER-USER防火墙策略

bash 复制代码
# 默认策略:限制特定网段访问
sudo iptables -I DOCKER-USER -s 10.0.0.0/8 -j DROP

# 允许特定容器访问外部服务
CONTAINER_IP=$(docker inspect api -f '{{.NetworkSettings.IPAddress}}')
sudo iptables -I DOCKER-USER -s $CONTAINER_IP -d 10.0.0.5 -j ACCEPT

17.5.3 网络隔离建议

text 复制代码
✅ 前端与数据库隔离(public/private)
✅ 仅API服务同时加入两个网络
✅ 使用internal网络屏蔽外网访问
✅ 关键服务不使用host模式

17.6 常见问题排查流程

17.6.1 排查清单

text 复制代码
1. 容器在同一网络?
2. DNS解析是否正确?
3. 是否有端口映射冲突?
4. 服务端口是否监听?
5. 防火墙/iptables是否拦截?
6. 主机IP转发是否开启?

17.6.2 诊断脚本(完整版)

bash 复制代码
#!/bin/bash
# net-triage.sh

CONTAINER=$1
if [ -z "$CONTAINER" ]; then
  echo "Usage: $0 <container>"
  exit 1
fi

echo "=== Network Triage for $CONTAINER ==="

echo "1) Network:"
docker inspect $CONTAINER --format '{{json .NetworkSettings.Networks}}' | jq

echo -e "\n2) DNS:"
docker exec $CONTAINER cat /etc/resolv.conf

echo -e "\n3) Routes:"
docker exec $CONTAINER ip route

echo -e "\n4) Ping gateway:"
GW=$(docker exec $CONTAINER ip route | awk '/default/ {print $3}')
docker exec $CONTAINER ping -c 2 $GW

echo -e "\n5) DNS lookup:"
docker exec $CONTAINER nslookup google.com

echo -e "\n6) Internet ping:"
docker exec $CONTAINER ping -c 2 8.8.8.8

echo -e "\n7) Host iptables (docker):"
sudo iptables -t nat -L -n | grep docker

17.7 实战:完整网络架构示例

17.7.1 电商系统网络拓扑

text 复制代码
Internet
  │
  ▼
Nginx (public)
  │
  ▼
API Gateway (public + private)
  │
  ▼
Service Mesh (private)
  │
  ▼
DB/Cache (private + internal)
yaml 复制代码
version: '3.8'

networks:
  public:
  private:
  internal:
    internal: true

services:
  nginx:
    image: nginx:alpine
    networks:
      - public
    ports:
      - "80:80"

  gateway:
    image: my-gateway
    networks:
      - public
      - private

  user-service:
    image: user-service
    networks:
      - private

  order-service:
    image: order-service
    networks:
      - private

  db:
    image: postgres
    networks:
      - internal
    volumes:
      - db-data:/var/lib/postgresql/data

  redis:
    image: redis
    networks:
      - internal

volumes:
  db-data:

17.8 小结

通过本章学习,你已经具备了Docker网络实战能力:

复杂网络拓扑设计

  • 三层网络设计
  • 多网络连接
  • internal网络隔离

服务发现与DNS

  • 内置DNS机制
  • 网络别名与轮询
  • 自定义DNS配置

负载均衡

  • 内置轮询解析
  • Nginx反向代理
  • Swarm服务负载均衡

网络监控与排查

  • 监控指标
  • Netshoot诊断
  • 排查脚本

安全策略

  • 最小暴露原则
  • DOCKER-USER防火墙
  • 网络隔离建议

下一步

在第18章中,我们将学习Docker Compose基础:

  • Compose是什么
  • docker-compose.yml结构
  • 常用命令
  • 单机多容器编排

本章思考题

  1. 如何设计一个三层安全网络?
  2. Docker内置DNS的工作机制是什么?
  3. 为什么要使用DOCKER-USER链?
  4. Swarm的负载均衡和Nginx负载均衡有什么区别?
  5. 如何快速定位容器网络问题?

相关资源

相关推荐
hjhcos2 小时前
【链观】一个面向经济社交的智能体网络
网络
DeeplyMind3 小时前
第19章 Docker Compose进阶
运维·docker·容器
小锋学长生活大爆炸4 小时前
【教程】PicoClaw:在嵌入式设备上部署OpenClaw
docker·github·教程·工具·openclaw·picoclaw
Hello.Reader5 小时前
从 0 到 1 理解硬盘数据恢复工具原理与工程实现
linux·运维·服务器·网络·数据库
小坏坏的大世界5 小时前
VMware 虚拟机无法上网问题排查
服务器·网络
KoiHeng6 小时前
网络原理相关内容(三)
网络
CHANG_THE_WORLD6 小时前
指针入门一
java·前端·网络
切糕师学AI7 小时前
NAT (Network Address Translation,网络地址转换)
运维·服务器·网络
only_Klein8 小时前
Kubernetes-deployment控制器
云原生·容器·kubernetes