Docker 使用宿主机网段多是使用 MacVlan 创建虚拟网络实现。
但本人在 RockyLinux 9.3 (ESXi 中运行的虚拟机)测试结果不尽人意。
主要问题是:容器无法访问宿主机所在局域网网关和网段内的其它 IP 地址
(PS:后续查询资料,该问题是未开启 ESXi 的网卡混杂模式。另所查资料原文说 MacVlan 模式 1 个物理网卡仅支持 2 台虚拟机,超出 2 台后掉包严重,原因不明。)

最后改用了 Docker 新的 IpVlan 驱动方式解决问题。

IpVlan 和 MacVlan 使用方法基本一致,个别参数有差别,但基本上用不到。

创建 IpVlan 网络

创建 IpVlan 网络:

1
2
3
4
5
6
7
8
9
10
docker network create \
-d ipvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--ipv6 \
--subnet=fd00:db8:1:ddee::/64 \
--gateway=fd00:db8:1:ddee::1 \
-o ipvlan_mode=l2 \
-o parent=ens192 \
ipv6ipvlan

参数说明:

  • -d:创建网络的驱动方式为 ipvlan。
  • –subnet=192.168.8.0/24:ipv4 的网段为 192.168.1.0/24(宿主机所在网段)。
  • –gateway=192.168.1.1:ipv4 的网关为 192.168.1.1(宿主机网关)。
  • –ipv6:启用 ipv6。
  • –subnet=fd00:db8:1:ddee::/64:ipv6 的网段为 fd00:db8:1:ddee::/64。
  • –gateway=fd00:db8:1:ddee::1:ipv6 的网关为 gateway=fd00:db8:1:ddee::1
  • -o ipvlan_mode=l2:ipvlan 工作模式为 l2(默认就是 l2,可省略该参数)。
  • -o parent=ens192:指定要使用的父接口(网卡名称)。
  • ipv6ipvlan:要创建的 Docker 网络名称。

测试 IpVlan 网络

ipvlan 使用了宿主机子网网段,建议在容器中指定 ip 地址。

使用 centos 镜像测试:

1
2
3
4
5
6
7
8
9
10
11
12
# 创建 CentOS 镜像
docker run --net=ipv6ipvlan --ip=192.168.1.10 --dns=192.168.1.1 --name=centos -itd centos /bin/bash
# 进入容器
docker exec -it centos /bin/bash
# ping 网关测试
ping 192.168.1.1
# ping 其它子网测试
ping 192.168.1.X
# ping 外网测试
ping www.baidu.com
# 退出容器
exit

正常情况下,容器已经能 ping 通各个地址。
此时,在其它网络设备也能 ping 通测试容器的 ip 地址 192.168.1.10

注意:宿主机和容器之间不能 ping 通。

打通宿主机和容器之间的互访

创建虚拟接口桥接到物理网卡打通宿主机和容器之间互访。

1
2
3
4
5
6
7
8
# 添加一个虚拟接口桥接到物理网卡
ip link add ipvlan-proxy link ens192 type ipvlan
# 给虚拟接口配置ip
ip addr add 192.168.1.11/32 dev ipvlan-proxy
# 启用虚拟接口
ip link set ipvlan-proxy up
# 添加需要访问的容器网络的静态路由规则
ip route add 192.168.1.10/32 dev ipvlan-proxy

参数说明:

  • ipvlan-proxy:虚拟接口名称。
  • ens192:物理网卡名称。
  • 192.168.1.11/32:给虚拟接口分配的 ip 地址。
  • 192.168.1.10/32:需互访的容器 ip 地址。