DSM7中Docker MacVLAN的使用

一、 介绍:

MACVLAN是一种网络虚拟化技术,它允许用户将多个虚拟的MAC地址映射到不同的容器或虚拟机上,从而使它们能够在同一物理网络上运行,同时保持相互隔离。具体来说,MACVLAN允许用户创建一组虚拟的接口(类似于真实网络接口),每个接口都拥有独立的MAC地址,并且能够与物理网络中的其他设备进行通信。

通过使用MACVLAN,用户可以实现容器或虚拟机之间的独立网络通信,同时利用主机物理网络的优势,比如更高的带宽和更低的延迟。此外,MACVLAN还可以帮助用户更好地管理网络资源,提高网络性能和安全性。

简单来说就是使用macvlan网络模式的docker容器,可以看作是局域网内的一个独立设备,它会有一个独立的内网IP。每个macvlan下的docker容器,都有自己一套完整的端口可用,不会互相冲突。

二、DSM配置

控制面板-网络-网络界面-管理-Open vSwitch 设置

image-20240415174943584

打开Open vSwitch

image-20240415175008953

Open vSwitch就是虚拟交换机。可以简单这样理解,docker容器接入这台交换机,就可以连上你的路由器,相当于一台手机or平板or盒子接入你家网络。

确认打开Open vSwitch开关以后,我们进入SSH控制台。

输入

image-20240415175124404

图中列出了NAS的所有网卡,其中有一个ovs_eth0的网口,对应NAS物理网口信息。这个网口就是开启了Open vSwitch以后的联网网口。如果你的联网网口是其他口(eth*),这里的ovs_eth*也可能不一样,自行注意。等会创建macvlan网络需要使用这个端口,一定记好,不要搞错。

下一步输入

1
docker network ls

查看docker的网络详情

image-20240415175236036

目前默认只有三种网络模式

bridge、host、none三种网络模式是什么原理作用,大家自行百度即可。

如果已经有driver为macvlan的docker网络,可以执行 docker network rm name 来进行删除,name为macvlan网络实际名称,即图上的NAME栏参数。

确认docker网络中没有macvlan网络,我们再进行下一步。

创建自定义macvlan网络。

创建命令很简单,和创建docker容器类似。

我这里内网网段是 11.0.0.0/24 ,主路由网关 11.0.0.1 ,旁路由网关 11.0.0.2 。

我的目的是让qB和TR不经过旁路由网关,直接走主路由网关,所以要把macvlan的网关设置成 11.0.0.1 。

创建macvlan网络命令如下

仅ipv4

1
docker network create -d macvlan --subnet=11.0.0.0/24 --gateway=11.0.0.1 -o parent=ovs_eth0 name

ipv4&ipv6双栈

1
docker network create -d macvlan --subnet=11.0.0.0/24 --gateway=10.0.0.1 --ipv6 --subnet=2008::/60 --gateway=2008::1  -o parent=ovs_eth0 name

简单解释一下

docker network create -d macvlan #指定创建的网络类型是macvlan

–subnet=11.0.0.0/24 #macvlan的ipv4网段,这里写你的内网网段即可。

–gateway=11.0.0.1 #macvlan的ipv4网关,这里写您需要容器走的网关。

–ipv6 #启用ipv6支持

–subnet=2408::/60 #macvlan的ipv6前缀

–gateway=2408::1 #macvlan的ipv6网关

-o parent=ovs_eth0 #桥接网络走的是ovs_eth0接口,如果你的接口不是这个,请自行更改。

name #macvlan网络的名称

参数怎么填大家按照自己实际需求情况来

image-20240415175421688

我这里仅供参考

上图的创建命令

1
docker network create -d macvlan --subnet=11.0.0.0/24 --gateway=11.0.0.1 --ipv6 --subnet=2408:825c:900:xxxx::/60 --gateway=2408:825c:900:xxxx::1  -o parent=ovs_eth0 GGGGG

创建了一个名为GGGGG(名字随意,你喜欢就可以)的ipv4&ipv6双栈macvlan网络。

创建完成以后可以再次输入 docker network ls 检查是否创建成功(如上图)。

也可以打开docker的webui,检查网络信息。

image-20240415175451364

macvlan网络创建成功以后,我们就可以使用它来创建具体容器了。

比如我这里要创建三个使用macvlan的qB

命令如下

1
2
3
4
5
docker run -d --name=qB-down1 --net=GGGGG --ip=11.0.0.151 -v /volume1/docker/qB/config1:/config --privileged=true --restart=always linuxserver/qbittorrent:latest

docker run -d --name=qB-down2 --net=GGGGG --ip=11.0.0.152 -v /volume1/docker/qB/config2:/config --privileged=true --restart=always linuxserver/qbittorrent:latest

docker run -d --name=qB-down3 --net=GGGGG --ip=11.0.0.153 -v /volume1/docker/qB/config3:/config --privileged=true --restart=always linuxserver/qbittorrent:latest

重点提一下

–net=GGGGG #为容器使用名为GGGGG的docker网络模式

–ip=11.0.0.xxx #指定容器IP

其余部分跟普通创建容器一致。

创建其他容器只要 –net 配置为macvlan网络名称即可,大家自行举一反三。

创建成功以后可以看到macvlan网络模式下有三个容器。

image-20240415175521503

我们进入容器内检查网络情况。

我这里选择进入qB-down1

1
docker exec -it qB-down1 /bin/bash

进入容器后输入 ifconfig 查看网络情况,输入 ip route show 查看网关。

image-20240415175553960

可以发现容器网关已经是我需要的主路由网关 11.0.0.1 ,并且获取到了ipv6。

下面测试一下网络是否正常

先为qB固定传输端口为22222并配置好端口转发

image-20240415175616684

image-20240415175628805

尝试下载一个种子。

image-20240415175654017

ipv6 ipv4都可以正常链接

直接看站点信息

image-20240415175714031

ipv6、ipv4均正常

三、与宿主机互通

一般在macvlan模式下同网段的其他机器可以和容器互通,但宿主不能和容器互通,这是在macvlan模式设计的时候为了安全而禁止了宿主机和容器直接通信。”援引Rehtt大佬的话。

打个比方就是你用host模式创建的iyuu,默认情况下是访问不了ping不通macvlan模式下的qB客户端的,反之也一样

image-20240415175807162

尝试宿主机直接ping容器qB-down1的IP ,无法ping通。

不过我们还有曲线救国的办法

具体直接看Rehtt大佬的教程,里面有详细原理方法介绍。https://rehtt.com/index.php/archives/236/

如果想要实现互通,有个曲线救国的方法,就是macvlan与macvlan之间可以互通,只需要在宿主机再创建一个macvlan网络,然后修改路由,让数据经过这个macvlan达到互通的目的。”同样援引Rehtt大佬的话。

命令也很简单

以我前面的配置环境举例就是以下几条命令即可

1
2
3
4
5
6
ip link add TTTTT link ovs_eth0 type macvlan mode bridge
ip addr add 11.0.0.160 dev TTTTT
ip link set TTTTT up
ip route add 11.0.0.151 dev TTTTT
ip route add 11.0.0.152 dev TTTTT
ip route add 11.0.0.153 dev TTTTT

以下为简单解释

ip link add TTTTT link ovs_eth0 type macvlan mode bridge #创建一个名为TTTTT的macvlan接口,名字随意你可以设置为你喜欢的名字。ovs_eth0和之前一样,需要写为开启了Open vSwitch以后的联网网口。

ip addr add 11.0.0.160 dev TTTTT #设置TTTTT接口的IP为11.0.0.160,需要和你之前设置的第一个macvlan(GGGGG)同网段。

ip link set TTTTT up #启动TTTTT接口。

ip route add 11.0.0.151 dev TTTTT #让IP11.0.0.151(qB-down1)到宿主机的路由经过TTTTT接口。

ip route add 11.0.0.152 dev TTTTT #让IP11.0.0.152(qB-down2)到宿主机的路由经过TTTTT接口。

ip route add 11.0.0.153 dev TTTTT #让IP11.0.0.153(qB-down3)到宿主机的路由经过TTTTT接口。

image-20240415175949063

创建完成后输入 ip addr 可以发现新建的TTTTT接口已经生效。

尝试在宿主机ping容器IP

image-20240415180007613

均可ping通,说明配置已经生效。

到这里就完成了整套macvlan配置,可以正常使用没有问题了

四、 开机启动

那就是上面macvlan网络模式下容器与宿主机互通的相关配置,默认情况下重启后会重置。

每次重启后就要重新执行一遍

1
2
3
4
5
6
ip link add TTTTT link ovs_eth0 type macvlan mode bridge
ip addr add 11.0.0.160 dev TTTTT
ip link set TTTTT up
ip route add 11.0.0.151 dev TTTTT
ip route add 11.0.0.152 dev TTTTT
ip route add 11.0.0.153 dev TTTTT

手动输入,作为一个懒人,这能忍?

所以最后就是配置开机启动自动配置。

因为群晖7.0变动比较大,不能简单地用系统自带的开机执行脚本方法实现。

我们需要把命令配置为systemd服务,通过systemd来实现开机启动自动配置。

我们先创建一个新的systemd服务,取名 macvlan.service

进入SSH执行

1
vi /usr/local/lib/systemd/system/macvlan.service

按i键,进入编辑模式,输入以下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=Macvlan shim to allow docker to route to host
# After=pkgctl-Docker.service
# BindsTo=pkgctl-Docker.service
ReloadPropagatedFrom=pkgctl-Docker.service
PartOf=pkgctl-Docker.service

[Service]
Type=oneshot
ExecStart=/bin/bash /usr/local/bin/macvlan_start.sh
ExecStop=/bin/bash /usr/local/bin/macvlan_stop.sh
RemainAfterExit=yes
Restart=no

[Install]
WantedBy=pkgctl-Docker.service

然后按 esc 键入 :wq 保存修改

然后我们要配置两个bash脚本。

也就是要对应macvlan.service服务配置内容中,start服务和stop服务两个脚本的路径。

image-20240415180209536

先配置start服务执行脚本

执行

1
vi /usr/local/bin/macvlan_start.sh

同样按i进入编辑模式,输入需要开机执行的命令,也就是我们的macvlan与宿主机互通需要的命令。

1
2
3
4
5
6
ip link add TTTTT link ovs_eth0 type macvlan mode bridge
ip addr add 11.0.0.160 dev TTTTT
ip link set TTTTT up
ip route add 11.0.0.151 dev TTTTT
ip route add 11.0.0.152 dev TTTTT
ip route add 11.0.0.153 dev TTTTT

image-20240415180247287

确定无误后,按 Esc 键入 :wq 保存脚本。

接下来配置stop脚本

1
vi /usr/local/bin/macvlan_stop.sh

输入对应的停止服务命令,如下。

1
2
3
4
5
6
ip route del 10.0.0.151 dev TTTTT || true
ip route del 10.0.0.152 dev TTTTT || true
ip route del 10.0.0.153 dev TTTTT || true
ip link set TTTTT down || true
ip addr del 11.0.0.160 dev TTTTT || true
ip link del TTTTT || true

同样操作,保存脚本。

image-20240415180342650

这样就配置好了启动和停止脚本。

以后只要macvlan.service在运行中,就会检测docker服务运行状态。当docker服务启动完成后,macvlan.service服务会执行start脚本。当docker服务关闭后,macvlan.service服务会执行stop脚本。

然后我们重新加载一下systemd服务

执行

1
2
systemctl daemon-reload
systemctl enable macvlan

这样macvlan.service服务已经在systemd服务列表中了。

如果想取消

1
systemctl disable macvlan

其他的命令介绍

1
2
3
systemctl start macvlan # 启动
systemctl stop macvlan # 停止
systemctl status macvlan # 查看状态

不迷路,转载NAS相关 篇十二:群晖DSM7下,docker中macvlan网络模式配置简单教程 实现macvlan与host网络互通,及互通服务自启动_NAS存储_什么值得买 (smzdm.com)