【问题标题】:Binding containers to a specific host VLAN将容器绑定到特定主机 VLAN
【发布时间】:2022-03-28 23:30:32
【问题描述】:

我有一台主机连接到多个 VLAN,这些 VLAN 在我的路由器上具有特定的路由规则,它们具有不同的属性。

我看到了其他关于在 VM 中为每个 VLAN 运行 docker 的建议,但这看起来也很丑陋和混乱。

例如

/etc/network/interfaces:

# Is routed out a VPN on my router
auto bond0.3
iface bond0.3 inet dhcp
iface bond0.3 inet6 auto

# Is null routed at my router (LAN only)
auto bond0.4
iface bond0.4 inet dhcp
  dns-nameserver 192.168.3.1
iface bond0.4 inet6 auto

# Routed directly to my ISP for containers only
auto bond0.7
iface bond0.7 inet dhcp
iface bond0.7 inet6 auto

我在名为“external_7”的 docker 接口上使用了 macvlan 接口:

networks:
  external_v7:
    name: external_v7
    driver: macvlan
    driver_opts:
      parent: bond0.7
    enable_ipv6: false
    ipam:
      config:
      - subnet: 192.168.7.0/24
        gateway: 192.168.7.1
        ip_range: 192.168.7.128/26

接下来,我在 VPN 后面有一个 Bittorrent 客户端,拥有单独的 VPN 隧道容器而不在我的路由器上使用它的主要原因是,在下载某些内容时它会阻塞隧道,我不能将它用于任何事情否则,我有一个专用的 Bittorrent VPN 隧道:

services:
  vpn_bittorrent:
    extends:
      file: ../docker-vpn/docker-compose-vpn.yml
      service: openvpn-client
    container_name: vpn_bittorrent
    networks:
      external_v7:
        ipv4_address: 192.168.7.128
    volumes:
      - /mnt/data/container_data/vpn:/data/vpn
    ports:
      - 192.168.7.128:26129:26129
      - 192.168.7.128:26129:26129/udp

扩展来自:

services:
  openvpn-client:
    image: ghcr.io/wfg/openvpn-client
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    restart: unless-stopped

我终于有 qbittorrent 运行了:

  qbittorrent:
    image: ghcr.io/linuxserver/qbittorrent
    container_name: qbittorrent
    network_mode: service:vpn_bittorrent
    environment:
      - PUID=1004
      - PGID=1003
      - WEBUI_PORT=8080
    volumes:
      - /mnt/data/container_data/qbittorrent:/config
      - /mnt/data/shared/incoming:/mnt/shared/incoming
    restart: unless-stopped

现在我当然喜欢在这前面有一个反向代理,因为我喜欢使用标准端口,比如 :443 或其他。

  web:
    image: nginx:stable-alpine
    container_name: web
    hostname: web.internal
    networks:
      external_v4:
        ipv4_address: 192.168.4.133
    volumes:
      - /mnt/data/container_data/web/nginx/auth-basic.conf:/etc/nginx/auth-basic.conf:ro
      - /mnt/data/container_data/web/nginx/htpasswd:/etc/nginx/htpasswd:ro
      - /mnt/data/container_data/web/nginx/http.d:/etc/nginx/http.d:ro
      - /mnt/data/container_data/web/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - /mnt/data/container_data/web/nginx/proxy-control.conf:/etc/nginx/proxy-control.conf:ro
      - /mnt/data/container_data/web/nginx/ssl.conf:/etc/nginx/ssl.conf:ro
      - /mnt/data/container_data/web/nginx/ssl:/etc/nginx/ssl:ro
      - /mnt/data/container_data/web/nginx/html:/etc/nginx/html:ro
    command: [nginx-debug, '-g', 'daemon off;']
    ports:
      - 8080:8080
      - 9090:9090
      - 8989:8989
      - 7878:7878
    restart: unless-stopped

每个服务都必须需要一个配置:

server {
    listen 443;
    listen [::]:443;
    include /etc/nginx/ssl/qbittorrent.web.internal/qbittorrent.web.internal.conf;

    server_name qbittorrent.web.internal;


    location / {
        proxy_pass http://192.168.7.128:8080/;
        include    /etc/nginx/proxy-control.conf;
        include    /etc/nginx/auth-basic.conf;
    }
}

现在有几个问题:

  1. 如果由于某种原因 VPN 容器 vpn_bittorrent 重新启动 nginx 代理 web 将无法再看到 bittorrent 容器,直到它也重新启动,结果是“502 Bad Gateway”错误。我怀疑这与qbittorrentvpn_bittorrent 之间的连接有关,即network_mode: service:vpn_bittorrent

  2. 我想用更灵活的东西替换我的反向代理,比如https://traefik.io/,我不想手动配置 nginx 配置来匹配某个 IP 地址,例如 192.168.7.128

  3. 我认为远离 macvlan 地址可能是一件好事,所以我在我的主机上创建了一个网桥

auto br7
iface br7 inet static
  address 192.168.7.252
  netmask 255.255.255.0
  gateway 192.168.7.1
  bridge_ports bond0.7
  bridge_stp 0

不知何故,我希望使用用户定义的网桥将我的容器绑定到该接口,然后就不必担心 docker 端的 VLAN。

似乎让 docker 使用特定接口的唯一方法是主机上的 macvlan 或路由规则:

如果我忽略了更简单的方法,请告诉我。

【问题讨论】:

    标签: docker nginx networking


    【解决方案1】:

    我最终解决了这个问题,诀窍是指定范围:

    # docker network create --subnet=172.18.0.0/16 -d bridge -o com.docker.network.bridge.name=MY_NET MY_NET
    

    然后在这种情况下使用防火墙标记我选择7

    # iptables -t mangle -A PREROUTING -s 172.18.0.0/16 -j MARK --set-xmark 0x7/0xffffffff
    

    确保启用此sysctl 进行路由

    # sysctl -w net.ipv4.conf.all.rp_filter=2
    

    /etc/rt_tables添加一个CONTAINER表

    7 CONTAINERS
    

    添加一些ip规则:

    # ip rule add fwmark 7 table CONTAINERS prio 700
    # ip route add default via 192.168.7.1 table CONTAINERS
    # ip route add 192.168.7.1 dev bond0.7 table CONTAINERS
    

    您可以使用以下方法对其进行测试:

    wget -q -O - ifconfig.me
    

    【讨论】:

      【解决方案2】:
      sudo nsenter --net=/var/run/netns/hostname
      

      【讨论】:

      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案添加解释并说明适用的限制和假设。
      猜你喜欢
      • 2016-07-27
      • 2021-11-07
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多