Привязка контейнера Docker только к определённой VLAN

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

Извините, если это дублирующий вопрос, но я давно ищу и не могу найти решение для моего случая. Пробовал AI ботов… это была просто огромная трата времени и энергии.

У меня есть сервер Ubuntu, и я разделил его на 3 VLAN, используя netplan. Нет функциональной “сети по умолчанию”. У него есть 3 VLAN: vlan2, vlan20 и vlan30. DHCP на маршрутизаторе назначает IP каждому из этих VLAN. Таким образом, машине назначены следующие IP:

  • 192.168.2.101
  • 192.168.20.2
  • 192.168.30.2

Теперь я хочу запустить несколько контейнеров Docker, каждый на своем VLAN. Но я просто не могу найти способ правильно это настроить. Я хотел бы достичь следующего:

  • каждый контейнер должен работать на одном интерфейсе VLAN и должен публиковаться ТОЛЬКО на этом интерфейсе, а не на всех из них
  • я не хочу, чтобы каждому контейнеру Docker назначались новые IP. Я знаю, что это “нормально”, но, честно говоря, не вижу в этом смысла. Если я запускаю 20 контейнеров, кто в здравом уме может поддерживать это? Скрытые IP, назначенные где-то еще, полностью невидимые для маршрутизатора. Это не вопрос, когда я получу конфликт IP, вопрос только в том, когда и сколько
  • я хочу выполнять всю конфигурацию с помощью docker compose, если возможно. Я не эксперт в сетях, и все мануальные команды я в итоге забуду
  • я могу на это пойти, но в идеале я не хочу жестко прописывать IP машины в docker compose. Я бы предпочел, чтобы машина (все 3 VLAN) получала IP, назначенные DHCP

Так, например, допустим, я хочу запустить ollama и ollama-webui. Я хочу, чтобы ollama работал на 192.168.2.101:7869, а ollama-webui на 192.168.2.101:8080. Я не хочу, чтобы они были на разных IP, и я не хочу, чтобы они были на IP, отличных от IP хоста.

Что я пробовал до сих пор:

  • режим сети host – проблема здесь в том, что используется “интерфейс сети по умолчанию” хоста. Мой “интерфейс по умолчанию” по сути бесполезен. Я не могу найти способ выбрать VLAN в режиме сети host

  • указание/жесткое задание IP в привязке портов – например, 192.168.2.101:8080:8080. Это работает немного лучше, но все равно не то, что мне нужно. Контейнер все еще доступен на всех VLAN. Я могу по-прежнему получить к нему доступ, например, через 192.168.20.2:8080. Это действительно вызывает ошибку сервера на любом другом IP, но я думаю, что это просто некоторая внутренняя ошибка в ollama-webui. С точки зрения сетей, здесь нет ничего, что привязывает это к vlan2. Например, я хочу запустить другой контейнер на 192.168.20.2:8080. Я не хочу, чтобы контейнер постоянно занимал порт для всех IP

  • macvlan/ipvlan – честно говоря, я не знаю, в чем разница между ними, но в моем случае они ведут себя одинаково. Они устраняют проблему утечки доступа к другим VLAN. Однако каждый контейнер теперь получает новый IP (не от маршрутизатора), что не то, что я хочу. Я хочу, чтобы все контейнеры, которые работают на одном VLAN, использовали тот же IP (такой же, как у хост-машины). У меня слишком много устройств, я действительно не могу управлять “скрытыми” статическими IP. Я мог бы жить с внутренними IP, если бы они были только внутренними. Мне нужно было бы настроить обратный прокси или что-то в этом роде, которое бы связывалось с этими внутренними IP из внешнего/хостового IP. Это кажется сложным, я не знаю, как сделать это правильно, и надеялся на более простое решение

Я практически застрял. Ни одно из этих решений не делает то, что я хочу. Я могу, возможно, пойти на компромисс и жестко прописать IP в docker compose, но это единственное, на что я готов пойти. Суть остается той же. Я хочу, чтобы несколько контейнеров, работающих на одном VLAN, использовали те же IP (такие же, как у VLAN хост-машины). По сути, я хочу представить, что у меня есть 3 ПК, каждый из которых подключен к разному порту доступа (и VLAN), и что все контейнеры на одной машине используют один и тот же сетевой интерфейс хоста.

Я бы оценил любую помощь. Я по уши в этом деле с VLAN. Наивно, как только я вышел из сетевого беспорядка, я надеялся, что дальше все будет “на плаву”…

Вот docker compose, с которым я играюсь, если это поможет. Я также могу опубликовать конфигурацию netplan, если это необходимо.

version: '3.8'

services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - 192.168.2.101:7869:11434
    volumes:
      - ./ollama/ollama:/root/.ollama
    container_name: ollama
    pull_policy: always
    tty: true
    restart: always
    environment:
      - OLLAMA_KEEP_ALIVE=24h
      - OLLAMA_HOST=0.0.0.0
#    networks:
#      - vlan2_ipvlan

  ollama-webui:
    image: ghcr.io/open-webui/open-webui:main
    volumes:
      - ./ollama/ollama-webui:/app/backend/data
    container_name: ollama-webui
    depends_on:
      - ollama
    ports:
      - 192.168.2.101:8080:8080
    environment:
      - OLLAMA_BASE_URLS=http://ollama:7869
      - ENV=dev
      - WEBUI_AUTH=False
      - WEBUI_NAME=Local AI
      - WEBUI_SECRET_KEY=some_key
    extra_hosts:
      - host.docker.internal:host-gateway
    restart: unless-stopped
#    networks:
#      - vlan2_ipvlan

#networks:
#  vlan2_ipvlan:
#    driver: ipvlan
#    driver_opts:
#      parent: vlan2
#    ipam:
#      config:
#       - subnet: 192.168.2.0/24
#         gateway: 192.168.2.1

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

Для того чтобы настроить Docker-контейнеры на работу только с определенным VLAN и решить перечисленные проблемы, требуется решение, которое учитывает все ваши уникальные требования: использование существующих IP-адресов хоста без назначения дополнительных IP-контейнерам, использование Docker Compose для упрощения конфигурации и отсутствие жесткого связывания с IP-адресами на хосте.

Теория

Docker контейнеры обычно взаимодействуют с сетью через виртуализацию сети. По умолчанию-то это могут быть мосты, nat или host сети, обеспечивающие взаимодействие контейнеров с внешней сетью. Однако ваш случай становится более сложным из-за использования VLAN. VLAN (виртуальные локальные сети) нужны для сегментации сети в целях управления трафиком и повышения безопасности. Основные варианты настройки Docker для работы с VLAN включают использование драйверов bridge и macvlan/ipvlan.

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

Пример

Ранее вы пробовали использовать macvlan и ipvlan драйверы, но они генерировали новые IP, что нежелательно в вашем случае. Проблема существующего моста или host сети заключается в том, что они автоматически привязывают сеть к основе хост-машины, тем самым открывая доступ через все VLAN. Решение будет в том, чтобы совершенствовать netplan конфигурацию и использовать возможности Docker Compose для лучшего контроля.

Применение

  1. Использование Netplan и Конфигурация VLAN: Убедитесь, что ваша конфигурация Netplan полностью определяет и изолирует каждый VLAN с нужными интерфейсами.

    Пример:

    network:
     version: 2
     ethernets:
       eth0:
         dhcp4: no
     vlans:
       vlan2:
         id: 2
         link: eth0
         addresses: [192.168.2.101/24]
       vlan20:
         id: 20
         link: eth0
         addresses: [192.168.20.2/24]
       vlan30:
         id: 30
         link: eth0
         addresses: [192.168.30.2/24]
  2. Настройка Docker Compose с использованием network_mode:

    Возможной опцией будет использование режима сети bridge с жесткой привязкой к IP и порту, что уже используете, но с некоторыми исправлениями для улучшения изоляции.

    version: '3.8'
    services:
     ollama:
       image: ollama/ollama:latest
       network_mode: "bridge"
       ports:
         - "192.168.2.101:7869:11434"
       volumes:
         - ./ollama/ollama:/root/.ollama
       container_name: ollama
       restart: always
       environment:
         - OLLAMA_KEEP_ALIVE=24h
         - OLLAMA_HOST=0.0.0.0
    
     ollama-webui:
       image: ghcr.io/open-webui/open-webui:main
       network_mode: "bridge"
       ports:
         - "192.168.2.101:8080:8080"
       volumes:
         - ./ollama/ollama-webui:/app/backend/data
       container_name: ollama-webui
       environment:
         - OLLAMA_BASE_URLS=http://ollama:7869
         - ENV=dev
         - WEBUI_AUTH=False
         - WEBUI_NAME=Local AI
         - WEBUI_SECRET_KEY=some_key
       restart: unless-stopped
  3. Использование IP-тейблов (iptables) для изоляции и маршрутизации трафика: Эта часть сложнее и требует знания правил iptables. Можно установить правило, которое будет принудительно разрешать трафик только с определенного IP и соответствующего VLAN интерфейса.

  4. Мосты или сети Docker (bridge networks) с ограничением по IP: Вы можете создать настраиваемую сеть с ограничением на использование IP хоста для всех контейнеров на этом VLAN. Это решение сложнее, но оно обеспечивает желаемую изоляцию.

В случае, если требуются дополнительные услуги или интеграция с другими VLAN, нужно дать дополнительное внимание к безопасности и облегчению маршрутизации на уровне сети.

Финальному решению можно предоставить основу для полноценного контроля через средствами дополнительной настройки контейнеров с применением proxies или Load Balancers, если это будет необходимо.

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

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

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