侧边栏壁纸
博主头像
J&S Blog

顺着一路星光,去往有你的嘉处

  • 累计撰写 14 篇文章
  • 累计创建 5 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Docker网络模式

Administrator
2026-05-24 / 0 评论 / 0 点赞 / 7 阅读 / 0 字

容器的网络实现

上网的要素:

每个容器都有自己的IP地址,、网关(路由)、DNS

容器中的主机名----->容器数据目录下的hostname文件

容器中的DNS---->容器数据目录下的resolv.conf文件

容器中的hosts---->容器数据目录下的hosts文件

如何上网的:默认采用bridge的网桥访问外网

每个容器在启动时,都会创建一组veth对(虚拟网卡对),这一组虚拟网卡,一端接入到容器中成为eth0的容器网卡,一端接入到docker0的网桥上,同时容器将网关地址指向docker0的网桥地址,所有的流量都会发送到docker0的网桥,docker的网桥根据NAT规则(通过iptables进行配置的)将其转发到物理网卡,进行外部网络的访问

Docker支持的网络模式

Bridge网络模式(桥接)

#查看具体的网桥配置

Docker network inspect bridge

Docker network ls

#创建桥接网络

docker network create zgs --subnet 172.17.0.0/24 --gateway 172.17.0.254

#将桥接网络设置为指定容器网络

Docker run -d -it --network zgs nginx:latest

#需要被外部访问到服务

Docker run -d -it --network zgs -p 主机端口:容器端口 nginx:latest

##容器之间互相访问

docker run -d  -it --name demo03  --link demo01:test  busybox:latest

--link demo01:test 已存在容器的名称:别名

配置完成后,即可通过名称或者是别名访问demo01的容器

 

性能开销

与 host 模式相比,Bridge 模式需要经过一层虚拟网桥和 NAT,这会引入轻微的网络性能开销。对于需要极致网络性能的场景(如高频交易),这可能是个问题。

复杂的网络配置

与简单的 host 模式相比,Bridge 网络的配置更复杂,涉及端口映射、网络创建和管理等概念,对新手来说学习曲线稍陡。

默认桥接网络的局限性

容器间通信依赖 IP 地址:

在默认的 bridge 网络上,容器不能通过容器名进行通信,必须使用 --link(不推荐)或直接使用 IP 地址,这非常不灵活。

自动化的缺失:

默认桥接网络不支持自动的 DNS 服务发现、自定义的 DNS 配置和容器连接/断开时的动态更新。

端口冲突

当多个容器都需要映射到宿主机的同一个端口时(例如,两个 Web 服务器都想使用宿主机的 80 端口),会发生端口冲突,需要管理员手动协调。

NAT 带来的复杂性

由于容器位于 Docker 的内部网络中,外部流量需要通过宿主机的 IP 和端口进行 NAT 转换。这有时会使网络流量路径变得不直观,尤其是在进行网络排障或设置防火墙规则时。从容器内部发起的连接,其源 IP 地址对于外部服务来说是宿主机的 IP,而不是容器的 IP。

Host网络模式

复用宿主机网络

在docker中,host模式是docker安装是默认创建的,不能用户认为定义,用来复用宿主机的网络,将容器设置为host模式后,容器的主机名将使用物理机的主机名,容器的hosts文件将使用物理机的hosts文件,因此可以像物理机一样去访问外部网络,并且在物理机中可以查询到容器内需要访问网络的进程

示例:

Docker run -it --network host nginx:latst

应用场景:

容器内的应用需要提供服务,被外部网络访问,并且需要较好的网络性能(外部网络直接访问),因此对比于bridge的桥接网络,该网络性能更好

 

None网络模式

容器没有网卡

如果容器使用该网络模式,则容器将不会创建网卡,也就是在容器有lo的回环接口,仅供测试使用,因此使用该模式的容器,不需要网络访问

 

让两个同处于none网络模式下的容器,可以共享一个网络命名空间,则共享命名空间的容器,可以用过127.0.0.1访问到被共享的容器

docker run -it --name by02 --network none --link container:by01  busybox:latest sh

container:by01 #表示共享by01容器的网络命名空间,也就是可以通过127.0.0.1访问到by01,需要注意在使用是避免端口冲突

 

Macvlan网络模式

macvlan可以用来解决容器跨主机访问的问题,通过给每个容器配置不同且唯一的mac地址,让容器可以直连到物理网络,得到物理网络子网的IP地址,使用物理网络进行跨主机节点之间的访问

原理

Docker的macvlan驱动允许你为每个容器分配一个唯一的MAC地址,并将其直接连接到主机的物理网络接口。容器在网络中表现为“独立的主机”,可以直接从物理网络获取IP地址,并与网络中的其他设备通信

基本原理是:

在宿主机的物理网卡上创建一个虚拟子接口(macvlan类型)

容器通过该子接口与外部通信,而不是使用NAT或桥接

该网络完全绕过宿主机的网络协议栈,具备更强的隔离性

特点

1、每个容器拥有独立IP(可被外部设备直接访问)

2、容器之间通过物理网络通信,不走docker默认的虚拟网络

3、容器与宿主机默认不能互通

4、适合需要“真实主机网络身份”的容器

5、性能高,无需端口映射,接近物理设备通信效率

 

应用场景

1. 运行需要被局域网内设备直接访问的容器(samba、ftp、dhcp、mqtt等)

2. 需要隔离容器网络但又要能让其访问物理网络的场景

3. 容器话传统应用时希望继续使用静态IP

4. 在物理网络中直接暴露容器服务而非通过NAPT或端口映射

5. 隔离容器和物理机的访问(保证安全)

配置方法

A节点

#创建macvlan网络

docker network create -d macvlan --subnet 192.168.135.0/24 --gateway 192.168.135.2 -o parent=ens160 mac-zgs

#创建容器进行测试

docker run -itd --name mac01 --network mac-zgs --ip 192.168.135.22 busybox:latest

#进入容器

/ # ping 192.168.135.33

PING 192.168.135.33 (192.168.135.33): 56 data bytes

64 bytes from 192.168.135.33: seq=0 ttl=64 time=0.558 ms

64 bytes from 192.168.135.33: seq=1 ttl=64 time=0.463 ms

 

B节点

#创建macvlan网络

docker network create -d macvlan --subnet 192.168.135.0/24 --gateway 192.168.135.2 -o parent=ens160 mac-zgs

#创建容器进行测试

docker run -itd --name mac02 --network mac-zgs --ip 192.168.135.33 busybox:latest

#进入容器

/ # ping 192.168.135.22

PING 192.168.135.22 (192.168.135.22): 56 data bytes

64 bytes from 192.168.135.22: seq=0 ttl=64 time=0.690 ms

64 bytes from 192.168.135.22: seq=1 ttl=64 time=0.610 ms

解决容器与宿主机的网络互通

在使用macvlan模式,因为容器复用了宿主机的网卡,当容器的流量达到物理机网卡时,物理网卡的mac地址和物理机自身IP的mac地址是同一个地址,linux内核会进行阻断,因此macvlan模式,容器和物理机默认不能通信,需要配置macvlan的子接口给到物理机使用,来访问容器

配置:

ip link add mac0 link ens160 type macvlan mode bridge

屏幕截图 2026-05-24 171518.png

ip addr add 192.168.135.100/24 dev mac0

ip link set up mac0

屏幕截图 2026-05-24 171556.jpg

这个时候,容器ping 192.168.135.100可以通信

删除:

ip link delete mac0

二层隔离机制

macvlan创建虚拟接口直接绑定物理网卡

相同mac地址的通信在二层被阻止(防止网络环路)

宿主机和容器共享一个物理网卡,但linux内核会阻止相同的MAC层设备的直接通信,也就是说容器和物理机都使用同一个物理网卡通信时,被linux内核阻止

注意事项

1、同一个macvlan网络下的容器与外部设备可以互相通信(默认和宿主机不可以互相通信)

2、多个容器需确保IP地址不冲突,且不被DHCP分配

3、交换机需要支持混杂模式,macvlan,使用虚拟mac进行通信,每个容器都是用单独虚拟mac

4、Parent网卡不能是虚拟接口(docker0或br-XXX),必须是真正的物理接口

 

Ipvlan网络模式

在某些网络中,物理网络对mac地址进行了管控,如果采用不同的mac可能会触发策略,导致不能访问网络,因此ipvlan的出现,就是为了让容器复用宿主机的mac地址来进行通信

原理

Ipvlan是linux提供的一种轻量级虚拟网络接口类型,docker通过它可以为容器分配和宿主机同一网段的IP地址,与macvlan相似

Ipvlan并不会为每个接口分配独立的MAC地址,而是复用宿主机的MAC地址

 

工作模式:

L2模式(默认):与macvlan类似,通过二层广播通信

通过共享宿主机的mac地址,来进行二层通信

L3模式:只通过IP(第三层)路由通信,无需二层桥接

通过ip路由,将不同主机上的docker子网打通,实现容器间通信

特点

IP独立 每个容器有独立IP,与宿主机同网段

MAC复用 所有容器复用宿主机网卡的MAC地址,适合对MAC限制严格的网络环境

容器与主机通信 默认无法通信

性能优秀 比macvlan更少的资源开销(无虚拟MAC)

L3模式支持路由 支持跨网段容器间通信,适用于多主机部署场景

应用场景

L2:

1、限制MAC地址数量的局域网中

2、容器需要拥有局域网独立IP的场景

3、不需要复杂路由、但希望容器可被直接访问的场合(直连物理网络)

 

L3:

1、数据中心或私有云中,有大量容器不俗在多主机,需要跨主机通信,且网络中不允许暴露额外的MAC或VLAN

2、不希望主机直接访问容器,增强安全性

3、容器跨物理主机通信,通过三层路由构建overlay

4、容器用于采集、爬虫、出站服务,不需要被局域网发现

5、内网批量部署轻量级容器服务

配置方法

L2模式:

#创建L2网络

docker network create -d ipvlan --subnet 192.168.135.0/24 --gateway 192.168.135.2 -o parent=ens160 -o ipvlan_mode=l2 ipvlan-l2

#配置容器使用该网络

docker run -itd --network ipvlan-l2 --ip 192.168.135.66  --name test-l2 busybox

 

L3模式:

A节点

#创建L3网络

docker network create -d ipvlan --subnet 192.168.30.0/24 --gateway 192.168.30.2 -o parent=ens160 -o ipvlan_mode=l3 ipvlan-l3

#配置容器使用该网络

docker run -itd --name ip-l3 --network ipvlan-l3 --ip 192.168.30.88 busybox:latest

#配置容器宿主机网卡

ip link  add ipvlan-gw link ens160 type ipvlan mode l3

ip addr add 192.168.30.2/24 dev ipvlan-gw

ip link set up ipvlan-gw

没有配置网关时,容器也可以通信,是因为当容器发包时,目标是192.168.30.2,linux内核并不会像普通bridge那样查mac,而是直接将容器IP发出的IP包,从宿主机物理接口以原始IP包的形式发出去,但是宿主机将无法访问容器(默认场景中,如果不配置网关,容器可以访问物理机,物理机不可以访问容器

#配置静态路由

ip route add 192.168.40.0/24 via 192.168.135.170

 

B节点

#创建L3网络

docker network create -d ipvlan --subnet 192.168.40.0/24 --gateway 192.168.40.2 -o parent=ens160 -o ipvlan_mode=l3 ipvlan-l3

#配置容器使用该网络

docker run -itd --network ipvlan-l3 --ip 192.168.40.88 --name  ip-l3 busybox:latest

容器互相通信设置:

ip link  add ipvlan-gw link ens160 type ipvlan mode l3

ip addr add 192.168.40.2/24 dev ipvlan-gw

ip link set up ipvlan-gw

#配置静态路由

ip route add 192.168.30.0/24 via 192.168.135.160

 

配置容器可以上网

iptables -t nat -A POSTROUTING -s 192.168.30.0/24 -o ens160 -j MASQUERADE

iptables -I FORWARD -s 192.168.30.0/24 -o ens160 -j ACCEPT

iptables -I FORWARD -d 192.168.30.0/24 -i ens160 -m state --state RELATED,ESTABLISHED -j ACCEPT

 

Overlay网络模式

Docker的集群专用网络,通过vxlan将各个节点docker物理节点打通,让容器处于一个大二层的网络中,容器本身对docker所在的节点没有网络感知

仅适用于docker swarm的集群,不支持单机版的docker

Docker节点和节点之间采用vxlan的隧道进行通信,将容器的网络信息封装到以太网的数据包中,采用UDP

配置

#初始化一个docker swarm集群

docker swarm init --advertise-addr 192.168.135.160

#添加一个节点到swarm集群(初始化之后,会生成这条命令)

docker swarm join --token SWMTKN-1-2sezwl1v1rry1rm0ay2uapiurmc516dwdwp3fywa0dslni2qal-98ipnc2qwxpnh9n3hoot3b29d 192.168.135.160:2377

#查看节点

docker node ls

#创建overlay网络

docker network create -d overlay --subnet 182.18.0.0/24 --attachable overlay01

--attachable  允许单个容器可以加入overlay网络

#创建容器进行测试

#A节点

docker run -itd --network overlay01 ovy busybox:latest

#B节点

docker run -itd --network overlay01 busybox:latest

 

overlay模式会创建一个名为docker-gwbridge的网桥,然后将该网桥连同overlay的网络,同时提供给到容器,在容器内采用overlay的隧道网络,进行容器间的互相通信,在容器外,采用docker-gwbridge进行上网和端口映射

 

#配置手动上网(新版好像没用,可以不做)

iptables -A FORWARD -s 182.18.0.0/24 -j ACCEPT

iptables -A FORWARD -d 182.18.0.0/24 -j ACCEPT

iptables -t nat -A POSTROUTING -s 182.18.0.0/24 ! -d 182.18.0.0/24 -o ens160 -j MASQUERADE

#服务创建

docker service create --name web --replicas 2 --network overlay01 -p 8090:80 nginx:latest

#查看服务

docker service ls

#查看服务详情

docker service ps web

0
博主关闭了所有页面的评论