自定义网络 #

为什么需要自定义网络? #

text
┌─────────────────────────────────────────────────────┐
│               自定义网络的优势                       │
├─────────────────────────────────────────────────────┤
│                                                     │
│  1. 容器名解析 - 通过容器名而非IP通信               │
│  2. 网络隔离 - 不同网络间容器隔离                   │
│  3. 灵活配置 - 自定义子网、网关等                   │
│  4. 动态管理 - 运行时连接/断开网络                  │
│  5. 服务发现 - 自动DNS解析                         │
│                                                     │
└─────────────────────────────────────────────────────┘

创建自定义网络 #

基本创建 #

bash
# 创建基本bridge网络
docker network create mynetwork

# 指定驱动类型
docker network create --driver bridge mynetwork

配置子网和网关 #

bash
# 指定子网
docker network create --subnet=172.20.0.0/16 mynetwork

# 指定子网和网关
docker network create \
  --subnet=172.20.0.0/16 \
  --gateway=172.20.0.1 \
  mynetwork

# 指定IP范围
docker network create \
  --subnet=172.20.0.0/16 \
  --ip-range=172.20.1.0/24 \
  mynetwork

配置选项 #

bash
# 设置MTU
docker network create --opt com.docker.network.driver.mtu=1400 mynetwork

# 禁用ICC(容器间通信)
docker network create --internal mynetwork

# 设置网络标签
docker network create --label env=prod mynetwork

网络配置参数 #

IP地址管理(IPAM) #

bash
# 完整IPAM配置
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \
  --subnet=172.21.0.0/16 \
  --gateway=172.20.0.1 \
  --gateway=172.21.0.1 \
  --ip-range=172.20.1.0/24 \
  --aux-address="host1=172.20.1.1" \
  --aux-address="host2=172.20.1.2" \
  mynetwork

网络选项 #

选项 说明
–driver 网络驱动
–subnet 子网CIDR
–gateway 网关地址
–ip-range IP分配范围
–aux-address 预留地址
–internal 禁止外部访问
–attachable 允许独立容器连接
–opt 驱动选项

使用自定义网络 #

连接容器到网络 #

bash
# 创建网络
docker network create app-network

# 运行容器并连接网络
docker run -d --name web --network app-network nginx
docker run -d --name app --network app-network myapp

# 通过容器名通信
docker exec web ping -c 3 app

指定容器IP #

bash
# 指定静态IP
docker run -d \
  --name web \
  --network app-network \
  --ip 172.20.0.10 \
  nginx

# 验证IP
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

网络别名 #

bash
# 设置网络别名
docker run -d \
  --name web \
  --network app-network \
  --network-alias webserver \
  --network-alias frontend \
  nginx

# 其他容器可以通过别名访问
docker run --rm --network app-network alpine ping webserver
docker run --rm --network app-network alpine ping frontend

多网络连接 #

连接多个网络 #

bash
# 创建多个网络
docker network create frontend-network
docker network create backend-network

# 容器连接多个网络
docker run -d --name app --network frontend-network myapp
docker network connect backend-network app

# 查看容器网络
docker inspect --format '{{json .NetworkSettings.Networks}}' app | jq

网络隔离 #

bash
# 创建隔离网络
docker network create --internal internal-network

# 运行容器
docker run -d --name app --network internal-network myapp

# 容器无法访问外部网络
docker exec app ping -c 3 google.com  # 失败

Docker Compose网络配置 #

默认网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
  app:
    image: myapp

# 自动创建 default 网络
# 所有服务连接到同一网络

自定义网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - frontend
  app:
    image: myapp
    networks:
      - frontend
      - backend
  db:
    image: mysql
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

网络配置选项 #

yaml
version: '3.8'

networks:
  frontend:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1400
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1
          ip_range: 172.20.1.0/24
    labels:
      - "env=production"

  backend:
    driver: bridge
    internal: true

使用外部网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - external-network

networks:
  external-network:
    external: true
    name: my-external-network

网络管理 #

查看网络 #

bash
# 列出所有网络
docker network ls

# 过滤网络
docker network ls --filter driver=bridge
docker network ls --filter name=my

# 查看网络详情
docker network inspect mynetwork

# 格式化输出
docker network inspect --format '{{.IPAM.Config}}' mynetwork

更新容器网络 #

bash
# 连接网络
docker network connect mynetwork mycontainer

# 断开网络
docker network disconnect mynetwork mycontainer

# 连接时指定IP
docker network connect --ip 172.20.0.50 mynetwork mycontainer

# 连接时指定别名
docker network connect --alias webserver mynetwork mycontainer

删除网络 #

bash
# 删除网络
docker network rm mynetwork

# 删除所有未使用网络
docker network prune

# 删除时排除特定网络
docker network prune --filter "label!=keep"

网络故障排除 #

常见问题 #

bash
# 容器无法通信
# 1. 检查是否在同一网络
docker inspect --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' container1
docker inspect --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' container2

# 2. 检查DNS解析
docker exec container1 nslookup container2

# 3. 检查网络配置
docker network inspect mynetwork

网络诊断工具 #

bash
# 使用netshoot诊断
docker run --rm --network mynetwork nicolaka/netshoot ping container2
docker run --rm --network mynetwork nicolaka/netshoot traceroute container2
docker run --rm --network mynetwork nicolaka/netshoot nslookup container2
docker run --rm --network mynetwork nicolaka/netshoot curl -v http://container2:80

查看网络流量 #

bash
# 使用tcpdump抓包
docker run --rm --net container:mycontainer nicolaka/netshoot tcpdump -i eth0

# 查看连接
docker exec mycontainer netstat -tunap

网络最佳实践 #

1. 使用自定义网络 #

bash
# 推荐
docker network create mynetwork
docker run --network mynetwork myapp

# 不推荐
docker run myapp  # 使用默认bridge

2. 网络隔离 #

yaml
# 前后端分离
networks:
  frontend:
  backend:
    internal: true  # 后端网络隔离

3. 合理规划IP #

bash
# 不同环境使用不同网段
docker network create --subnet=172.20.0.0/16 dev-network
docker network create --subnet=172.21.0.0/16 prod-network

4. 使用网络别名 #

bash
# 服务发现
docker run --network-alias db mydb
docker run --network-alias cache myredis

小结 #

本节学习了Docker自定义网络的配置:

  • 创建和配置自定义网络
  • 网络参数详解
  • 多网络连接
  • Docker Compose网络配置
  • 网络故障排除

下一步 #

接下来,让我们学习 容器互联,了解容器间通信的详细方法。