Docker 网络
Docker 网络
简介
Docker 网络是 Docker 容器之间以及容器与外部世界通信的核心机制。当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,实际上是 Linux 的一个 Bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
当创建一个 Docker 容器的时候,同时会创建一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。
网络模式对比
| 网络模式 | 说明 | 使用场景 | 命令示例 |
|---|---|---|---|
| bridge | 桥接模式(默认),通过 docker0 网桥通信 | 大多数单机容器应用 | --net bridge |
| none | 不配置网络,容器没有网络功能 | 安全隔离、离线计算 | --net none |
| host | 和宿主机共享网络命名空间 | 需要高性能网络的场景 | --net host |
| container | 与另一个容器共享网络命名空间 | Sidecar 模式、容器间紧密协作 | --net container:容器名 |
| overlay | 跨主机网络,用于 Swarm/K8s 集群 | 多主机容器通信 | --net overlay网络名 |
| macvlan | 为容器分配真实 MAC 地址 | 需要直接接入物理网络的场景 | --net macvlan网络名 |
理解 Docker0
使用 ip addr 查看网卡信息,可以看到 Docker 创建的虚拟网桥。
原理:
Docker 中的所有网络接口都是虚拟的,虚拟的转发效率高。只要删除容器,对应的一对网桥就没了。

自定义网络
创建自定义网络
# 创建自定义桥接网络
docker network create --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 查看网络列表
docker network ls
# 查看网络详情
docker network inspect mynet使用自定义网络
# 使用自定义网络启动容器
docker run -d -P --name tomcat01 --net mynet tomcat
docker run -d -P --name tomcat02 --net mynet tomcat
# 容器间可以直接通过容器名互相 ping 通
docker exec -it tomcat01 ping tomcat02自定义网络的优势:自带 DNS 解析,容器间可以通过容器名直接访问,不需要使用 --link。
--link 方式(已过时)
在自定义网络出现之前,使用 --link 来实现容器名访问:
# 启动容器并 link 到另一个容器
docker run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02原理:--link 就是在容器的 /etc/hosts 配置中增加一个映射。
# 查看 hosts 映射
docker exec -it tomcat03 cat /etc/hosts网络连通
不同网络下的容器默认不能互相通信,可以使用 docker network connect 打通:
# 将 tomcat00 连接到 mynet 网络
docker network connect mynet tomcat00容器访问外网
容器要想访问外部网络,需要本地系统的转发支持。
# 检查转发是否打开
sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 1
# 如果为 0,手动打开
sysctl -w net.ipv4.ip_forward=1如果在启动 Docker 服务的时候设定 --ip-forward=true,Docker 就会自动设定系统的 ip_forward 参数为 1。
多主机网络(Overlay)
在多主机环境中,需要使用 Overlay 网络来实现跨主机容器通信。
创建 Overlay 网络
# 初始化 Swarm 集群
docker swarm init
# 创建 Overlay 网络
docker network create -d overlay --subnet 10.0.9.0/24 my-overlay-net
# 在不同主机上启动容器并加入同一 Overlay 网络
docker run -d --name container1 --net my-overlay-net nginx
docker run -d --name container2 --net my-overlay-net nginxOverlay 网络原理
Overlay 网络通过 VXLAN 隧道在主机之间建立虚拟网络:
DNS 服务发现
Docker 内置 DNS 服务支持容器名解析:
# 自定义网络中自动启用 DNS
docker network create --driver bridge my-dns-net
# 启动容器时指定 --name,其他容器可通过该名称访问
docker run -d --name my-web --net my-dns-net nginx
docker run -d --name my-api --net my-dns-net nginx
# 在 my-api 容器中可以直接 ping my-web
docker exec -it my-api ping my-web| DNS 特性 | 说明 |
|---|---|
| 默认 bridge 网络 | 不支持自动 DNS,需用 --link |
| 自定义 bridge 网络 | 自动 DNS 解析容器名 |
| Overlay 网络 | 自动 DNS 解析,支持跨主机 |
| 外部 DNS | 通过 --dns 参数指定 |
MacVLAN 网络
MacVLAN 允许容器直接获得物理网络的 MAC 地址,使容器在网络中表现得像一台真实的物理主机。
MacVLAN 工作模式
| 模式 | 说明 | 使用场景 |
|---|---|---|
| bridge | 容器间通过宿主机转发通信 | 最常用,同一父接口下的容器互通 |
| vepa | 流量经过上游交换机转发 | 需要交换机支持反射端口 |
| passthru | 将物理接口直接分配给容器 | SR-IOV 场景,一个容器独占物理接口 |
| private | 容器间完全隔离 | 安全敏感场景 |
创建和使用 MacVLAN 网络
# 查看宿主机物理网卡名称
ip addr show
# 创建 MacVLAN 网络(bridge 模式)
docker network create -d macvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
-o parent=eth0 macvlan-net
# 使用 MacVLAN 网络启动容器
docker run -d --name macvlan-nginx \
--net macvlan-net \
--ip 192.168.1.100 \
nginx:1.24-alpine
docker run -d --name macvlan-redis \
--net macvlan-net \
--ip 192.168.1.101 \
redis:7-alpineMacVLAN 注意事项
MacVLAN 有一个重要限制:宿主机无法直接与 MacVLAN 网络中的容器通信。这是因为流量从物理网卡进入后,宿主机不会将流量转发给自己发出的 MacVLAN 接口。
# 解决方案一:在宿主机上创建一个 macvlan 子接口
ip link add macvlan-shim link eth0 type macvlan mode bridge
ip addr add 192.168.1.200/32 dev macvlan-shim
ip link set macvlan-shim up
ip route add 192.168.1.100/32 dev macvlan-shim
# 解决方案二:使用额外的 bridge 网络并连接容器
docker network create -d bridge --subnet 172.30.0.0/16 mgmt-net
docker network connect mgmt-net macvlan-nginx
# 现在可以通过 172.30.x.x 地址从宿主机访问容器IPvLAN 网络
IPvLAN 与 MacVLAN 类似,但所有容器共享宿主机的 MAC 地址,仅通过不同的 IP 地址区分。这在某些对 MAC 地址有限制的网络环境中非常有用。
# 创建 IPvLAN L2 模式网络
docker network create -d ipvlan \
--subnet 10.10.0.0/24 \
--gateway 10.10.0.1 \
-o parent=eth0 \
-o ipvlan_mode=l2 ipvlan-net
# 创建 IPvLAN L3 模式网络(跨子网通信)
docker network create -d ipvlan \
--subnet 10.20.0.0/16 \
-o parent=eth0 \
-o ipvlan_mode=l3 ipvlan-l3-net
# 使用 IPvLAN 启动容器
docker run -d --name ipvlan-web \
--net ipvlan-net \
--ip 10.10.0.50 \
nginx:1.24-alpineIPvLAN L2 与 L3 模式对比:
| 特性 | L2 模式 | L3 模式 |
|---|---|---|
| 工作层级 | 数据链路层 | 网络层 |
| 跨子网通信 | 不支持 | 支持 |
| 广播/多播 | 支持 | 不支持 |
| 路由需求 | 依赖外部路由 | Docker 内部路由 |
| 性能 | 接近物理网络 | 略有开销(需要路由) |
网络管理命令
# 列出所有网络
docker network ls
# 查看网络详情
docker network inspect 网络名称或ID
# 创建网络
docker network create -d bridge --subnet 172.20.0.0/16 my-custom-net
# 删除网络
docker network rm my-custom-net
# 清理未使用的网络
docker network prune
# 断开容器与网络的连接
docker network disconnect my-net 容器名
# 将容器连接到网络
docker network connect my-net 容器名网络高级配置
指定容器 IP 地址
# 创建自定义网络时定义子网
docker network create --subnet 172.20.0.0/16 --gateway 172.20.0.1 static-net
# 启动时指定固定 IP
docker run -d --name app-server \
--net static-net \
--ip 172.20.0.100 \
nginx:1.24-alpine
# 指定 IP 和 IP6 双栈
docker network create --subnet 172.21.0.0/16 --subnet 2001:db8:1::/64 \
--gateway 172.21.0.1 --gateway 2001:db8:1::1 dual-stack-net
docker run -d --name dual-stack-container \
--net dual-stack-net \
--ip 172.21.0.10 \
--ip6 2001:db8:1::10 \
nginx:1.24-alpine容器端口映射详解
# 随机端口映射(-P 大写)
docker run -d -P --name random-port nginx
# 指定端口映射
docker run -d -p 8080:80 --name fixed-port nginx
# 绑定到指定网卡
docker run -d -p 127.0.0.1:8080:80 --name localhost-only nginx
docker run -d -p 192.168.1.100:8080:80 --name lan-only nginx
# 映射多个端口
docker run -d -p 8080:80 -p 8443:443 --name multi-port nginx
# 映射端口范围
docker run -d -p 3000-3005:3000-3005 --name range-port my-app
# 使用 UDP 协议
docker run -d -p 53:53/udp --name dns-server bind9
# 同时映射 TCP 和 UDP
docker run -d -p 53:53/tcp -p 53:53/udp --name dns-server bind9
# 查看所有端口映射
docker port multi-port网络别名配置
# 创建网络时设置别名
docker run -d --name api-server \
--net mynet \
--network-alias api \
--network-alias api-v1 \
my-api:latest
# 同一网络中的其他容器可以通过以下名称访问
# curl http://api:8080
# curl http://api-v1:8080
# 同一网络中启动多个容器使用相同别名(DNS 轮询)
docker run -d --name api-server-2 \
--net mynet \
--network-alias api \
my-api:latest
# 此时 DNS 查询 "api" 会返回两个容器的 IP(简单的负载均衡)网络内部 DNS 配置
# 指定容器使用的 DNS 服务器
docker run -d --dns 8.8.8.8 --dns 114.114.114.114 nginx
# 指定 DNS 搜索域
docker run -d --dns-search example.com nginx
# 设置容器 hostname
docker run -d --hostname myhost.internal nginx
# 自定义 hosts 映射
docker run -d --add-host db.internal:192.168.1.50 nginx
# 禁用容器的 /etc/hosts 自动修改
docker run -d --network-alias web --dns-opt ndots:2 nginx网络驱动选项
# 限制 bridge 网络的 MTU
docker network create -d bridge \
--opt com.docker.network.bridge.name=br-custom \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
--opt com.docker.network.driver.mtu=1400 \
--subnet 10.50.0.0/16 mtu-net
# 限制容器连接数
docker network create -d bridge \
--opt com.docker.network.bridge.host_binding_ipv4=0.0.0.0 \
restricted-net
# 内置加密的 Overlay 网络
docker network create -d overlay \
--opt encrypted \
--subnet 10.60.0.0/16 secure-overlay-net
# 配置 Overlay 网络的 MTU(通常物理网络 MTU 减去 50 字节 VXLAN 封装开销)
docker network create -d overlay \
--opt overlay.mtu=1450 \
--subnet 10.70.0.0/16 overlay-mtu-net网络性能优化
宿主机网络参数调优
# 查看 Docker 默认的 iptables 规则数量
iptables -t nat -L DOCKER -n --line-numbers | wc -l
# 启用 BBR 拥塞控制算法(提升网络吞吐)
echo "net.core.default_qdisc=fq" >> /etc/sysctl.d/99-docker-network.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/99-docker-network.conf
sysctl -p /etc/sysctl.d/99-docker-network.conf
# 调整网络连接跟踪表大小(大量并发连接时)
echo "net.netfilter.nf_conntrack_max = 262144" >> /etc/sysctl.d/99-docker-network.conf
echo "net.netfilter.nf_conntrack_tcp_timeout_established = 7200" >> /etc/sysctl.d/99-docker-network.conf
# 调整容器端口范围
echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.d/99-docker-network.conf
# 增加网卡接收缓冲区
echo "net.core.rmem_max = 16777216" >> /etc/sysctl.d/99-docker-network.conf
echo "net.core.wmem_max = 16777216" >> /etc/sysctl.d/99-docker-network.conf
# 增加 SYN 队列长度(应对 SYN Flood)
echo "net.ipv4.tcp_max_syn_backlog = 65535" >> /etc/sysctl.d/99-docker-network.conf
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.d/99-docker-network.conf容器网络性能对比
| 网络模式 | 吞吐量 | 延迟 | CPU 开销 | 适用场景 |
|---|---|---|---|---|
| host | 最高 | 最低 | 无 | 高性能计算、DPDK |
| bridge | 高 | 低 | 低 | 大多数应用 |
| macvlan | 高 | 低 | 低 | 需要物理网络直接接入 |
| overlay | 中 | 中 | 高 | 跨主机通信 |
| ipvlan | 高 | 低 | 低 | MAC 地址受限环境 |
使用 host 网络提升性能
# 适用于对网络性能要求极高的场景(如 Redis、Kafka)
docker run -d --net host --name redis-cluster redis:7
# 注意:host 模式下不能使用 -p 映射端口(直接使用宿主机端口)
# 注意:host 模式下端口冲突风险更高,同一端口不能启动多个容器
# 高性能网络工具容器
docker run -d --net host --name traffic-monitor \
nicolaka/netshoot \
tcpdump -i any -w /data/capture.pcap网络安全配置
限制容器网络访问
# 仅允许出站流量(默认拒绝所有入站)
docker run -d --name restricted-web \
--cap-drop NET_RAW \
--cap-drop NET_ADMIN \
nginx
# 使用 --internal 创建完全隔离的网络(无外网访问)
docker network create -d bridge --internal isolated-net
docker run -d --net isolated-net --name offline-app my-app
# 禁止容器修改路由表和 iptables
docker run -d --cap-drop NET_ADMIN --name secure-app my-app
# 限制容器只能访问特定外部网络
# 方法:创建自定义网络 + iptables 规则
docker network create --subnet 10.80.0.0/16 locked-down-net
docker run -d --net locked-down-net --name locked-app my-app
# 在宿主机上用 iptables 限制该网络的出站访问
iptables -I DOCKER-USER -s 10.80.0.0/16 -d 10.0.0.0/8 -j DROP
iptables -I DOCKER-USER -s 10.80.0.0/16 -d 172.16.0.0/12 -j DROP
iptables -I DOCKER-USER -s 10.80.0.0/16 -j ACCEPT使用 userland proxy 控制
# 在 /etc/docker/daemon.json 中禁用 userland-proxy
# userland-proxy 会增加额外的用户态转发开销
cat > /etc/docker/daemon.json << 'EOF'
{
"userland-proxy": false,
"iptables": true
}
EOF
# 重启 Docker 服务
systemctl restart docker
# 禁用后 Docker 将完全依赖 iptables 进行端口转发,性能更好
# 但某些特殊场景(如非 localhost 绑定)可能不兼容网络故障排查
常用排查命令
# 查看容器网络配置
docker inspect 容器名 --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
# 进入容器检查网络
docker exec -it 容器名 bash
# 然后使用 ping、curl、telnet 等工具排查
# 查看容器端口映射
docker port 容器名
# 查看宿主机 iptables 规则
iptables -t nat -L -n
# 查看 docker0 网桥信息
brctl show
# 查看网络流量
tcpdump -i docker0 -nn常见问题及解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 容器无法访问外网 | ip_forward 未开启 | sysctl -w net.ipv4.ip_forward=1 |
| 容器间无法通信 | 处于不同网络 | docker network connect 打通 |
| 容器名无法解析 | 使用默认 bridge | 创建自定义 bridge 网络 |
| 端口冲突 | 宿主机端口被占用 | 更换映射端口或停止占用进程 |
| DNS 解析失败 | DNS 配置错误 | --dns 8.8.8.8 指定 DNS |
容器网络排障实战
容器无法解析域名
# 检查容器内的 DNS 配置
docker exec -it my-container cat /etc/resolv.conf
# 方法一:在 daemon.json 中全局配置 DNS
cat > /etc/docker/daemon.json << 'EOF'
{
"dns": ["223.5.5.5", "8.8.8.8"],
"dns-opts": ["ndots:2", "timeout:2", "attempts:2"]
}
EOF
systemctl restart docker
# 方法二:在 docker run 时指定 DNS
docker run -d --dns 223.5.5.5 --dns 8.8.8.8 nginx
# 方法三:在 docker-compose.yml 中配置
# services:
# web:
# dns:
# - 223.5.5.5
# - 8.8.8.8容器间通信延迟高
# 检查 veth pair 的队列长度
ethtool -l vethxxxxx
# 优化:增大队列长度
ethtool -L vethxxxxx rx 8 tx 8
# 检查宿主机网桥的 stp 状态(不必要的 STP 会导致延迟)
brctl showstp docker0
# 检查 conntrack 表是否满了(常见性能瓶颈)
conntrack -C
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# 如果 conntrack 接近上限,增大它
echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max网络命名空间调试
# 查看容器的网络命名空间
docker inspect my-container --format='{{.NetworkSettings.SandboxKey}}'
# 使用 nsenter 进入容器的网络命名空间(不需要容器内安装工具)
PID=$(docker inspect -f '{{.State.Pid}}' my-container)
nsenter -n -t $PID ip addr
nsenter -n -t $PID ip route
nsenter -n -t $PID iptables -L -n
# 在宿主机上直接测试容器的网络栈
nsenter -n -t $PID curl -s http://localhost:80
nsenter -n -t $PID ping -c 3 8.8.8.8
# 查看容器 veth pair 的对端
nsenter -n -t $PID ip link show eth0
# 记录 ifindex,然后在宿主机上找到对应的 veth
ip link show | grep -A1 "index 对应的index号"网络数据包抓包分析
# 在宿主机上抓取 docker0 网桥上的流量
tcpdump -i docker0 -nn -vvv port 80
# 抓取特定容器的流量(通过 veth 接口)
VETH=$(docker exec my-container cat /sys/class/net/eth0/iflink)
ip link | grep "iflink $VETH" | awk -F: '{print $2}' | tr -d ' '
tcpdump -i $VETH_IFACE -nn -vvv
# 抓取 Overlay 网络的 VXLAN 流量
tcpdump -i eth0 -nn -vvv udp port 4789
# 使用 wireshark 分析抓包文件
tcpdump -i docker0 -w /tmp/docker-capture.pcap
# 下载后在 Wireshark 中打开分析网络连通性自动化检查脚本
#!/bin/bash
# docker-network-check.sh — Docker 网络连通性检查脚本
echo "=== Docker 网络健康检查 ==="
# 检查 Docker 服务状态
echo -n "Docker 服务: "
systemctl is-active docker
# 检查 ip_forward
echo -n "IP 转发: "
cat /proc/sys/net/ipv4/ip_forward
# 检查 docker0 网桥
echo -n "docker0 状态: "
ip link show docker0 | grep "state UP" > /dev/null && echo "UP" || echo "DOWN"
# 检查 iptables DOCKER 链
echo -n "DOCKER 链规则数: "
iptables -t nat -L DOCKER -n | wc -l
# 检查 conntrack 使用率
COUNT=$(cat /proc/sys/net/netfilter/nf_conntrack_count)
MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
echo "conntrack 使用: ${COUNT}/${MAX} ($(echo "scale=2; ${COUNT}*100/${MAX}" | bc)%)"
# 检查各容器的网络连通性
for container in $(docker ps --format '{{.Names}}'); do
IP=$(docker inspect $container --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}')
echo -n "$container ($IP): "
docker exec $container sh -c "ping -c 1 -W 2 8.8.8.8 > /dev/null 2>&1" && echo "外网OK" || echo "外网FAIL"
doneDocker 底层网络实现
Docker 底层的核心技术包括:
Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。
iptables 与 Docker 网络
Docker 大量使用 iptables 实现端口映射和 NAT。理解这些规则对排障至关重要。
# 查看 Docker 创建的所有 iptables 规则
iptables -t filter -L DOCKER -n -v
iptables -t filter -L DOCKER-ISOLATION-STAGE-1 -n -v
iptables -t filter -L DOCKER-ISOLATION-STAGE-2 -n -v
iptables -t nat -L DOCKER -n -v
iptables -t nat -L POSTROUTING -n -v
# Docker 网络隔离原理
# DOCKER-ISOLATION-STAGE-1:拒绝不同 bridge 网络之间的直接通信
# DOCKER-ISOLATION-STAGE-2:通过 docker0 网桥转发到 DOCKER 链处理
# 查看端口映射对应的 DNAT 规则
iptables -t nat -L DOCKER -n | grep 8080
# 例如:DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
# 手动添加规则(谨慎操作)
# 允许特定 IP 访问容器的映射端口
iptables -I DOCKER-USER -s 192.168.1.0/24 -p tcp --dport 3306 -j ACCEPT
iptables -I DOCKER-USER -p tcp --dport 3306 -j DROP网络命名空间详解
# 查看系统所有网络命名空间
ls /var/run/docker/netns/
# 或
ip netns list
# Docker 将容器网络命名空间文件放在此处
ls -la /var/run/docker/netns/
# 手动操作网络命名空间
ip netns add test-ns
ip netns exec test-ns ip link set lo up
ip netns exec test-ns ip addr add 10.99.0.1/24 dev veth-test
# 创建 veth pair 连接两个命名空间
ip link add veth-a type veth peer name veth-b
ip link set veth-b netns test-ns
ip addr add 10.99.0.2/24 dev veth-a
ip link set veth-a up
ip netns exec test-ns ip addr add 10.99.0.1/24 dev veth-b
ip netns exec test-ns ip link set veth-b up
ip netns exec test-ns ping -c 3 10.99.0.2Docker Compose 网络配置
单 compose 文件中的网络
version: "3.8"
services:
web:
image: nginx:1.24-alpine
ports:
- "80:80"
networks:
- frontend
- backend
api:
image: my-api:latest
networks:
- backend
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
networks:
- backend
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
backend:
driver: bridge
internal: true # 隔离网络,无外网访问跨 compose 项目网络共享
# 项目 A:docker-compose-a.yml
version: "3.8"
services:
shared-db:
image: mysql:8.0
networks:
- shared
networks:
shared:
name: shared-external-net # 显式命名以便其他项目引用# 项目 B:docker-compose-b.yml
version: "3.8"
services:
web-app:
image: my-app:latest
networks:
- shared
networks:
shared:
external: true # 使用已存在的外部网络
name: shared-external-netCompose 网络高级配置
version: "3.8"
services:
app:
image: my-app:latest
networks:
app-net:
ipv4_address: 10.100.0.10
aliases:
- app.internal
- app-v1.internal
dns:
- 223.5.5.5
- 8.8.8.8
dns_search:
- mycompany.local
extra_hosts:
- "host.docker.internal:host-gateway"
deploy:
resources:
limits:
# 网络带宽限制(需要插件支持)
memory: 512M
networks:
app-net:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-app
com.docker.network.bridge.enable_icc: "true"
com.docker.network.driver.mtu: 1450
ipam:
config:
- subnet: 10.100.0.0/16
gateway: 10.100.0.1CNI 网络插件
CNI 概述
Container Network Interface(CNI)是 Kubernetes 使用的标准网络接口。Docker 也支持 CNI 插件。
# 安装 CNI 插件
mkdir -p /opt/cni/bin
curl -L https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz | tar -C /opt/cni/bin -xz
# 配置 Docker 使用 CNI
cat > /etc/docker/daemon.json << 'EOF'
{
"bridge": "none",
"ip-forward": true,
"iptables": true
}
EOF常见 CNI 插件对比
| 插件 | 类型 | 性能 | 适用场景 |
|---|---|---|---|
| Calico | BGP + VXLAN | 高 | 大规模集群,支持网络策略 |
| Flannel | VXLAN / host-gw | 中 | 简单易用,中小规模集群 |
| Cilium | eBPF | 最高 | 需要可观测性和安全策略 |
| Weave | VXLAN | 中 | 多云环境,自动发现 |
| Canal | Flannel + Calico | 中高 | 兼顾简单与网络策略 |
特点
优点
缺点
总结
Docker 网络是容器间通信的基础。单机用 bridge 网络,跨主机用 overlay 网络。生产环境建议使用自定义网络而非默认 bridge。
关键知识点
- 部署类主题的核心不是“装成功”,而是“稳定运行、可排障、可回滚”。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- 部署主题通常要同时看镜像、容器、卷、网络和宿主机资源。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 固定镜像标签,记录端口、挂载目录、环境变量和自启动策略。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 使用 latest 导致结果不可复现。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续补齐 Compose 编排、镜像瘦身、安全扫描和镜像仓库治理。
适用场景
- 当你准备把《Docker 网络》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免“latest”带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
复盘问题
- 如果把《Docker 网络》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《Docker 网络》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《Docker 网络》最大的收益和代价分别是什么?
