Docker-хост с несколькими VLAN-ами

Вопрос или проблема

Фоновая информация

У меня есть сервер с одним физическим сетевым интерфейсом, на котором работает Docker. Этот интерфейс настроен как транк 802.1Q. Чтобы избежать ассиметричной маршрутизации, я настроил таблицы маршрутизации для каждой подсети. Вот мои интерфейсы /etc/network/interfaces:

auto enp3s0
iface enp3s0 inet dhcp
    post-up ip route add 192.168.1.0/24 dev enp3s0 table 1
    post-up ip route add default via 192.168.1.1 table 1
    post-up ip rule add from 192.168.1.0/24 table 1 priority 101
    post-up ip route flush cache
    pre-down ip rule del from 192.168.1.0/24 table 1 priority 101
    pre-down ip route flush table 1
    pre-down ip route flush cache

auto enp3s0.2
iface enp3s0.2 inet dhcp
        hwaddress ether 00:11:22:33:44:55
        post-up ip route add 192.168.2.0/24 dev enp3s0.2 table 2
        post-up ip route add default via 192.168.2.1 table 2
        post-up ip rule add from 192.168.2.0/24 table 2 priority 102
        post-up ip route flush cache
        pre-down ip rule del from 192.168.2.0/24 table 2 priority 102
        pre-down ip route flush table 2
        pre-down ip route flush cache

auto enp3s0.4
iface enp3s0.4 inet dhcp
        hwaddress ether 00:11:22:33:44:56
        post-up ip route add 192.168.4.0/24 dev enp3s0.4 table 4
        post-up ip route add default via 192.168.4.1 table 4
        post-up ip rule add from 192.168.4.0/24 table 4 priority 104
        post-up ip route flush cache
        pre-down ip rule del from 192.168.4.0/24 table 4 priority 104
        pre-down ip route flush table 4
        pre-down ip route flush cache
...

Эта настройка работает нормально, если я запускаю контейнер с параметром –net=host. Контейнеры доступны из каждой подсети/VLAN.

Проблема

Я хотел бы иметь больше контроля над портами и доступностью (не каждый Docker должен быть доступен в каждой подсети). Если я использую параметр -p (например, -p 3777:3777), контейнеры больше не доступны.

Этот гид https://hicu.be/docker-networking-macvlan-vlan-configuration
решает аналогичную проблему, но я не хочу расширять свои VLAN на Docker и назначать IP-адрес каждому экземпляру Docker. Это слишком много.

Желательное решение

У моего сервера есть IP-адрес в каждой подсети/VLAN,
192.168.1.199 (родной VLAN / управление)
192.168.2.199 (vlan2)
192.168.4.199 (vlan4)

Я хотел бы запускать Docker с параметром -p и выбирать, на каком интерфейсе он будет доступен.
Например, docker run –p 9000:9000 –name portainer … и он должен быть доступен только через 192.168.1.199:9000.

Возможно, моя настройка ip route/ip rule не совсем корректна или/и мне нужен мост Docker для каждой подсети… но на этом этапе я не знаю, как двигаться дальше. На данный момент, если я выбираю параметр –p и Docker подключен к стандартному мосту Docker… контейнер совсем недоступен.

Есть ли у вас идеи?

С уважением,
Марк

Редактирование:
Контейнер portainer_test недоступен по адресу 192.168.4.199:9001

   mark@server:~/docker$ docker ps -a
        CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                  PORTS                          NAMES
        359ebfd027b2        portainer/portainer         "/portainer -H unix:…"   21 минуты назад      Работающий около минуты       192.168.4.199:9001->9000/tcp   portainer_test
        9d523a8b22e4        eclipse-mosquitto           "/docker-entrypoint.…"   10 дней назад         Работающий 16 часов                                            mosquito
        a2eeb9582838        portainer/portainer         "/portainer"             10 дней назад         Работающий 16 часов                                            portainer
        f4ef7570cea2        symcon/symcon:stable        "/usr/bin/symcon"        10 дней назад         Работающий 16 часов                                            symcon
        ae43e8be871f        jacobalberty/unifi:stable   "/usr/local/bin/dock…"   10 дней назад         Работающий 16 часов (здоровый)                                  unifi
        mark@server:~/docker$ sudo netstat -tulpn | grep LISTEN
        tcp        0      0 127.0.0.1:27117         0.0.0.0:*               LISTEN      23374/bin/mongod
        tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      30474/systemd-resol
        tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1592/sshd
        tcp        0      0 0.0.0.0:1883            0.0.0.0:*               LISTEN      22212/mosquitto
        tcp        0      0 0.0.0.0:3777            0.0.0.0:*               LISTEN      22247/symcon
        tcp        0      0 192.168.4.199:9001      0.0.0.0:*               LISTEN      18622/docker-proxy
        tcp6       0      0 :::8843                 :::*                    LISTEN      22511/java
        tcp6       0      0 :::8880                 :::*                    LISTEN      22511/java
        tcp6       0      0 :::8080                 :::*                    LISTEN      22511/java
        tcp6       0      0 :::8443                 :::*                    LISTEN      22511/java
        tcp6       0      0 :::1883                 :::*                    LISTEN      22212/mosquitto
        tcp6       0      0 :::6789                 :::*                    LISTEN      22511/java
        tcp6       0      0 :::9000                 :::*                    LISTEN      22273/portainer

Для параметра -p вы можете использовать формат ip:hostPort:containerPort, например

docker run -p 192.168.1.199:9000:9000 ...

Дополнительную информацию о доступных форматах можно найти в документации

Может быть, уже поздно, но я опубликую то, что сработало с моей стороны с транком VLAN, подключенным к моему NAS, работающему на Docker….

Вам нужно создать свою собственную сетевую сеть BRIDGE => https://docs.docker.com/network/network-tutorial-standalone/#use-user-defined-bridge-networks
Стандартный мост, созданный по умолчанию, связывается со всеми IP-адресами хоста (0.0.0.0), что и является вашей проблемой.

Убедитесь, что вы используете эту опцию при его создании: com.docker.network.bridge.host_binding_ipv4 с желаемым IP-адресом вашего сервера (в вашем случае 192.168.1.199, чтобы созданный мост связывался только с этим IP)

Затем просто укажите (в вашем примере), что контейнер Portainer использует эту созданную сеть пользователя (–network при создании/запуске контейнера).

Кроме того, вы также можете рассмотреть тип сети macvlan. Удачи 🙂

Ответ или решение

Вам необходимо настроить контейнеры Docker так, чтобы они были доступны только через определённые IP-адреса и порты в ваших VLAN. Рассмотрим, как это можно сделать, шаг за шагом.

Шаг 1: Использование синтаксиса ip:hostPort:containerPort

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

docker run -p 192.168.1.199:9000:9000 --name portainer ...

Этот подход позволяет вам явно указать, что контейнер Portainer должен быть доступен только через IP-адрес 192.168.1.199 на порту 9000. То же самое можно сделать для других VLAN:

docker run -p 192.168.4.199:9001:9000 --name portainer_test ...

Шаг 2: Создание пользовательской сетевой моста

Вы можете создать свою собственную сетевую мостовую сеть Docker, чтобы контролировать, какие IP-адреса используются для связи. Для этого выполните следующие команды:

  1. Создайте пользовательскую мостовую сеть, ограничив её привязкой к определённому IP:
docker network create \
  --driver bridge \
  --subnet 192.168.1.0/24 \
  --opt com.docker.network.bridge.host_binding_ipv4=192.168.1.199 \
  my_custom_bridge

Замените 192.168.1.199 на любой IP-адрес, который должен использоваться для привязки, и my_custom_bridge на любое имя сети.

  1. Теперь запустите ваш контейнер, указав созданную сеть:
docker run --network my_custom_bridge -p 9000:9000 --name portainer ...

Шаг 3: Проверка доступности

После запуска контейнера проверьте, что он слушает указанный IP-адрес и порт. Вы можете использовать netstat для этого, аналогично тому, как это было указано в вашем вопросе. Вы должны увидеть строки, подобные следующим:

tcp        0      0 192.168.1.199:9000      0.0.0.0:*               LISTEN      ...

Если доступность работает, вы должны иметь возможность получить доступ к вашему Portainer по адресу http://192.168.1.199:9000.

Заключение

Используя вышеперечисленные методы, вы сможете контролировать доступность ваших контейнеров Docker в зависимости от VLAN и IP-адресов. Не забывайте также корректно настраивать свои маршруты и ip правила, чтобы избежать проблем с асимметричной маршрутизацией.

Если у вас возникнут дополнительные вопросы или сложности, дайте знать — я постараюсь помочь!

Оцените материал
Добавить комментарий

Капча загружается...