个人随笔
目录
Docker容器网络与通信原理深度解析(含实战案例)
2026-06-27 18:01:22
Docker 容器的网络隔离与通信是容器化部署的核心知识点,所有微服务、容器集群的网络互通都基于底层 Docker 网络模型实现。本文将从默认网络原理、四大网络模型特性、单机通信机制、跨主机通信方案四个维度,结合完整实战命令、原理图解与落地案例,全方位讲解 Docker 容器网络核心知识,适合运维、开发、集群入门学习与笔记收藏。

一、Docker容器默认网络模型

1.1 核心原理图

Docker 安装后会自动初始化一套默认网桥网络,是单机容器通信的基础,核心由 docker0 网桥veth pair 虚拟设备对 组成,实现容器网络隔离与数据转发。


1.2 核心名词详解

1.2.1 docker0(默认网桥)

docker0 是 Docker 自动创建的二层虚拟网桥设备,本质是虚拟交换机,核心作用是打通宿主机与容器、容器与容器之间的网络:
  • 支持多端口接入,实现多容器多对多通信转发
  • 默认网段为 172.17.0.0/16,网关为 172.17.0.1
  • 所有未指定网络的容器,默认接入 docker0 网桥

1.2.2 veth pair(虚拟设备对)

veth pair 是 Linux 内核提供的成对虚拟以太网设备,是实现容器网络隔离通信的核心载体,解决网络命名空间隔离后的通信问题:
  • 设备成对出现,数据双向互通,一端进一端出
  • 一端绑定容器网络命名空间,作为容器内网网卡
  • 一端绑定宿主机网络命名空间,接入 docker0 网桥

二、Docker默认网络通信工作原理

基于默认 bridge 网桥模式,容器通信分为两大核心场景:容器访问外网外网访问容器,均通过 iptables 规则实现 NAT 转发与端口映射。

2.1 容器访问外网(出站通信)

2.1.1 通信原理

容器发起外网请求时,数据包经 veth pair 转发至 docker0 网桥,宿主机通过 iptables NAT 伪装规则(MASQUERADE),将容器内网 IP 转换为宿主机公网 IP,实现容器上网。


2.1.2 实战验证

1. 启动 Nginx 测试容器,映射宿主机8081端口到容器80端口
# docker run -d --name web1 -p 8081:80 nginx:latest
2. 查看 NAT 出站转发规则
# iptables -t nat -vnL POSTROUTING
输出结果(核心规则):
Chain POSTROUTING (policy ACCEPT 7 packets, 766 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:80
规则说明:容器 172.17.0.2 的80端口出站流量,自动伪装为宿主机IP,实现外网访问。

2.2 外网访问容器(入站通信)

2.2.1 通信原理

外网用户访问宿主机映射端口时,Docker 通过 iptables DOCKER 链 DNAT 规则,将宿主机端口流量转发至对应容器内网IP和端口,实现外网访问容器服务。

2.2.2 实战验证

查看 Docker 入站转发规则
# iptables -t nat -vnL DOCKER
输出结果(核心规则):
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8081 to:172.17.0.2:80
规则说明:所有访问宿主机8081端口的流量,全部转发至容器 172.17.0.2:80 服务。

三、Docker四大网络模型全解析

Docker 内置四种核心网络模型,适配网络隔离、性能优先、端口共享、服务互通等不同业务场景,创建容器时通过 --network 参数指定,未指定则默认 bridge 模式。

3.1 四大网络模型特性对比

网络模式
使用命令
核心特性
隔离性
适用场景
bridge(桥接模式)
--network bridge
默认模式,独立网络命名空间,通过docker0网桥通信,默认172.17.0.0/16网段,支持端口映射、单机容器互通
绝大多数单机容器业务、微服务单机部署
host(主机模式)
--network host
直接共享宿主机网络命名空间,无独立网卡IP,容器端口直接绑定宿主机端口,网络性能无损耗
极低
高性能服务、监控采集、网关服务,无需网络隔离场景
none(空网络模式)
--network none
仅保留本地回环接口lo,无任何外网、内网网卡,完全断绝所有网络通信
最高
纯本地计算、数据处理、无网络需求的安全隔离场景
container(联盟模式)
--network container:容器名/ID
多个容器共享同一个网络命名空间,共享IP和端口,文件系统、进程空间相互隔离
服务附属组件、日志采集、同组服务本地互通场景

四、四大网络模型实战案例

4.1 基础网络查看命令

1. 查看Docker所有内置网络
# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a26c79961d8c   bridge    bridge    local
d04ce0d0e6ca   host      host      local
a369d8e58a41   none      null      local
2. 查看bridge网络详细配置(网段、网关、绑定容器等)
# docker network inspect bridge
3. 查看Docker支持的所有网络驱动
# docker info | grep Network
  Network: bridge host ipvlan macvlan null overlay

4.2 自定义Bridge网络实战

默认bridge网络网段固定,生产环境常自定义网桥,指定专属网段、网关,实现网络资源隔离。
1. 查看网络创建帮助
# docker network create --help
2. 创建自定义网桥 mybr0(指定网段、网关、网桥名称)
# docker network create -d bridge --subnet "192.168.100.0/24" --gateway "192.168.100.1" -o com.docker.network.bridge.name=docker1 mybr0
3. 查看新建网络
# docker network ls
4. 宿主机查看生成的虚拟网桥docker1
# ifconfig
5. 启动容器并绑定自定义网桥
# docker run -it --network mybr0 --rm busybox
/ # ifconfig
容器将获取 192.168.100.0/24 网段IP,实现自定义网络隔离通信。

4.3 Host网络模式实战

Host模式容器完全共享宿主机网络栈,无独立IP,直接使用宿主机网卡与端口,性能最优。
1. 查看host网络详情
# docker network inspect host
2. 启动host模式busybox容器,查看网络
# docker run -it --network host --rm busybox
/ # ifconfig
可看到容器内完全展示宿主机所有网卡(docker0、物理网卡、lo等),与宿主机网络完全一致。
3. 部署Nginx服务验证通信
# docker run -d --network host nginx:latest
# docker ps
# ss -anput | grep ":80"
4. 访问验证(直接访问宿主机IP)
# curl http://192.168.255.161
成功返回Nginx默认页面,证明容器与宿主机网络完全共享。

4.4 None网络模式实战

None模式容器禁用所有网络设备,仅保留本地回环接口,完全隔离内外网络,安全性最高。
# docker network inspect none
# docker run -it --network none --rm busybox:latest
/ # ifconfig
执行后仅显示 lo 回环网卡,无法访问外网、宿主机及其他容器。

4.5 Container联盟网络模式实战

联盟模式核心:多容器共享网络命名空间,独立文件系统与进程空间,容器间可通过127.0.0.1直接通信。
1. 启动基础容器c1(默认bridge网络)
# docker run -it --name c1 --rm busybox:latest
/ # ifconfig
2. 启动c2容器,共享c1网络命名空间
# docker run -it --name c2 --network container:c1 --rm busybox:latest
/ # ifconfig
c2与c1拥有完全一致的IP和网卡信息。
3. 跨容器本地通信验证
# c2容器内执行
/ # echo "hello world" >> /tmp/index.html
/ # httpd -h /tmp
/ # netstat -npl

# c1容器内访问
# docker exec c1 wget -O - -q 127.0.0.1
可成功获取c2创建的页面内容,证明网络互通;但c1无法查看c2的/tmp文件,验证仅网络共享、文件系统隔离特性。

五、跨Docker Host容器通信实现

5.1 跨主机通信必要性

默认Docker网络仅支持单机容器互通,不同宿主机的容器网段重复、无法直接通信。若采用端口映射实现跨主机访问,会严重消耗宿主机端口资源,无法适配集群、微服务多节点部署场景,因此需要专门的跨主机网络方案。

5.2 主流跨主机通信方案

5.2.1 Docker原生方案

  • overlay网络:基于VXLAN协议封装,Docker原生跨主机覆盖网络,适配集群环境
  • macvlan网络:将宿主机物理网卡拆分为多个子接口,容器直接接入物理网段,独立IP通信

5.2.2 第三方主流方案

  • 隧道方案:Flannel(UDP/VXLAN)、Weave(UDP/VXLAN)、OpenvSwitch(VXLAN/GRE)
  • 路由方案:Calico(BGP协议+IPIP隧道),基于路由转发实现跨主机容器通信

5.3 Flannel核心原理

Flannel是CoreOS专为Kubernetes/容器集群设计的Overlay网络工具,核心作用是为集群所有节点容器分配唯一全局IP,实现跨主机容器直接互通

5.3.1 Overlay网络简介

Overlay网络是在现有物理网络基础上,通过协议封装构建的虚拟二层网络,无需改造底层物理架构,可突破传统VLAN数量限制,支持大规模容器集群网络隔离与转发,是当前容器跨节点通信的主流方案。

5.3.2 Flannel工作流程


  1. 源容器数据包经veth pair、docker0网桥转发至宿主机flannel0虚拟网卡
  2. flanneld服务读取etcd存储的集群子网路由表,获取目标节点网段信息
  3. 数据包经UDP/VXLAN封装,通过物理网络转发至目标宿主机flanneld服务
  4. 目标节点解包后,经flannel0、docker0网桥转发至目标容器,完成跨主机通信

5.4 Etcd集群部署(Flannel依赖)

Flannel依赖etcd存储网络配置、子网分配与节点路由信息,需先部署双节点etcd集群。

5.4.1 环境准备

  • 两台节点:node1(192.168.255.154)、node2(192.168.255.155)
  • 关闭防火墙、SELinux,开启内核IP转发
1. 主机名配置
# node1执行
hostnamectl set-hostname node1
# node2执行
hostnamectl set-hostname node2
2. 静态IP配置(两台节点分别配置对应IP)
# vim /etc/sysconfig/network-scripts/ifcfg-ens33
# node1 IPADDR=192.168.255.154
# node2 IPADDR=192.168.255.155
PREFIX="24"
GATEWAY="192.168.255.2"
DNS1="119.29.29.29"
3. 主机名IP解析(两台节点均配置)
# vim /etc/hosts
192.168.255.154 node1
192.168.255.155 node2
4. 开启内核转发(两台节点)
# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
# sysctl -p

5.4.2 Etcd安装与配置

1. 两台节点安装etcd
# yum -y install etcd
2. node1节点etcd核心配置
# vim /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/node1.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="node1"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.255.154:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.255.154:2379,http://192.168.255.155:4001"
ETCD_INITIAL_CLUSTER="node1=http://192.168.255.154:2380,node2=http://192.168.255.155:2380"
3. node2节点etcd核心配置
# vim /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/node2.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
ETCD_NAME="node2"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.255.155:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.255.155:2379,http://192.168.255.155:4001"
ETCD_INITIAL_CLUSTER="node1=http://192.168.255.154:2380,node2=http://192.168.255.155:2380"

5.4.3 启动集群并验证

1. 启动etcd服务(两台节点)
# systemctl enable etcd
# systemctl start etcd
2. 检查端口监听
# netstat -tnlp | grep -E  "4001|2380"
3. 检查集群健康状态
# etcdctl -C http://192.168.255.154:2379 cluster-health
# etcdctl member list
输出 cluster is healthy 即为集群部署成功。

5.5 Flannel集群部署与配置

5.5.1 安装Flannel

# 两台节点执行
yum -y install flannel

5.5.2 配置Flannel

两台节点统一配置flanneld文件
# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.255.154:2379,http://192.168.255.155:2379"
FLANNEL_ETCD_PREFIX="/atomic.io/network"
FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/ --etcd-endpoints=http://192.168.255.154:2379,http://192.168.255.155:2379 --iface=ens33"

5.5.3 Etcd写入Flannel网段配置

# node1执行,定义集群统一容器网段
etcdctl mk /atomic.io/network/config '{"Network":"172.21.0.0/16"}'
# 查看配置
etcdctl get /atomic.io/network/config

5.5.4 启动Flannel服务

# 两台节点执行
systemctl enable flanneld;systemctl start flanneld

5.5.5 查看Flannel生成网络配置

# 查看子网分配信息
cat /run/flannel/subnet.env
# 查看虚拟网卡flannel0
ip a s
node1分配网段:172.21.31.0/24,node2分配网段:172.21.55.0/24,集群网段统一且不重复。

5.6 Docker适配Flannel网络

修改Docker启动参数,适配Flannel网段、MTU与IP伪装规则
1. node1 Docker配置修改
# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.21.31.1/24 --ip-masq=true --mtu=1472
2. node2 Docker配置修改
# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.21.55.1/24 --ip-masq=true --mtu=1472
3. 重启Docker生效(两台节点)
systemctl daemon-reload
systemctl restart docker
ip a s

5.7 跨主机容器通信最终验证

1. node1启动容器,IP:172.21.31.2
docker run -it --rm busybox:latest
ping 172.21.55.2
2. node2启动容器,IP:172.21.55.2
docker run -it --rm busybox:latest
ping 172.21.31.2
验证结果:两台不同宿主机的容器可互通无丢包,跨主机容器通信搭建完成。

六、总结与场景选型

6.1 单机网络模型选型

  • 常规业务:默认 bridge 模式,兼顾隔离性与互通性
  • 高性能业务:host 模式,无网络转发损耗
  • 安全隔离业务:none 模式,完全断绝网络
  • 附属协同服务:container 联盟模式,共享网络、节省端口

6.2 跨主机网络选型

  • 小规模集群、简单互通:Flannel(部署简单、稳定性高)
  • 大规模集群、精细化网络策略:Calico(支持网络策略、路由精准控制)
  • 物理网段直接接入:macvlan 原生网络方案

6.3 核心知识点复盘

  1. Docker单机网络核心依赖 网络命名空间、veth pair、docker0网桥、iptables 四大组件
  2. 四大网络模型的核心差异是网络命名空间的共享与隔离程度
  3. 跨主机通信的本质是通过Overlay隧道/路由方案,打破单机网络隔离,实现全局容器IP互通
  4. Flannel+Etcd是入门级容器集群跨主机网络的最优落地方案,部署简单、适配性广
 5

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2