Назначение IP-адреса LAN контейнеру Docker, отличному от IP-адреса хоста

Я не очень хорошо разбираюсь в сети Unix, добавляя виртуальные интерфейсы и т. д., пытаясь изучить его сейчас. Мы пытаемся dockerize наше приложение.
Мое требование: назначить ip-адрес контейнеру docker, который доступен из внешнего приложения / браузера.

IP-адрес контейнера должен быть pingable с другого компьютера в той же сети в основном.Я не хочу использовать переадресацию портов.

  1. Я хочу получить доступ к контейнеру docker просто как мы получаем доступ к виртуальной машине с помощью IP адрес.[ Без отображения порта, - P флаг. Если я запускаю любой сервер, например Apache или Tomcat внутри контейнера, он должен быть доступен используя IP контейнера и порт. Например: http://container_ip:8443]
    Возможно ли это в docker?

  2. запуск ifconfig в моем окне Unix (RHEL 7.1) показывает интерфейсы docker0, ens,lo и veth. Нет для eth0. Немного запутался в этом.

2 ответов


я изо всех сил пытался получить эту функциональность, и я поделюсь своим опытом и тем, что я сделал, чтобы получить именно то, что вам нужно.

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

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

подробный ответ:

Создание Сетевого Моста Персистентности

на Bridge, является устройством (в нашем случае виртуальным устройством), которое ведет себя подобно сетевым swiches (работает в основном на сетевом уровне 2), т. е. может подключать два или более сетевых интерфейса быть в той же локальной сети (LAN), если они имеют ту же подсеть.

вы собираетесь создать новый мост настойчивость br0 (она будет запускаться автоматически по загрузки системы), добавьте свой физический сетевой интерфейс (в моем случае это eth0). Обратите внимание, что после добавления интерфейса к мосту интерфейс больше не нуждается в IP-адресе, потому что мост получит IP-адрес и может использоваться вместо вашего интерфейса, т. е. вы можете общаться с помощью моста как если бы это был ваш физический интерфейс, и он будет пересылать пакеты данных in/out в правильное место назначения. Вам не нужно назначать какое-либо оборудование (MAC-адрес) мост, он будет автоматически принимать MAC первого добавленного интерфейса.

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

установить мосты утилита управления:

sudo apt install bridge-utils

система не сможет создать мост без bridge-utils пакет.

чтобы создать мост персистентности, отредактируйте :

sudo vim /etc/network/interfaces

добавьте конфигурацию follwing в конец файла (адаптируйте их в соответствии с вашими потребностями):

auto br0
iface br0 inet static
    bridge_ports eth0
    address 192.168.1.10
    netmask 255.255.255.0
    broadcast 192.168.1.255
    gateway 192.168.1.1

теперь удалите мост Docker по умолчанию docker0, так как он нам не нужен:

sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0

изменить сценарий запуска службы Docker для использования моста (br0) вместо моста по умолчанию Docker (docker0) и передать некоторый важный мост параметры:

Ubuntu:

sudo vim /etc/systemd/multi-user.target.wants/docker.service

адаптировать файл так, чтобы он выглядел следующим образом:

[Service]

ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1

теперь расскажите системе об изменениях в этом файле:

sudo systemctl daemon-reload

перезагрузить систему:

sudo reboot

теперь проверьте свой мост, он должен быть там!

ip addr

Теперь создайте свой контейнер, как ниже,это приведет к тому, что ваш контейнер исправит IP:

  docker run --name myContainer \
  -it --restart always --memory 100M \
  --network bridge --cap-add NET_ADMIN \
  --hostname client1.noureldin.local \
  --add-host "client1.noureldin.local client1":192.168.1.123 \
  mnoureldin/general-purpose:latest /bin/bash -c " \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \
  /bin/bash"

важная часть связанная с ваши требования к сети:

  --network bridge --cap-add NET_ADMIN \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \

конечно, убедитесь, что вы установили iproute2 net-tools iputils-ping пакеты в контейнере, чтобы иметь возможность выполнять общие сетевые команды (предоставление фиксированного ip-адреса, выполненного ip command).

при первом запуске контейнера вы можете не заметить никаких изменений в IP-адресе, потому что ваш conainer, вероятно, не имеет iproute2 пакет (т. е. нет ), просто введите упомянутые пакеты и перезагрузите контейнер и все должно быть именно так, как вы хотите!

надеюсь, что это поможет.


мой текущий предпочтительный подход с этим-использовать сетевой драйвер Macvlan или ipvlan Docker. Я предпочитаю macvlan, поскольку каждый контейнер может иметь свой собственный MAC-адрес, но некоторые вещи, такие как VMware, не любят иметь несколько Mac-адресов для одного виртуализированного nic и не будут маршрутизировать трафик должным образом.

настройка довольно прямолинейна. Сначала нужно определить несколько вещей.

  • подсети вашей сети. Используя 10.0.0.0/24 для этого пример
  • шлюз вашей сети. Использование 10.0.0.1 для примера
  • диапазон IP, используемый для выделения IP-адресов (вы можете статически назначить IP-адреса вне этого диапазона при выполнении Docker, если это необходимо). Для этого примера я буду использовать 10.0.0.128 / 25. Вам понадобится кусок IP-адресов, чтобы позволить Docker управлять, поэтому вам нужно будет убедиться, что эти IP-адреса не используются в вашей сети.
  • имя устройства, которое вы хотите использовать для движения. Для примера я буду использовать интерфейс eth0
  • имя новой сети Docker, которую вы собираетесь создать. Использование "my net" для примера.

затем вы создаете новую сеть докеров, например:

docker network create -d macvlan —-subnet 10.0.0.0/24 --ip-range 10.0.0.128/25 —-gateway 10.0.0.1 -o parent=eth0 mynet

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

docker run —-network mynet .....

дополнительные сведения см. В документах docker:https://docs.docker.com/engine/userguide/networking/get-started-macvlan

одно предостережение к этому подходу заключается в том, что macvlan/ipvlan, похоже, не работает очень хорошо с Докером для Мака. ВМ HyperKit это создает немного черный ящик. Подход macvlan / ipvlan требует более контролируемой сети, которую Docker для Mac не предоставляет. Если вы пытаетесь сделать это с Docker для Mac, я бы предложил настроить машину Docker. Документы для того, как это сделать, здесь:https://docs.docker.com/machine/get-started/.

в этом случае, если вам не нравится настройка правил маршрутизации на вашем Mac, вы должны иметь docker машина использует мостовой интерфейс, к которому можно подключить сеть macvlan/ipvlan. По моему опыту, необходимость второго NIC, который NAT ' Ed через хост MacOS не нужна, но вы можете найти что-то другое.