CentOS 7.9 上给裸金属服务建了 macvlan 网络,容器之间互通,容器 ping 宿主机网关也不通,宿主机 ping 容器同样超时,业务健康检查全挂。

一开始怀疑是「子网和网关参数给错了,容器拿到的默认路由指向不存在的地址」,查了一圈,方向不对。

原因不止一个,得分开看。macvlan 的父接口不能同时作为宿主机访问该网段的出口,回包被内核丢弃。还有一种是交换机的端口安全只允许一个 MAC,容器的新 MAC 被直接阻断。

少数情况下是混杂模式没开,父网卡收不到发往容器 MAC 的帧。

上来先确认容器拿到了地址和网关

docker network inspect macnet -f '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{end}}'

然后在宿主机上建一个 macvlan 子接口做回程

ip link add mac0 link eth0 type macvlan mode bridge && ip addr add 192.168.1.250/24 dev mac0 && ip link set mac0 up

接着确认网卡是否处于混杂模式

ip link show eth0 | grep -o PROMISC

从宿主机经子接口访问容器

ping -c 2 -I mac0 192.168.1.51

改完先别撤,确认这几项。宿主机经 mac0 能 ping 通容器,容器也能访问宿主机,健康检查恢复,容器 IP 与交换机侧的 MAC 表对得上。

macvlan 天生宿主机与容器不通,这是设计取舍不是故障;交换机端口安全和不支持混杂模式的环境,直接换 ipvlan 或 bridge 更省事。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189