Docker macvlan 容器与宿主机互通

Docker macvlan 容器与宿主机互通
TM大队长Docker 容器使用 macvlan 后,可以像局域网里的独立设备一样拥有 IP。但宿主机默认无法通过自己的物理网卡直接访问这些容器。这是 Linux macvlan 的限制。解决方法是在宿主机上再创建一张 macvlan 虚拟网卡,让宿主机通过它访问容器。
本文的网络配置
| 用途 | 地址或名称 |
|---|---|
| 宿主机物理网卡 | eno1 |
| 宿主机虚拟网卡 | macvlan-host |
| 虚拟网卡 IP | 192.168.5.223 |
Docker 网络的 Subnet |
192.168.5.0/24 |
分配给容器的 IPRange |
192.168.5.192/28 |
| qBittorrent 容器 IP | 192.168.5.199 |
先检查自己的 Docker 网络,不能只看容器 IP。
1 | docker network inspect <macvlan网络名> |
本文的做法要求 Options.parent 是 eno1,Docker 网络的 Subnet 是 192.168.5.0/24,而 192.168.5.192/28 是专门分配给容器的地址段。Docker 网络的网关也应与实际局域网配置一致。
192.168.5.223 在 /24 内,但不在 192.168.5.192/28 内。它必须是未被 NAS、其他设备或 DHCP 占用的独立 IP。如果 Docker 网络的 Subnet 本身就是 192.168.5.192/28,不要照搬 .223;应从 .193~.206 中选择一个空闲地址作为宿主机虚拟网卡的 IP,并在 Docker 网络中用 --aux-address 保留,避免分配给容器。
还要确认 .192/28 整段只用于这些 macvlan 容器。添加路由后,宿主机发往这个范围内的流量都会走 macvlan-host;如果里面有普通局域网设备,宿主机访问它们可能受到影响。
临时配置
以具有管理员权限的 shell 执行:
1 | ip link add macvlan-host link eno1 type macvlan mode bridge |
/32 只给虚拟网卡指定一个本机地址;单独添加的路由负责将容器地址段导向这张网卡。src 则明确指定宿主机访问容器时使用 .223 作为源地址。
检查路由选取:
1 | ip route get 192.168.5.199 |
输出中应包含 dev macvlan-host src 192.168.5.223。然后测试连通性:
1 | ping 192.168.5.199 |
如果路由正确但 ping 不通,还需要检查容器是否运行、防火墙规则,以及容器是否响应 ICMP。也可以直接测试容器实际提供的服务端口。
用 systemd 持久化
临时配置在宿主机重启后会消失。创建以下服务,使系统启动时自动恢复接口和路由:
1 | cat >/etc/systemd/system/macvlan-host.service <<'EOF' |
如果已经执行过临时配置,服务会复用现有的虚拟网卡。检查服务和路由:
1 | systemctl status macvlan-host.service |
以后容器只要使用 192.168.5.192/28 内的 IP,宿主机就不需要再为每个容器添加单独的路由。这里的 /28 覆盖 .192~.207,通常可分配的主机地址为 .193~.206;请结合 Docker 网络的实际配置保留宿主机所用地址。



