请稍侯

使用 macvlan 配置网络让

22 December 2024

使用 macvlan 配置网络让docker连接宿主机

ubuntu 上配置 macvlan

Ticket:要将docker容器 nginx-ui 添加到一个名为:network_172_16 的 network 上,并指定ip地址为: 172.16.2.241,网关: 172.16.15.253, 其中宿主机ip: 172.16.2.240/20, gw:172.16.15.253, 实现让容器 nginx-ui 可以以内网的方式访问宿主机未对外开放的端口。

  • 创建基于 macvlan 的 docker network ```bash

    创建基于 macvlan 的虚拟网桥 network_100

    docker network create -d macvlan
    –subnet=192.168.100.0/24
    –gateway=192.168.100.1
    -o parent=ens18
    network_100

aliyun wodedata

docker network create -d macvlan
–subnet=172.16.0.1/20
–gateway=172.16.15.253
-o parent=eth0
network_172_16

为已存在的容器添加到网络: network_100, 并指定ip: 192.168.100.145

docker network connect –ip 192.168.100.145 network_100 nginx-ui

运行容器并指定 macvlan 网络

docker run -dit
–name networktool
–network=network_100
–ip=192.168.100.149
docker.wodedata.com/network-multitool:alpine-extra

进入容器shell

docker exec -it networktool sh

ping 测试

ping 192.168.100.100


通过上述操作已经可以很舒服的给容器分配独立的IP地址,如果发现添加了 `macvlan` network 的容器虽然可以和局域网内其他的设备或者在他们之间通信,但是却无法与宿主机通信,其实这是Macvlan的一个安全机制,按照下面方法在宿主机上再添加一个 `macvlan bridge` + `route rule` 即可绕过该限制。
```bash
# 再创建一个 macvlan_100 的网桥
ip link add macvlan_100 link eth0 type macvlan mode bridge
# 添加一个与宿主机(192.168.100.100/24)同网段的ip: 192.168.100.140/24
ip addr add 192.168.100.140/24 dev macvlan_100
# 启动网桥
ip link set macvlan_100 up     
# 添加一条到宿主机(192.168.100.100/32)的路由
ip route add 192.168.100.100 dev macvlan_100

# aliyun wodedata 案例
ip link add mll link eth0 type macvlan mode bridge
ip addr add 172.16.2.100/12 dev mll
ip link set mll up                                
ip route add 172.16.2.241 dev mll

注: 要开启ip转发后并重启 docker 以后才能实现 macvlan bridge 与宿主机通信,编辑 sudo vim /etc/sysctl.conf 设置 net.ipv4.ip_forward=1, 然后再 sudo sysctl -psudo systemctl restart docker.

设置自启动

在ubuntu上,若要将以上命令添加成开机后自动启动,可有以下两种方式:

方法 1:使用 Systemd 服务

  1. sudo vim /usr/local/bin/setup_macvlan.sh, 添加内容:
    #!/bin/bash
    ip link add mll link eth0 type macvlan mode bridge
    ip addr add 172.16.2.100/12 dev mll
    ip link set mll up                                
    ip route add 172.16.2.241 dev mll
    
  2. 运行以下命令,使脚本可执行:sudo chmod +x /usr/local/bin/setup_macvlan.sh
  3. 创建一个新的 Systemd 服务文件:sudo vim /etc/systemd/system/setup_macvlan.service, 并添加以下内容: ```ini [Unit] Description=Setup Macvlan Interface After=network.target

[Service] Type=oneshot ExecStart=/usr/local/bin/setup_macvlan.sh RemainAfterExit=yes

[Install] WantedBy=multi-user.target

4. 运行以下命令以启用服务,使其在启动时自动执行:`sudo systemctl enable setup_macvlan.service`  ;
5. 立即启动服务进行测试: `sudo systemctl start setup_macvlan.service`;

**方法 2:使用 Netplan 配置(适用于 Ubuntu 17.10 及以上版本)**  
通常,Netplan 配置文件位于 /etc/netplan/ 目录下,可以先查看当前系统现在的 netplan 配置。
1. 新增配置文件:`sudo vim /etc/netplan/02-macvlan.yaml`,也可修改(如:`sudo vim /etc/netplan/01-netcfg.yaml`), 添加以下内容:
```yaml
network:
    version: 2
    macvlans:
        mll:
            link: eth0
            mode: bridge
            addresses:
                - 172.16.2.100/24
            routes:
                - to: 172.16.2.241
                  via: 172.16.2.100

确保文件名按字母顺序排列,以便 Netplan 正确应用配置。在这种情况下,02-macvlan.yaml 的前缀 02 确保它在 01-netcfg.yaml 之后被处理。

  1. 保存并关闭文件后,使用命令:sudo netplan apply 应用新的 Netplan 配置.

最后,如果是阿里云(aliyun)服务器,防火墙配置加上内网(172.16.0.0/20 或整个B类子网172.16.0.0/12)即可.

Synology 上配置 macvlan

参考:macvlan systemd script

Three files are required. Each file states where it must be copied to. You will require sudo access for this as these areas are protected.

  1. macvlan.service
    ```sh

    Service file for creating macvlan shim, after docker has started

    copy this file to /usr/local/lib/systemd/system

    For use with systemd on DSM7.2

    Synology renamed pkgctl-Docker to pkg-ContainerManager-dockerd

[Unit] Description=Macvlan shim to allow docker to route to host

Ensure macvlan is stopped if pkg-ContainerManager-dockerd.service stops/fails

BindsTo=pkg-ContainerManager-dockerd.service

Define dependency

Requires=pkg-ContainerManager-dockerd.service

Ensure order of startup

After=pkg-ContainerManager-dockerd.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]

Informs systemd to start macvlan after this service at startup

WantedBy=pkg-ContainerManager-dockerd.service


2. `macvlan_start.sh`  
```sh
#!/bin/bash

# macvlan address range is 192.168.100.33 to 192.168.100.46
# IP address used for R100 is 192.168.100.1
# mac address is a0:b1:c2:d3:e4:f5
# copy this file to /usr/local/bin/macvlan_start.sh

ip link add macvlan_100 link ovs_eth0 type macvlan mode bridge 
ip link set macvlan_100 address a0:b1:c2:d3:e4:f5
ip addr add 192.168.100.33/32 dev macvlan_100
ip link set macvlan_100 up
# ip route add 192.168.100.0/24 dev macvlan_100  # because exsists
ip route add 192.168.100.8/32 dev macvlan_100
  1. macvlan_stop.sh
    ```sh #!/bin/bash

macvlan address range is 192.168.100.33 to 192.168.100.46

IP address used for R100 is 192.168.100.1

mac address is a0:b1:c2:d3:e4:f5

copy this file to /usr/local/bin/macvlan_stop.sh

ip route del 192.168.100.8/32 dev macvlan_100 || true

ip route del 192.168.100.0/24 dev macvlan_100 || true

ip link set macvlan_100 down || true ip addr del 192.168.100.33/32 dev macvlan_100 || true ip link del macvlan_100 || true


Having saved the 3 files to the locations as documented in the files you will need to enable the macvlan service to ensure it runs at startup.
```sh
sudo systemctl enable macvlan.service

Created symlink from /etc/systemd/system/pkg-ContainerManager-dockerd.service.wants/macvlan.service to /usr/local/lib/systemd/system/macvlan.service.

常见的特殊保留网段( 内网地址 / 保留网络 )

参考:
Docker网络之Macvlan
从 VLAN 到 IPVLAN: 聊聊虚拟网络设备及其在云原生中的应用
Configuring Macvlan and Ipvlan Linux Networking
Docker 使用 macvlan 网络容器与宿主机的通信过程