Используйте мостовые сети

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

С точки зрения Docker, мостовая сеть использует программный мост, который позволяет контейнерам, подключенным к одной мостовой сети, взаимодействовать, обеспечивая при этом изоляцию от контейнеров, которые не подключены к этой мостовой сети. Драйвер моста Docker автоматически устанавливает правила на хост-компьютере, чтобы контейнеры в разных сетях моста не могли напрямую взаимодействовать друг с другом.

Мостовые сети применяются к контейнерам, работающим на одном хосте демона Docker. Для связи между контейнерами, работающими на разных хостах демона Docker, вы можете управлять маршрутизацией на уровне ОС или использовать файл оверлейная сеть.

Когда вы запускаете Docker, автоматически создаётся мостовая сеть по умолчанию (также называемый bridge), и к нему подключаются только что запущенные контейнеры, если не указано иное. Вы также можете создавать определяемые пользователем пользовательские мостовые сети. Мостовые сети, определяемые пользователем, превосходят стандартную сеть bridge.

Различия между пользовательскими мостами и мостом по умолчанию

  • Определяемые пользователем мосты обеспечивают автоматическое разрешение DNS между контейнерами.

Контейнеры в мостовой сети по умолчанию могут обращаться друг к другу только по IP-адресам, если вы не используете опция –link, который считается устаревшим. В определяемой пользователем мостовой сети контейнеры могут разрешать друг друга по имени или псевдониму.

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

Если вы запускаете тот же стек приложений в мостовой сети по умолчанию, вам необходимо вручную создает ссылки между контейнерами (используя устаревший флаг --link). Данные ссылки должны быть созданы в обоих направлениях, так что вы можете видеть, что это усложняется с более чем двумя контейнерами, которые должны взаимодействовать. Кроме того, вы можете манипулировать файлами /etc/hosts внутри контейнеров, но это создаёт проблемы, которые трудно отладить.

  • Пользовательские мосты обеспечивают лучшую изоляцию.

Все контейнеры без указанного --network присоединяются к мостовой сети по умолчанию. Это может быть рискованно, т. к. тогда несвязанные стеки/сервисы/контейнеры могут обмениваться данными.

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

  • Контейнеры можно подключать и отключать от определяемых пользователем сетей на лету.

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

  • Каждая определяемая пользователем сеть создаёт настраиваемый мост.

Если ваши контейнеры используют мостовую сеть по умолчанию, вы можете настроить её, но все контейнеры используют одни и те же параметры, такие как правила MTU и iptables. Кроме того, настройка сети моста по умолчанию происходит вне самого Docker и требует перезапуска Docker.

Пользовательские мостовые сети создаются и настраиваются с помощью docker network create. Если разные группы приложений имеют разные сетевые требования, вы можете настроить каждый пользовательский мост отдельно по мере его создания.

  • Связанные контейнеры в сетевых мостах по умолчанию совместно используют переменные среды.

Первоначально единственным способом обмена переменными среды между двумя контейнерами было их связывание с помощью –link флаг. Данный тип совместного использования переменных невозможен в пользовательских сетях. Однако есть более эффективные способы совместного использования переменных среды. Несколько идей:

  • Несколько контейнеров могут монтировать файл или каталог, содержащий общую информацию, с помощью тома Docker.

  • Несколько контейнеров можно запускать вместе, используя docker-compose, а файл compose может определять общие переменные.

  • Вы можете использовать службы swarm вместо автономных контейнеров и воспользоваться преимуществами общих секреты и конфиги.

Контейнеры, подключенные к одной и той же определяемой пользователем мостовой сети, эффективно открывают друг другу все порты. Чтобы порт был доступен для контейнеров или хостов, отличных от Docker, в разных сетях, данный порт должен быть опубликован с использованием флага -p или --publish.

Управление пользовательским мостом

Используйте команду docker network create, чтобы создать пользовательскую мостовую сеть.

$ docker network create my-net

Вы можете указать подсеть, диапазон IP-адресов, шлюз и другие параметры. Дополнительные сведения см. в справке docker network create или выводе docker network create --help.

Используйте команду docker network rm, чтобы удалить пользовательскую мостовую сеть. Если контейнеры в данный момент подключены к сети, сначала входит отключить их.

$ docker network rm my-net

Что происходит на самом деле?

Когда вы создаёте или удаляете пользовательский мост или подключаете или отключаете контейнер от пользовательского моста, Docker использует инструменты, специфичные для операционной системы, для управления базовой сетевой инфраструктурой (например, добавление или удаление устройств моста или настройка правил iptables на линукс). Данные детали следует рассматривать как детали реализации. Позвольте Docker управлять вашими пользовательскими сетями за вас.

Подключите контейнер к определяемому пользователем мосту

При создании нового контейнера вы можете указывает один или несколько флагов --network. В этом примере контейнер Nginx подключается к сети my-net. Он также публикует порт 80 в контейнере для порта 8080 на хосте Docker, поэтому внешние клиенты могут получает доступ к этому порту. Любой другой контейнер, подключенный к сети my-net, имеет доступ ко всем портам контейнера my-nginx, и наоборот.

$ docker create --name my-nginx \
  --network my-net \
  --publish 8080:80 \
  nginx:latest

Чтобы подключить работающий контейнер к существующему пользовательскому мосту, используйте команду docker network connect. Следующая команда подключает уже запущенный контейнер my-nginx к уже существующей сети my-net:

$ docker network connect my-net my-nginx

Отключить контейнер от пользовательского моста

Чтобы отключить работающий контейнер от пользовательского моста, используйте команду docker network disconnect. Следующая команда отключает контейнер my-nginx от сети my-net.

$ docker network disconnect my-net my-nginx

Используйте IPv6

Если вам нужна поддержка IPv6 для контейнеров Docker, вам нужно включить опцию в демоне Docker и перезагрузить его конфигурацию, прежде чем создавать какие-либо сети IPv6 или назначать IPv6-адреса контейнеров.

Когда вы создаёте свою сеть, вы можете указывает флаг --ipv6, чтобы включить IPv6. Вы не можете выборочно отключить поддержку IPv6 в сети bridge по умолчанию.

Включает пересылку из контейнеров Docker во внешний мир

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

  1. Настраивает ядро Linux, чтобы разрешить переадресацию IP.

    $ sysctl net.ipv4.conf.all.forwarding=1
    
  2. Изменяет политику для политики iptables FORWARD с DROP на ACCEPT.

    $ sudo iptables -P FORWARD ACCEPT
    

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

Используйте мостовую сеть по умолчанию

Сеть по умолчанию bridge считается устаревшей деталью Docker и не рекомендуется для использования в рабочей среде. Его настройка выполняется вручную, и он имеет технические недостатки.

Подключите контейнер к мостовой сети по умолчанию

Если вы не укажете сеть с помощью флага --network и укажете сетевой драйвер, ваш контейнер по умолчанию будет подключен к сети bridge по умолчанию. Контейнеры, подключенные к сети bridge по умолчанию, могут обмениваться данными, но только по IP-адресу, если они не связаны с использованием устаревший флаг –link.

Настраивает мостовую сеть по умолчанию

Чтобы настроить сеть по умолчанию bridge, вы указываете параметры в daemon.json. Вот пример daemon.json с несколькими указанными параметрами. Указывает только те параметры, которые необходимо настроить.

{
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/25",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "192.168.1.254",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["10.20.1.2","10.20.1.3"]
}

Перезапустите Docker, чтобы изменения вступили в силу.

Используйте IPv6 с мостовой сетью по умолчанию

Если вы настраиваете Docker для поддержки IPv6 (см. Использовать IPv6), мостовая сеть по умолчанию также автоматически настраивается для IPv6. В отличие от определяемых пользователем мостов, вы не можете выборочно отключить IPv6 на мосте по умолчанию.

Следующие шаги