Portainer 创建 MacVLAN 网络需要两步
第一次创建 macvlan 网络只能选择 Configuration,并且直接使用会产生 docker: Error response from daemon: failed to set up container networking: cannot create endpoint on configuration-only network 错误,原因是网络被设置为 "ConfigOnly": true,
- Mac VLAN configuration success - what finally worked! : r/portainer
需要再次用Creation创建一遍才能使用。说是历史遗留问题,IPVLAN 那边就没这个问题。
Docker 主机无法访问 MACVLAN 网络上的容器,但外部却能访问
没有路由可以从主机打到容器里,说是设计预期内的问题。
- Using Docker macvlan networks :: blog.oddbit.com
- Cursed Docker networking - using MacVLAN to pretend your containers are VMs
- Macvlan network driver | Docker Docs
相同的问题也会发生在 IPVLAN 设置中,从主机无法访问容器。此时用 Bridge 因为自带路由表所以可以。
2025-11-16 已经解决了,见 给 Docker 配置完整的 IPv6 macvlan 网络环境
Docker IPVLAN 设置
我一直没法让 MACVLAN 和 Docker Host 互相访问。考虑到实际的需求
- 在本地网络可以直接访问到容器,省略端口转发(没有 NAT、没有端口冲突),不需要在主机层做防火墙
- 容器工作在独立的网段,最小化对本地网络的影响
- 可以通过 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 网络环境