Portainer 创建 MacVLAN 网络需要两步

第一次创建 macvlan 网络只能选择 Configuration,并且直接使用会产生 docker: Error response from daemon: failed to set up container networking: cannot create endpoint on configuration-only network 错误,原因是网络被设置为 "ConfigOnly": true,

Docker 主机无法访问 MACVLAN 网络上的容器,但外部却能访问

没有路由可以从主机打到容器里,说是设计预期内的问题。

相同的问题也会发生在 IPVLAN 设置中,从主机无法访问容器。此时用 Bridge 因为自带路由表所以可以。

2025-11-16 已经解决了,见 给 Docker 配置完整的 IPv6 macvlan 网络环境

Docker IPVLAN 设置

我一直没法让 MACVLAN 和 Docker Host 互相访问。考虑到实际的需求

  1. 在本地网络可以直接访问到容器,省略端口转发(没有 NAT、没有端口冲突),不需要在主机层做防火墙
  2. 容器工作在独立的网段,最小化对本地网络的影响
  3. 可以通过 DNS 和 IPv6 访问到容器

小范围使用的话,bridge 模式可能更简单,但放到多容器部署,以及 IPv6 环境,可以看看 ipvlan。

  • host 模式适合像与 Docker Daemon 平级的应用程序一样,以主机所在的身份访问本地网络
  • macvlan 模式适合需要以新主机的身份直接连到主机所在本地网络的情况,类比于虚拟机
  • ipvlan 不会在主机上新建 bridge 网卡,且性能更高
  • ipvlan 自动接上 ipv6 passthrough 获取地址
  • bridge 也能实现 ipvlan l3 那样的路由功能,多了一份 iptables 防火墙
  • bridge 模式下每个容器都会在主机上创建一张虚拟网卡

相比 MACVLAN 只能工作在 L2 层,限制在同一个子网内。IPVLAN (L3) 让 Docker Host 成为路由器,有更广大的 IP 地址空间,不再和当前网络的 DHCP 打架。
当然 MACVLAN 在同一个子网广播域内也有好处,比如部署 HomeBridge 时可以不需要跨网段转发 mDNS 包。

但是需要配置路由器添加静态路由。

# on docker host which eth0 has ip 192.168.9.201/24
docker network create -d ipvlan \
  -o parent=eth0 -o ipvlan_mode=l3 \
  --subnet=192.168.5.0/24 \
  --subnet=192.168.4.0/24 mynet 
# spin up some container in the network
docker run -itd --rm --network mynet --ip 192.168.4.10 --name b1 busybox
docker run -itd --rm --network mynet --ip 192.168.5.10 --name b2 busybox
# on router which has ip 192.168.9.1
ip route add 192.168.4.0/24 via 192.168.9.201
ip route add 192.168.5.0/24 via 192.168.9.201
# now container <=> docker host <=> router <=> internet works

好在 IPv6 下可以吃到 SLAAC 自动配置,不需要关注 ISP 动态变化的前缀。

2025-11-16 总结经验,还是 MACVLAN 适合我,见 给 Docker 配置完整的 IPv6 macvlan 网络环境