在容器化技术中,网络隔离与通信是最核心的挑战之一。Docker通过libnetwork库实现了CNM(Container Network Model)模型,提供了多种网络驱动模式,每种模式都有其特定的应用场景和底层实现原理。
bridge是Docker默认的网络驱动模式,其工作流程如下:
关键配置参数可以通过修改/etc/docker/daemon.json实现:
json复制{
"bip": "172.18.0.1/16",
"fixed-cidr": "172.18.1.0/24",
"mtu": 1500
}
注意:修改网络配置后需要重启docker服务(systemctl restart docker),但会重建所有容器网络栈
host模式直接使用宿主机网络栈,其性能特点表现为:
典型使用场景包括:
bash复制# 性能测试对比命令
docker run --rm --network=host alpine ping -c 100 www.google.com
docker run --rm --network=bridge alpine ping -c 100 www.google.com
overlay网络通过以下组件实现跨主机通信:
创建overlay网络示例:
bash复制# 需要先初始化swarm集群
docker swarm init --advertise-addr <MANAGER-IP>
# 创建overlay网络
docker network create -d overlay --subnet=10.0.9.0/24 my-overlay
remote驱动允许集成第三方SDN方案,开发流程包括:
实现Docker网络驱动插件接口:
插件注册示例:
go复制func main() {
driver := new(myDriver)
h := drivers.NewHandler(driver)
h.ServeUnix("myplugin", 0)
}
null模式提供完全空白的网络环境,典型配置流程:
bash复制ip netns add mynet
bash复制ip link add veth0 type veth peer name veth1
ip link set veth1 netns mynet
bash复制ip netns exec mynet ip addr add 192.168.1.2/24 dev veth1
ip netns exec mynet ip link set veth1 up
ip netns exec mynet ip route add default via 192.168.1.1
创建自定义网络时的完整参数示例:
bash复制docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
--opt com.docker.network.bridge.name=mybr0 \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
--opt com.docker.network.bridge.mtu=1450 \
my-network
关键参数说明:
--opt com.docker.network.bridge.enable_icc=false 可禁用容器间通信--opt com.docker.network.bridge.host_binding_ipv4 控制端口绑定IP动态连接/断开网络的操作方法:
bash复制# 连接运行中容器到网络
docker network connect my-network my-container
# 指定IP地址连接
docker network connect --ip 172.28.5.33 my-network my-container
# 从网络断开连接
docker network disconnect my-network my-container
重要:连接不同网络的容器时,端口映射规则不会自动同步,需要重新发布端口
bash复制docker exec -it my-container ip addr
bash复制docker exec -it container1 ping container2
bash复制# 在主机上抓取docker0流量
tcpdump -i docker0 -w docker.pcap
# 在容器内抓包需要特权模式
docker run --rm --privileged -it alpine tcpdump -i eth0
bash复制apt-get install graphviz
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nicolaka/netshoot \
dot -Tpng <(docker network inspect -f '{{dot}}' bridge) > network.png
Docker网络在内核路由表中的典型表现:
code复制Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
关键字段解释:
Docker网络依赖的iptables规则主要包括:
bash复制Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
bash复制Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-1 all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
直接操作network namespace的进阶方法:
bash复制docker inspect -f '{{.NetworkSettings.SandboxKey}}' my-container
bash复制nsenter --net=/var/run/docker/netns/<namespace-id> bash
bash复制nsenter --net=/var/run/docker/netns/<namespace-id> ip route show
iptables -t nat -L -nsysctl net.ipv4.ip_forwarddocker run --rm busybox nslookup google.comdocker network inspect <network>iptables -L DOCKER-USER -ndocker exec -it container1 ping container2_ipss -tulnp | grep <port>docker inspect -f '{{.NetworkSettings.Ports}}' <container>bash复制# 安装iperf3
docker run --rm -it --network=host networkstatic/iperf3 -s
# 在另一台主机测试
docker run --rm -it --network=host networkstatic/iperf3 -c <server_ip>
bash复制# 增加连接跟踪表大小
echo 65536 > /proc/sys/net/nf_conntrack_max
# 调整TCP缓冲区大小
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
# 优化VXLAN性能
ethtool -K <interface> tx-udp_tnl-segmentation on
bash复制# 创建隔离网络
docker network create --internal isolated-net
# 禁用容器间通信
docker network create --opt com.docker.network.bridge.enable_icc=false secure-net
bash复制# 限制容器访问特定IP
iptables -I DOCKER-USER -i docker0 -d 192.168.1.0/24 -j DROP
# 允许特定容器访问外网
iptables -I DOCKER-USER -i docker0 -s 172.17.0.2 -j ACCEPT
bash复制# 检查开放端口
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine \
sh -c "apk add -U nmap && nmap -sT -p- 172.17.0.1"