📋 目录


一、Docker网络基础

1.1 为什么需要Docker网络?

在容器化应用中,我们经常需要:

  • 容器间通信:微服务架构中,服务之间需要相互调用
  • 隔离性:不同项目的容器应该在独立网络中
  • 可扩展性:轻松添加新容器到现有网络
  • 服务发现:通过容器名称直接通信,无需记忆IP

1.2 Docker网络核心概念

概念说明
Network Driver网络驱动,决定网络的工作方式
Network网络实例,容器连接的虚拟网络
Endpoint网络端点,容器在网络中的连接点
Sandbox沙盒,容器的网络栈(网卡、路由表等)

1.3 Docker网络命令速查

# 网络管理命令
docker network ls                    # 列出所有网络
docker network create <网络名>       # 创建网络
docker network rm <网络名>           # 删除网络
docker network inspect <网络名>      # 查看网络详情
docker network connect <网络> <容器> # 容器连接网络
docker network disconnect <网络> <容器> # 容器断开网络

二、Docker网络类型详解

Docker提供了多种网络驱动,每种适用于不同场景。

2.1 Bridge网络(桥接网络)

特点:

  • Docker的默认网络模式
  • 容器通过虚拟网桥连接
  • 同一网络内容器可互相通信
  • 适合单主机部署

默认bridge网络限制:

  • 容器间只能通过IP通信,不能用容器名
  • 不推荐在生产环境使用

自定义bridge网络优势:

  • ✅ 支持容器名解析(自动DNS)
  • ✅ 更好的隔离性
  • ✅ 可自定义子网和网关
  • ✅ 动态连接/断开容器

使用场景:

  • 同一主机上的多容器应用
  • 微服务架构(单机版)
  • 开发测试环境

2.2 Host网络(主机网络)

特点:

  • 容器与宿主机共享网络栈
  • 无网络隔离
  • 性能最高(无NAT转换)

使用场景:

  • 需要极致性能的场景
  • 容器需要访问大量端口

缺点:

  • 端口冲突风险高
  • 安全性较差

2.3 Overlay网络(覆盖网络)

特点:

  • 支持跨主机容器通信
  • 需要Swarm或Kubernetes
  • 适合集群环境

使用场景:

  • Docker Swarm集群
  • 分布式微服务

2.4 Macvlan网络

特点:

  • 容器拥有独立MAC地址
  • 容器看起来像网络中的物理设备

使用场景:

  • 需要容器直接接入物理网络
  • 传统应用迁移

2.5 None网络

特点:

  • 容器无网络连接
  • 完全隔离

使用场景:

  • 安全性要求极高的场景
  • 不需要网络的批处理任务

三、实战:创建3容器自定义网络

本节将演示如何创建一个自定义bridge网络,并在其中运行3个容器,实现容器间的互联互通。

3.1 实验目标

  • 创建自定义bridge网络
  • 启动3个Alpine容器
  • 容器间通过名称ping通
  • 理解Docker DNS机制

3.2 准备基础镜像

首先拉取轻量级的Alpine Linux镜像:

docker pull alpine:latest

为什么选择Alpine?

  • 超小体积(仅5MB左右)
  • 包含基础网络工具
  • 启动速度快
  • 适合做网络测试

验证镜像:

docker images | Select-String "alpine"

输出示例:

alpine       latest    c1aabb73d233   2 weeks ago   7.33MB

3.3 创建自定义Bridge网络

方法1:使用默认配置
docker network create test-network
方法2:指定子网和网关(推荐)
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \
  --gateway=172.20.0.254 \
  test-network

参数详解:

参数说明示例值
--driver bridge指定网络驱动为桥接模式bridge
--subnet子网地址范围172.20.0.0/16
--gateway网关地址172.20.0.254
--ip-range容器可分配IP范围172.20.1.0/24
--aux-address保留IP地址-

为什么使用172.20.0.0/16?

  • 避免与常见局域网冲突(192.168.x.x)
  • /16掩码提供65534个可用IP
  • 172.16.0.0-172.31.255.255是私有地址段

验证网络创建成功:

docker network ls | Select-String "test-network"

输出示例:

a1b2c3d4e5f6   test-network   bridge    local

查看网络详细信息:

docker network inspect test-network

输出示例(JSON格式):

[
    {
        "Name": "test-network",
        "Id": "a1b2c3d4e5f6...",
        "Driver": "bridge",
        "IPAM": {
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.254"
                }
            ]
        },
        "Containers": {},
        "Options": {}
    }
]

3.4 启动3个容器并加入网络

方式1:创建时指定网络
# 启动container-1
docker run -dit \
  --name container-1 \
  --network test-network \
  --ip 172.20.0.10 \
  alpine:latest

# 启动container-2
docker run -dit \
  --name container-2 \
  --network test-network \
  --ip 172.20.0.11 \
  alpine:latest

# 启动container-3
docker run -dit \
  --name container-3 \
  --network test-network \
  --ip 172.20.0.12 \
  alpine:latest

参数说明:

  • -d:后台运行
  • -i:保持STDIN开启
  • -t:分配伪终端
  • --name:容器名称
  • --network:指定网络
  • --ip:指定IP地址(可选)
方式2:先创建后连接
# 先启动容器
docker run -dit --name container-1 alpine:latest

# 后连接网络
docker network connect test-network container-1

验证容器启动成功:

docker ps | Select-String "container-"

输出示例:

CONTAINER ID   IMAGE          STATUS         NAMES
abc123def456   alpine:latest  Up 10 seconds  container-1
def456ghi789   alpine:latest  Up 8 seconds   container-2
ghi789jkl012   alpine:latest  Up 6 seconds   container-3

查看网络中的容器:

docker network inspect test-network

在输出的Containers字段中,应该能看到3个容器的信息:

"Containers": {
    "abc123...": {
        "Name": "container-1",
        "IPv4Address": "172.20.0.10/16"
    },
    "def456...": {
        "Name": "container-2",
        "IPv4Address": "172.20.0.11/16"
    },
    "ghi789...": {
        "Name": "container-3",
        "IPv4Address": "172.20.0.12/16"
    }
}

3.5 测试容器间连通性

测试1:通过容器名称ping(推荐)

进入container-1:

docker exec -it container-1 sh

在容器内ping其他容器:

# Ping container-2(通过名称)
ping -c 4 container-2

# Ping container-3(通过名称)
ping -c 4 container-3

成功输出示例:

PING container-2 (172.20.0.11): 56 data bytes
64 bytes from 172.20.0.11: seq=0 ttl=64 time=0.123 ms
64 bytes from 172.20.0.11: seq=1 ttl=64 time=0.098 ms
64 bytes from 172.20.0.11: seq=2 ttl=64 time=0.105 ms
64 bytes from 172.20.0.11: seq=3 ttl=64 time=0.112 ms

--- container-2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss

关键观察点:

  • ✅ 容器名称自动解析为IP地址
  • ✅ 延迟极低(微秒级)
  • ✅ 无丢包
测试2:通过IP地址ping
# Ping container-2的IP
ping -c 4 172.20.0.11

# Ping container-3的IP
ping -c 4 172.20.0.12
测试3:跨容器双向通信

退出container-1,进入container-2:

exit
docker exec -it container-2 sh

在container-2中ping container-1和container-3:

ping -c 4 container-1
ping -c 4 container-3
测试4:查看网络配置

在容器内执行:

# 查看网卡信息
ip addr show

# 查看路由表
ip route

# 查看DNS配置
cat /etc/resolv.conf

示例输出:

# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP>
    inet 127.0.0.1/8 scope host lo
2: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP>
    inet 172.20.0.10/16 brd 172.20.255.255 scope global eth0

# ip route
default via 172.20.0.254 dev eth0
172.20.0.0/16 dev eth0 scope link src 172.20.0.10

# cat /etc/resolv.conf
nameserver 127.0.0.11

重要发现:

  • DNS服务器是127.0.0.11(Docker内置DNS)
  • 这就是容器名称解析的秘密!

四、容器网络故障排查

4.1 常见问题1:容器无法ping通

症状:

ping: bad address 'container-2'

可能原因及解决方案:

原因1:容器未在同一网络

检查容器网络:

docker inspect container-1 | grep NetworkMode
docker inspect container-2 | grep NetworkMode

解决:

docker network connect test-network container-2
原因2:使用默认bridge网络

默认bridge网络不支持容器名解析!

解决:创建自定义网络并迁移容器。

原因3:防火墙阻止

检查Docker防火墙规则:

# Linux系统
iptables -L DOCKER-USER

# Windows系统
# 检查Windows防火墙设置

4.2 常见问题2:容器获取不到IP

症状: 容器启动后,docker inspect显示IP为空

解决方案:

# 重启容器
docker restart container-1

# 或重新创建容器
docker rm container-1
docker run -dit --name container-1 --network test-network alpine

4.3 常见问题3:网络冲突

症状:

Error response from daemon: Pool overlaps with other one on this address space

原因: 子网与现有网络冲突

解决:

# 查看所有网络的子网
docker network ls
docker network inspect <network-id>

# 使用不同的子网
docker network create --subnet=172.21.0.0/16 test-network2

4.4 网络调试工具安装

在Alpine容器中安装网络工具:

# 进入容器
docker exec -it container-1 sh

# 更新包管理器
apk update

# 安装常用网络工具
apk add curl          # HTTP客户端
apk add wget          # 文件下载
apk add bind-tools    # nslookup/dig
apk add traceroute    # 路由跟踪
apk add tcpdump       # 抓包工具
apk add netcat-openbsd # 网络瑞士军刀

使用示例:

# DNS查询
nslookup container-2

# 测试端口连通性
nc -zv container-2 80

# HTTP请求
curl http://container-2:8080

五、进阶:跨主机容器通信

5.1 使用Overlay网络

初始化Swarm模式:

docker swarm init

创建overlay网络:

docker network create \
  --driver overlay \
  --attachable \
  my-overlay-network

跨主机启动容器:

# 在主机1
docker run -dit --name app1 --network my-overlay-network nginx

# 在主机2
docker run -dit --name app2 --network my-overlay-network nginx

# app1和app2可以直接通信!

5.2 使用Docker Compose管理网络

创建docker-compose.yml

version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      - frontend
    ports:
      - "8080:80"

  app:
    image: python:3.9-alpine
    networks:
      - frontend
      - backend
    depends_on:
      - db

  db:
    image: mysql:8.0
    networks:
      - backend
    environment:
      MYSQL_ROOT_PASSWORD: secret

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # 不允许外部访问

启动:

docker-compose up -d

六、最佳实践与性能优化

6.1 网络设计最佳实践

1. 合理划分网络
┌─────────────────────────────────┐
│   Frontend Network (public)     │
│   ┌─────┐  ┌─────┐  ┌─────┐    │
│   │Nginx│  │Nginx│  │Nginx│    │
│   └──┬──┘  └──┬──┘  └──┬──┘    │
└──────┼────────┼────────┼────────┘
       │        │        │
┌──────┼────────┼────────┼────────┐
│   App Network (internal)        │
│   ┌──┴──┐  ┌──┴──┐  ┌──┴──┐    │
│   │ App │  │ App │  │ App │    │
│   └──┬──┘  └──┬──┘  └──┬──┘    │
└─────┼────────┼────────┼─────────┘
      │        │        │
┌─────┼────────┼────────┼─────────┐
│   Data Network (isolated)       │
│   ┌──┴──┐  ┌──┴──┐              │
│   │MySQL│  │Redis│              │
│   └─────┘  └─────┘              │
└─────────────────────────────────┘
2. 使用明确的命名规范
# 不好的命名
docker network create net1

# 好的命名
docker network create myapp-frontend-net
docker network create myapp-backend-net
docker network create myapp-data-net
3. 限制网络访问
# 创建内部网络(不允许外部访问)
docker network create --internal backend-net
4. 使用网络别名
docker run -dit \
  --name web1 \
  --network frontend \
  --network-alias webserver \
  nginx

docker run -dit \
  --name web2 \
  --network frontend \
  --network-alias webserver \
  nginx

# 客户端可以通过'webserver'访问,Docker自动负载均衡

6.2 性能优化建议

1. 选择合适的网络驱动
驱动性能适用场景
host⭐⭐⭐⭐⭐高性能单主机应用
bridge⭐⭐⭐⭐常规单主机应用
overlay⭐⭐⭐跨主机集群
macvlan⭐⭐⭐⭐需要独立MAC地址
2. 减少网络跳转
# 不好:容器跨多个网络
docker run --network net1 ...
docker network connect net2 container
docker network connect net3 container

# 好:直接连接目标网络
docker run --network net1 ...
3. 使用DNS缓存

在容器内配置DNS缓存:

FROM alpine
RUN apk add --no-cache dnsmasq
# 配置dnsmasq...
4. 监控网络性能
# 查看容器网络统计
docker stats container-1

# 使用iftop监控流量
docker run -it --net=host --pid=host --rm \
  nicolaka/netshoot iftop

6.3 安全加固建议

1. 禁用容器间通信(特殊场景)
docker network create --opt com.docker.network.bridge.enable_icc=false secure-net
2. 启用网络加密(Overlay)
docker network create \
  --driver overlay \
  --opt encrypted \
  encrypted-overlay
3. 使用网络策略
# 使用Docker Swarm或Kubernetes实现网络策略
# 限制特定服务间的通信
4. 定期审计网络配置
# 列出所有网络
docker network ls

# 检查未使用的网络
docker network prune

# 审查网络连接
for net in $(docker network ls -q); do
    echo "=== Network: $(docker network inspect $net --format '{{.Name}}') ==="
    docker network inspect $net --format '{{range $k, $v := .Containers}}{{$v.Name}} {{end}}'
done

七、总结

7.1 核心知识点回顾

知识点要点
网络类型Bridge、Host、Overlay、Macvlan、None
自定义网络优势容器名解析、更好隔离、灵活配置
网络命令create、connect、disconnect、inspect
DNS机制Docker内置DNS(127.0.0.11)自动解析容器名
最佳实践合理划分网络、使用明确命名、限制访问

7.2 实战技能掌握

通过本文,你应该已经掌握:

✅ 创建自定义bridge网络 ✅ 配置子网和网关 ✅ 将容器加入指定网络 ✅ 测试容器间连通性 ✅ 使用容器名称进行通信 ✅ 排查网络故障 ✅ 性能优化和安全加固

7.3 进阶学习路线

Docker网络基础
    ↓
自定义网络实战
    ↓
Docker Compose网络编排
    ↓
Swarm Overlay网络
    ↓
Kubernetes网络(CNI插件)
    ↓
Service Mesh(Istio/Linkerd)

7.4 常用网络模式对比

特性默认Bridge自定义BridgeHostOverlay
容器名解析N/A
网络隔离⚠️
跨主机通信
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
易用性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

7.5 实用网络命令速查卡

# 创建网络
docker network create --driver bridge --subnet 172.20.0.0/16 my-net

# 启动容器并指定网络和IP
docker run -dit --name app --network my-net --ip 172.20.0.10 alpine

# 查看容器IP
docker inspect app --format '{{.NetworkSettings.Networks.my-net.IPAddress}}'

# 连接/断开网络
docker network connect my-net container-name
docker network disconnect my-net container-name

# 查看网络详情
docker network inspect my-net

# 清理未使用网络
docker network prune

🎯 完整实战代码汇总

为方便复现,这里提供完整的命令脚本:

#!/bin/bash
# Docker网络实战脚本

# 1. 清理环境
docker rm -f container-1 container-2 container-3 2>/dev/null
docker network rm test-network 2>/dev/null

# 2. 拉取镜像
docker pull alpine:latest

# 3. 创建自定义网络
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \
  --gateway=172.20.0.254 \
  test-network

# 4. 启动3个容器
docker run -dit --name container-1 --network test-network --ip 172.20.0.10 alpine
docker run -dit --name container-2 --network test-network --ip 172.20.0.11 alpine
docker run -dit --name container-3 --network test-network --ip 172.20.0.12 alpine

# 5. 验证网络
echo "=== Network Info ==="
docker network inspect test-network | grep -A 3 "Containers"

echo "=== Running Containers ==="
docker ps --filter "name=container-"

# 6. 测试连通性
echo "=== Testing Connectivity ==="
docker exec container-1 ping -c 2 container-2
docker exec container-1 ping -c 2 container-3

echo "=== Network Setup Complete! ==="

作者经验分享:Docker网络是容器技术的核心,理解其原理能帮助你更好地设计微服务架构。在实际项目中,建议为不同职责的服务创建独立网络,既保证安全隔离,又便于维护管理。

如果本文对你有帮助,别忘了点赞👍、收藏⭐、关注📌!有任何问题欢迎在评论区讨论~

相关文章推荐

  • 《Windows环境下Docker完整安装配置指南》

文章声明:本文为原创技术文章,欢迎转载,转载请注明出处。

更多推荐