Сеть 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