Docker 使用 macvlan 部署 OpenWrt 旁路由

配置 macvlan 容器网络与 OpenWrt 旁路由,并说明地址规划和宿主机通信。

本文在 Linux 宿主机上使用 macvlan 运行 OpenWrt 旁路由,地址规划如下。执行前按实际网络替换地址和物理网卡名 eth0。

设备IPv4 地址网关与 DNS
上游路由器10.0.0.254按现有上游网络配置
OpenWrt 旁路由10.0.0.110.0.0.254
宿主机 macvlan 接口10.0.0.1110.0.0.1

Docker 网络的网关填写上游路由器地址 10.0.0.254,OpenWrt 容器使用 10.0.0.1,两者占用不同地址。

IPv6 部分使用静态地址:容器为 fd00:10::1/64,上游网关示例为 fd00:10::fe。这组 ULA 地址用于本地网络,上游路由器也需要配置对应网关地址;复制示例不会获得公网 IPv6。使用公网 IPv6 时,Docker 子网、容器地址与 OpenWrt 内部地址、网关均需改成实际网络提供的对应值。

配置系统环境

打开网卡混杂模式

1
ip link set eth0 promisc on

加载 PPPOE 内核模块

1
modprobe pppoe

创建接口

1
2
3
4
5
docker network create -d macvlan \
    --subnet=10.0.0.0/24 --gateway=10.0.0.254 \
    --ipv6 --subnet=fd00:10::/64 --gateway=fd00:10::fe \
    -o parent=eth0 \
    macvlan

创建容器

下载OpenWrt镜像

1
docker pull dawn2000/openwrt:latest

创建并启动容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
docker run -d \
    --restart unless-stopped \
    --net macvlan \
    --ip 10.0.0.1 \
    --ip6 fd00:10::1 \
    --cap-add NET_ADMIN \
    --hostname OpenWrt \
    --name openwrt \
    dawn2000/openwrt:latest \
    sh -c "echo -e 'search lan\nnameserver 127.0.0.1\nnameserver ::1' > /etc/resolv.conf && /sbin/init"

配置 OpenWrt

进入容器终端

1
docker exec -it openwrt /bin/sh

使用vi编辑 /etc/config/network

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
config interface 'lan'
        option type 'bridge'
        option ifname 'eth0'
        option proto 'static'
        option ipaddr '10.0.0.1' #旁路由地址
        option netmask '255.255.255.0'
        option gateway '10.0.0.254' #上游路由地址
        option dns '10.0.0.254'
        option ip6addr 'fd00:10::1/64'
        option ip6gw 'fd00:10::fe'

Docker 的 --ip、--ip6 分别与这里的 ipaddr、ip6addr 保持一致。ip6addr 设置容器的静态 IPv6 地址,ip6gw 设置上游网关;这里不配置自动前缀分配。

重启 openwrt 网络

1
/etc/init.d/network restart

宿主机通信:ifupdown 配置示例

由于 docker 网络采用 macvlan 的 bridge 模式,即使宿主机与容器在同一网段,相互之间也是无法通信的。 为了解决这个问题,需利用多个 macvlan 接口之间是互通的原理,在 LAN 口新建一个 macvlan 虚拟接口。

以下持久化配置仅适用于使用 ifupdown 与 /etc/network/interfaces 的宿主机,常见于部分 Debian 环境。macvlan 的原理不依赖 Debian;使用 Netplan、NetworkManager 或 systemd-networkd 时,需要在实际网络管理工具中创建对应接口,不要直接套用这个文件。

编辑 /etc/network/interfaces,按实际地址规划添加配置。示例 IP 只分配给 macvlan,不能同时重复分配给物理接口:

1
2
3
4
5
6
7
8
auto macvlan
iface macvlan inet static
  address 10.0.0.11 #此处为宿主机ip
  netmask 255.255.255.0
  gateway 10.0.0.1
  dns-nameservers 10.0.0.1
  pre-up ip link add macvlan link eth0 type macvlan mode bridge
  post-down ip link del macvlan link eth0 type macvlan mode bridge

参考:Docker macvlan 的 IPv6 配置、OpenWrt IPv6 配置。

延伸阅读

使用 Hugo 构建
主题 Stack 由 Jimmy 设计