在群晖的 docker 上启动了一个 Ubuntu 容器,希望将这个 Ubuntu 容器的网关设置到旁路由上,以实现透明代理。

这个事问了下 ChatGPT,给的答案不靠谱,这里也不再赘述。经过网上查找,发现还是有人有跟我一样的需求的。这里参考了几篇文章,再将方法整理备份下。

  1. 群晖创建桥接网络-使容器和路由器一个网段 | sleele的博客
  2. unRAID 直连软路由时 Docker 容器 分离国内外网 - Chinese / 简体中文 - Unraid
  3. docker使容器和宿主机使用同一网段 | hysyeah
  4. 旁路由及docker容器独立旁路由访问-老李不着调的记事本

这个功能依赖内核的 macvlan、ipvlan 功能。

其中 macvlan 在 3.10 版本以上的内核支持,而 ipvlan 则在 4.2 版本的内核之上才支持。我的群晖版本是 7.2,其内核为 3.10,因此只能使用 macvlan。

如果内核没有加载 macvlan 模块,那么首先使用命令加载。

1
2
3
4
# 查看内核是否加载 macvlan模块
lsmod | grep macvlan
# 如果没有加载,那么加载之
modprobe macvlan

之后打开当前群晖网卡的混杂模式,对群晖来说,使用的网卡名一般是 ovs_eth0

1
2
# 打开网卡混杂模式
ip link set ovs_eth0 promisc on

如果不确定自己使用的是哪个网卡,可以使用 ifconfig 命令确认 下。

1
2
# 查看自己的IP对应的是哪个网卡
ifconfig | grep <IP> -C 10

之后使用 docker 命令创建一个自定义网络。

1
2
3
4
5
docker network create -d macvlan \
    --subnet=192.168.1.0/24 \       // 这里设置自定义网络的子网,应该设置为旁路由的子网
    --gateway=192.168.1.1 \         // 这里设置自定义网络的网关,应该设置为旁路由
    -o parent=ovs_eth0 \            // 上游网卡,通过上述的`ifconfig`命令确定
    bridge-host                     // 自定义网络的名称

之后启动容器,并使用该自定义网络,同时可以使用 --ip 参数指定容器的 IP。

1
docker create --name ubuntu --network bridge-host --ip=192.168.1.5 ubuntu

启动容器后进入容器,确定是否可以经旁路由上网。

注意事项

使用上述方式配置好容器后,容器可以和局域网下的其他设备进行通信,但是无法与容器的宿主机进行通信,基于网上的资料来看,说是安全方面的考虑。不过也是其他方法绕过的。

查了一些资料,后续有需要可以参考,目前我没有尝试。

  1. macvlan模式容器与宿主机通信
  2. 解决Docker macvlan网络与宿主机通讯问题_docker macvlan无法ping通网关-CSDN博客