Сеть Docker Macvlan внутри контейнера не достигает своего собственного хоста

Я настроил сеть Macvlan между 2 хостами докера следующим образом:

Настройка хоста: HOST_1 ens192: 172.18.0.21

Создать интерфейс моста Macvlan

docker network  create  -d macvlan \
--subnet=172.18.0.0/22 \
--gateway=172.18.0.1 \
--ip-range=172.18.1.0/28 \
-o macvlan_mode=bridge \
-o parent=ens192 macvlan

Создать интерфейс macvlan HOST_1

ip link add ens192.br link ens192 type macvlan mode bridge
ip addr add 172.18.1.0/28 dev ens192.br
ip link set dev ens192.br up

Настройка хоста: HOST_2 ens192: 172.18.0.23

Создать интерфейс моста Macvlan

docker network  create  -d macvlan \
--subnet=172.18.0.0/22 \
--gateway=172.18.0.1 \
--ip-range=172.18.1.16/28 \
-o macvlan_mode=bridge \
-o parent=ens192 macvlan

Создать интерфейс macvlan в HOST_2

ip link add ens192.br link ens192 type macvlan mode bridge
ip addr add 172.18.1.16/28 dev ens192.br
ip link set dev ens192.br up

Настройка контейнера

Создайте контейнеры в обоих хостах

HOST_1# docker run --net=macvlan -it --name macvlan_1 --rm alpine /bin/sh
HOST_2# docker run --net=macvlan -it --name macvlan_1 --rm alpine /bin/sh

CONTAINER_1 в HOST_1

24: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether 02:42:ac:12:01:00 brd ff:ff:ff:ff:ff:ff inet 172.18.1.0/22 brd 172.18.3.255 scope global eth0 valid_lft forever preferred_lft forever

CONTAINER_2 в HOST_2

21: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether 02:42:ac:12:01:10 brd ff:ff:ff:ff:ff:ff inet 172.18.1.16/22 brd 172.18.3.255 scope global eth0 valid_lft forever preferred_lft forever

Таблица маршрутов в CONTAINER_1 и CONTAINER_2

Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.18.0.1 0.0.0.0 UG 0 0 0 eth0 172.18.0.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0

сценарий

HOST_1 (172.18.0.21) <-> HOST_2 (172.18.0.23) = ОК (наоборот)

HOST_1 (172.18.0.21) -> CONTAINER_1 (172.18.1.0) and CONTAINER_2 (172.18.1.16) = ОК

HOST_2 (172.18.0.23) -> CONTAINER_1 (172.18.1.0) and CONTAINER_2 (172.18.1.16) = ОК

CONTAINER_1 (172.18.1.0) -> HOST_2 (172.18.0.23) = ОК

CONTAINER_2 (172.18.1.16) -> HOST_1 (172.18.0.21) = ОК

CONTAINER_1 (172.18.1.0) <-> CONTAINER_2 (172.18.1.16) = ОК (наоборот)

CONTAINER_1 (172.18.1.0) -> HOST_1 (172.18.0.21) = FAIL

CONTAINER_2 (172.18.1.16) -> HOST_2 (172.18.0.23) = FAIL

Вопрос

Я очень близок к своему решению, которого я хотел достичь, кроме этой одной проблемы. Как я могу сделать эту работу для контейнера для подключения к своему собственному хосту. Если есть решение для этого, я хотел бы знать, как настроить в перспективе виртуализации ESXi, а также на голое железо, если есть какая-либо разница

3 ответа

Решение

Это определенное поведение для macvlan и оно разработано. Смотрите документацию по Docker Macvlan

  • При использовании macvlan вы не можете пропинговать или связываться с IP-адресом пространства имен по умолчанию. Например, если вы создадите контейнер и попытаетесь пропинговать eth0 хоста Docker, он не будет работать. Этот трафик явно фильтруется самими модулями ядра, чтобы обеспечить дополнительную изоляцию и безопасность провайдера.

  • Подчиненный интерфейс macvlan может быть добавлен к хосту Docker, чтобы разрешить трафик между хостом Docker и контейнерами. IP-адрес должен быть установлен на этом подинтерфейсе и удален из родительского адреса.

Вопрос "староват", но другие могут счесть его полезным. Существует обходной путь описан в доступе Узла секции ИСПОЛЬЗОВАНИЯ DOCKER MACVLAN NETWORKS Ларс Келлога-Stedman. Могу подтвердить - работает.

Доступ к хосту С контейнером, подключенным к сети macvlan, вы обнаружите, что, хотя он может без проблем связываться с другими системами в вашей локальной сети, контейнер не сможет подключиться к вашему хосту (и ваш хост не сможет подключиться. в ваш контейнер). Это ограничение интерфейсов macvlan: без специальной поддержки со стороны сетевого коммутатора ваш хост не может отправлять пакеты на свои собственные интерфейсы macvlan.

К счастью, есть обходной путь для этой проблемы: вы можете создать другой интерфейс macvlan на своем хосте и использовать его для связи с контейнерами в сети macvlan.

Во-первых, я собираюсь зарезервировать адрес из нашего сетевого диапазона для использования интерфейсом хоста, используя параметр --aux-address для создания сети докеров. В результате наша последняя командная строка будет выглядеть так:

docker network create -d macvlan -o parent=eno1 \
  --subnet 192.168.1.0/24 \
  --gateway 192.168.1.1 \
  --ip-range 192.168.1.192/27 \
  --aux-address 'host=192.168.1.223' \
  mynet

Это предотвратит присвоение Docker этого адреса контейнеру.

Затем мы создаем новый интерфейс macvlan на хосте. Вы можете называть это как хотите, но я называю это mynet-shim:

ip link add mynet-shim link eno1 type macvlan  mode bridge

Теперь нам нужно настроить интерфейс с зарезервированным адресом и вызвать его:

ip addr add 192.168.1.223/32 dev mynet-shim
ip link set mynet-shim up

Последнее, что нам нужно сделать, это указать нашему хосту использовать этот интерфейс при взаимодействии с контейнерами. Это относительно просто, потому что мы ограничили наши контейнеры определенным подмножеством CIDR в локальной сети; мы просто добавляем маршрут к этому диапазону следующим образом:

ip route add 192.168.1.192/27 dev mynet-shim

С этим маршрутом ваш хост будет автоматически использовать интерфейс mynet-shim при взаимодействии с контейнерами в сети mynet.

Обратите внимание, что представленные здесь интерфейс и конфигурация маршрутизации не являются постоянными - вы проиграете, если перезагрузите свой хост. Как сделать его постоянным, зависит от распространения.

В моей ситуации я добавил в контейнер еще одну сеть.

так CONTAINER_1 -> HOST_1 можно получить с другого IP-адреса ( 10.123.0.2).

CONTAINER_2 или же HOST_2 может добраться до 172.18.1.0.

Ниже приводится docker-compose образец, надеюсь, это может быть обходным путем.

      version: "3"

services:
  macvlan_1:
    image: alpine
    container: macvlan_1
    command: ....
    restart: always
    networks:
      macvlan:
        ipv4_address: 172.18.1.0
      internalbr:
        ipv4_address: 10.123.0.2

networks:
  macvlan:
    driver: macvlan
    driver_opts:
      parent: ens192
      macvlan_mode: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/22
          gateway: 172.18.0.1
          ip_range: 172.18.1.0/28

  internalbr:
    driver: bridge
    ipam:
      config:
        - subnet: 10.123.0.0/24
Другие вопросы по тегам