n1ro°
RU

Документы · Инструкция

Docker macvlan: как настроить отдельный IP для контейнера

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

Редакция N1RO · Проверено

Короткий ответ

Docker macvlan нужен, когда контейнер должен выглядеть в физической LAN как отдельное устройство со своим MAC- и IP-адресом. На Linux создайте сеть с реальными subnet/gateway/parent параметрами, заранее исключите DHCP-конфликты и учтите, что контейнер macvlan по умолчанию не общается напрямую с самим Docker host.

Когда macvlan лучше обычного bridge

Обычный user-defined bridge подходит большинству приложений: контейнеры общаются по внутренней сети Docker, а наружу сервисы публикуются через ports. Macvlan нужен в более узких случаях — например, старое приложение ожидает присутствовать прямо в физическом сегменте, сетевой сканер должен видеть контейнер как отдельный узел или требуется собственный IP без NAT/publish. Docker назначает каждой macvlan interface уникальный MAC, поэтому для коммутатора контейнер выглядит как физически подключённое устройство. Цена такой прозрачности — требования к сетевому оборудованию: порт должен допускать несколько MAC, а слишком большое число адресов создаёт VLAN spread. Кроме того, многие cloud-провайдеры ограничивают macvlan, поэтому это в первую очередь инструмент контролируемой Linux/LAN-инфраструктуры.

Совет: Если задачу можно решить bridge + publish, не переходите на macvlan ради «красивого отдельного IP»: bridge обычно проще сопровождать.

Как создать macvlan без IP-конфликтов

  1. Узнайте интерфейс хоста, subnet, gateway и свободный диапазон адресов. Не копируйте пример 172.16.86.0/24 буквально: macvlan должен соответствовать вашей реальной L2-сети и не конфликтовать с DHCP.
  2. Используйте docker network create -d macvlan с --subnet, --gateway и -o parent=<интерфейс>. Если нужен ограниченный пул, добавьте --ip-range и --aux-address для адресов, которые Docker не должен выдавать.
  3. Запустите временный контейнер в новой сети, проверьте docker network inspect, выданный IP, MAC и default route. Затем проверьте доступ с другого устройства физической сети, а не только с самого Docker host.
  4. Linux kernel не позволяет macvlan-контейнерам напрямую общаться с их host через ту же parent interface. Если это нужно, добавьте контейнеру вторую bridge-сеть или создайте macvlan interface на host с адресом из той же subnet.

Предупреждение: Никогда не задавайте --ip-range, пересекающийся с активным DHCP pool, если DHCP-сервер не знает об этом исключении.

Параметры, которые нужно проверить

  • parent — физическая interface Linux host, через которую пойдёт трафик. --subnet должна совпадать с адресным пространством нужного сегмента, --gateway — быть реальным шлюзом этой сети. --ip-range ограничивает адреса, которые Docker будет раздавать контейнерам; --aux-address резервирует уже занятые адреса, например маршрутизатор. В режиме 802.1Q можно указать parent вроде eth0.50: Docker интерпретирует имя с точкой как VLAN sub-interface и создаёт её автоматически. Но это имеет смысл только если uplink и switch уже настроены на соответствующий tagged VLAN. Перед production проверьте ARP/MAC-таблицу на сетевом оборудовании и убедитесь, что адреса не выдаются параллельно DHCP.

Важно: Сначала создайте сеть с одним тестовым контейнером и только потом переносите сервисы: сетевые ошибки macvlan часто видны уже на уровне ARP и маршрутизации.

Почему host не пингует macvlan-контейнер

Это не обязательно ошибка firewall или Docker daemon. Документация Docker прямо описывает ограничение Linux kernel: контейнеры, подключённые к macvlan, не могут напрямую общаться с host через тот же parent. Поэтому тест «ping с Docker host» может провалиться, хотя контейнер прекрасно доступен с другого компьютера LAN. Есть два практических обхода. Первый — дать контейнеру дополнительную обычную bridge-сеть и использовать её для управления с host. Второй — создать на host отдельную macvlan interface с тем же parent и назначить ей адрес из subnet, после чего настроить маршрут к пулу контейнеров. Второй вариант требует сетевой аккуратности и не должен конфликтовать с Docker IPAM. Если host-to-container не нужен, лучше не усложнять схему.

Совет: Диагностируйте доступ минимум из трёх точек: сам контейнер, отдельное устройство LAN и Docker host. У них могут быть разные результаты по дизайну.

Перед вводом macvlan в работу

  • Linux host поддерживает macvlan; Docker не rootless; parent interface определён верно; subnet/gateway соответствуют LAN; Docker pool не пересекается с DHCP; switch допускает несколько MAC; тестовый контейнер доступен из LAN; понятна политика host-to-container; firewall физической сети пропускает нужный трафик; есть план удаления network без потери данных приложения.

Практический пример адресного плана macvlan

Допустим, домашняя или лабораторная LAN использует 192.168.10.0/24, gateway 192.168.10.1, а DHCP выдаёт 192.168.10.50–150. Для Docker можно согласовать отдельный CIDR-пул, например 192.168.10.192/27, и передать его как --ip-range=192.168.10.192/27, если этот пул исключён из DHCP. После создания network запустите один Alpine-контейнер, проверьте его адрес через docker inspect и попробуйте подключиться к нему с другого ноутбука в LAN. Если это работает, но сам Docker host контейнер не пингует, это соответствует известному ограничению macvlan, а не доказывает поломку сети. Далее решите, действительно ли host должен общаться с сервисом. Если да — добавьте management bridge или отдельную host macvlan interface; если нет, оставьте схему простой. Перед масштабированием на десятки контейнеров проверьте MAC-limit и настройки switch port, потому что каждый macvlan endpoint добавляет отдельный MAC в физическую сеть.

Совет: `--ip-range` задаётся подсетью в CIDR, а не диапазоном через тире; согласуйте этот пул с DHCP и зарезервируйте занятые адреса через `--aux-address`.

Как проверить адресный план до запуска реального сервиса

Сначала нарисуйте адресный план на бумаге или в заметке: общая LAN, gateway, DHCP-пул, статические адреса инфраструктуры и отдельный CIDR-пул Docker. Например, при LAN `192.168.10.0/24` и DHCP `192.168.10.50–150` можно выделить для macvlan непрерывную CIDR-подсеть вроде `192.168.10.192/27`, если этот диапазон действительно исключён на DHCP-сервере. В команду передаётся именно `--ip-range=192.168.10.192/27`, а не запись вида `200-220`. Если внутри пула уже есть адрес, который должен остаться за маршрутизатором, NAS или другим устройством, исключите его через `--aux-address`. После создания сети запустите один временный контейнер и проверьте `docker network inspect`, фактически выданный IP, маршрут по умолчанию и доступ с другого устройства LAN. Отдельно выполните тест с Docker host и не принимайте отсутствие связи за DHCP-проблему: прямой host-to-macvlan трафик ограничен ядром Linux. Только после проверки одного endpoint добавляйте постоянные сервисы и статические IP. Такой порядок ловит ошибки адресного плана до того, как они превращаются в плавающие конфликты ARP на всей локальной сети.

Что учитывать

Это не обязательно ошибка firewall или Docker daemon. Документация Docker прямо описывает ограничение Linux kernel: контейнеры, подключённые к macvlan, не могут напрямую общаться с host через тот же parent. Поэтому тест «ping с Docker host» может провалиться, хотя контейнер прекрасно доступен с другого компьютера LAN. Есть два практических обхода. Первый — дать контейнеру дополнительную обычную bridge-сеть и использовать её для управления с host. Второй — создать на host отдельную macvlan…

Источники и проверка

Фактическая часть сверена по первичным источникам (в т.ч. Macvlan network driver). Пример и формулировки — редакция N1RO на 2026-09-21.