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 更省事。这类问题最好一次改到位,反复小改反而容易把原因搅混。
