使用 macvlan 配置网络让
使用 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 -p 与 sudo systemctl restart docker.
设置自启动
在ubuntu上,若要将以上命令添加成开机后自动启动,可有以下两种方式:
方法 1:使用 Systemd 服务
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- 运行以下命令,使脚本可执行:
sudo chmod +x /usr/local/bin/setup_macvlan.sh; - 创建一个新的 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 之后被处理。
- 保存并关闭文件后,使用命令:
sudo netplan apply应用新的 Netplan 配置.
最后,如果是阿里云(aliyun)服务器,防火墙配置加上内网(172.16.0.0/20 或整个B类子网172.16.0.0/12)即可. 
Synology 上配置 macvlan
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.
macvlan.service
```shService 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
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 网络容器与宿主机的通信过程
