配置ipv6

 cat /etc/docker/daemon.json 
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00:dead:beef::/48"
}

让容器内应用也能访问ipv6

  ipv6nat:
    container_name: "ipv6nat"
    image: "robbertkl/ipv6nat"
    network_mode: "host"
    privileged: true
    restart: "unless-stopped"
    volumes:
      - "/lib/modules:/lib/modules:ro"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

创建macvlan

根据自己网络配置修改

docker network create -d macvlan --subnet=192.168.10.0/24 --gateway=192.168.10.1 --ipv6 --subnet=fe80::2e2:69ff:fe5e:aed9/64 --gateway=fe80::3abc:1ff:fe5c:3e22 -o parent=vmbr0 mvl

docker network create -d macvlan \
--subnet=192.168.10.0/24 \
--gateway=192.168.10.1 \
--ipv6 \
--subnet=fd0d:7eb5:2afd::/64 \
--gateway=fd0d:7eb5:2afd::1 \
-o parent=vmbr0 \
mvl

解决容器和宿主机通信问题

在 macvlan 模式下,出于安全考虑,默认禁止宿主机与容器的通信,也就是宿主机无法访问以及反代容器。但是局域网中的其他设备可以访问到容器。此时的网络拓扑如下图所示,可以将接入 macvlan 的容器看作一个直接接入局域网的设备(蓝色线),只是无法与宿主机(以及宿主机中使用 brigde 模式的设备)直接通信(红色线)。

配置过程

  1. 使用 root 用户执行以下命令,创建一个名为 macvlan-host 的网卡,连接到 ovs_eth0 物理网卡上(需要根据实际情况修改网卡名字)
 ip link add macvlan-host link ovs_eth0 type macvlan mode bridge
  1. 设置该虚拟接口的 IP,需要在 macvlan 网段内
    ip addr add 192.168.1.254 dev macvlan-host
  1. 启动接口
    ip link set macvlan-host up
  1. 修改路由,其中 192.168.1.201192.168.1.202 是容器 ip,如果有多个容器,需要分别设置
    ip route add 192.168.1.201 dev macvlan-host
    ip route add 192.168.1.202 dev macvlan-host

至此,即可实现宿主机到容器的访问。

修改完成后的网络拓扑类似下图。通过手动配置静态路由,将 192.168.1.201192.168.1.202 的路由指向新建的 macvlan-host 虚拟接口,由于该接口视作一个局域网设备可以访问到容器,因此从主机 -> 容器变得可达。(粉色线)

反过来,若是 macvlan 下的容器需要访问主机,直接访问主机 IP 也是不通的(红色线),但此时访问主机可以直接使用虚拟接口的 IP 来替代(绿色线),即在 macvlan 容器下使用 192.168.1.254:port 即可正常访问到主机服务。

持久化配置

由于该网卡和路由设置在宿主机重启后会丢失,因此需要创建开机启动脚本,以实现自动配置。

使用 Systemd

Debian 等 Linux 可以用 Systemd 管理 macvlan,该方法可以实现与 docker 服务关联,docker 启动时自动设置 macvlan,启动失败或者退出时还原修改。

群晖也可以(推荐)使用该方法,但与 Linux 有一点不同,且看后文。

具体步骤如下:

  1. 以下脚本放到一个文件夹,例如 /usr/local/bin/setup_docker_macvlan.sh,注意修改其中的变量。并赋予可执行权限:sudo chmod +x /usr/local/bin/setup_docker_macvlan.sh
  2. sudo vim /etc/systemd/system/setup_docker_macvlan.service 创建 Systemd 服务单元文件,内容如下:
    [Unit]
    Description=Setup macvlan shim for docker to allow to route to host
    BindsTo=docker.service
    Requires=docker.service
    After=docker.service

    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/setup_docker_macvlan.sh start
    ExecStop=/usr/local/bin/setup_docker_macvlan.sh stop
    RemainAfterExit=yes
    Restart=no

    [Install]
    WantedBy=multi-user.target
如果是群晖用户,由于群晖的 docker systemed 不是 `docker.service`,因此需要修改 `BindsTo`、`Requires` 和 `After`,根据 DSM 版本不同,服务名称可能也不同,可以通过以下方式查看:
    systemctl list-units --type=service | grep docker
目前已知可能的名称有:

-   `pkgctl-Docker.service`
-   `pkg-ContainerManager-dockerd.service`
-   `pkg-Docker-dockerd.service`

**当然也可以使用 `network.target`,当网络服务设置完成后启动,不强制依赖 docker,是一种更宽松的设置方式。**
  1. 启用服务单元
    sudo systemctl daemon-reload
    sudo systemctl enable setup_docker_macvlan.service
群晖 DSM

更简单的配置方式:群晖 DSM7 下可以在 /usr/local/etc/rc.d 中写入启动脚本,例如 vim /usr/local/etc/rc.d/macvlan.sh,然后通过 chmod +x /usr/local/etc/rc.d/macvlan.sh 赋予可执行权限;也可以通过控制面板 - 任务计划来设置开机脚本。

脚本内容参考:

#!/bin/sh
ip link add macvlan-host link ovs_eth0 type macvlan mode bridge
ip addr add 192.168.1.254 dev macvlan-host
ip link set macvlan-host up
ip route add 192.168.1.201 dev macvlan-host
ip route add 192.168.1.202 dev macvlan-host

删除配置

sudo rm -rf /var/lib/docker/network

Last modification:April 7th, 2024 at 01:59 pm
如果觉得我的文章对你有用,请随意赞赏