При создании распределенных систем для обслуживания контейнеров Docker корректно настроенная сеть имеет огромное значение. Сервис-ориентированная архитектура, вне всяких сомнений, в значительной мере основывается на взаимодействии между компонентами.
В данном руководстве речь пойдёт о различных сетевых стратегиях и инструментах для построения сети, используемой контейнерами Docker. Также мы рассмотрим ситуации, в которых лучше обратиться к “родным” решениям Docker, и случаи применения альтернативных подходов.
Сетевые стратегии и инструменты Docker
Docker предлагает множество базовых сетевых инструментов, необходимых для настройки взаимодействия по типу контейнер-контейнер (container-to-container) и контейнер-хост (container-to-host).
При порождении процесса Docker создаёт интерфейс нового виртуального моста по имени docker0. Этот интерфейс позволяет Docker выделить виртуальную подсеть для использования среди запущенных контейнеров. Мост служит в качестве основного связующего интерфейса между контейнером и хостом.
Когда Docker запускает контейнер, создаётся новый виртуальный интерфейс, который получает отдельный адрес в диапазоне подсети моста. IP-адрес перехватывается внутренней сетью контейнера, предоставляя сети контейнера путь к интерфейсу docker0 на хост-системе. Docker автоматически настраивает правила переадресации iptables и маскировку NAT (или сокрытие IP-адресов) для исходящего трафика docker0.
Как контейнеры открывают сервисы посетителям?
Контейнеры, находящиеся на одном хосте, могут получать доступ к сервисам, предоставляемым их соседями, без дополнительной настройки. Хост-система будет просто перенаправлять запросы, предназначенные для интерфейса docker0, в нужную точку.
Контейнеры могут открывать свои порты хосту и таким образом получать перенаправленный внешний трафик. Открытые порты могут быть отображены на хост-системе, либо выбрав определенный порт, либо позволив Docker самостоятельно выбрать случайный неиспользуемый порт. Кроме того, Docker сам выполняет настройку и создаёт правила переадресации IPtables для правильной маршрутизации пакетов в подобных ситуациях.
Открытие и публикация порта: в чём разница?
При запуске или создании образа контейнера пользователь может открыть или опубликовать порты. Разница между этими опциями существенна, хотя и не сразу заметна.
Открытие порта (англ. exposing a port) означает, что Docker примет к сведению, что запрашиваемый порт используется контейнером. Эта опция может быть использована для обнаружения сервисов и редактирования связей. Например, проверка контейнера предоставит пользователю информацию об открытых портах. Когда контейнеры связаны между собой, переменные среды будут устанавливаться в новый контейнер с указанием портов, которые были открыты в оригинальном контейнере.
По умолчанию контейнеры доступны для хост-системы и для любого другого контейнера, расположенного в этой хост-системе, вне зависимости от того, какие контейнеры в нем открыты. Открытие портов просто документирует использование порта и делает эту информацию доступной для автоматизированного редактирования связей и распределения.
В отличие от открытия порта, публикация порта (publishing a port) будет отображать его хост-интерфейс, что делает его доступным извне. Порты контейнеров могут преобразовываться в определенный порт на хосте (либо же Docker может автоматически выбрать надёжный неиспользуемый порт в случайном порядке).
Что такое Docker links?
Docker предоставляет механизм по имени Docker links, позволяющий управлять связями между контейнерами. Если к существующему контейнеру подключается новый контейнер, этот новый контейнер получит информацию о подключении через переменные среды.
Это простой способ установить связь между двумя контейнерами, предоставляющий новому контейнеру точную информацию о том, как получить доступ к нужному контейнеру. Переменные окружения устанавливаются в соответствии с портами, открытыми в другом контейнере. IP-адрес и другую информацию Docker указывает самостоятельно.
Расширения для настройки сети Docker
Описанная выше сетевая модель – это отличный фундамент для построения надёжной сети. Взаимодействие между контейнерами одного хоста – это довольно простой процесс, который может происходить по обычной сети общего пользования, если порты корректно настроены, а информация о соединении предоставляется другой стороне.
Однако функционирование или безопасность многих приложений требуют специального сетевого окружения. В некоторых случаях такого функционала Docker оказывается недостаточно. Потому для расширения функций Docker был разработан довольно широкий ряд проектов.
Создание наложенных сетей
Одним из функциональных улучшений, на котором сосредоточены сразу несколько проектов – это создание наложенных (или оверлейных) сетей. Оверлейная сеть (англ. overlay network) – это виртуальная сеть, построенная на основе существующих сетевых соединений.
Установка оверлейных сетей позволяет создавать между хостами более предсказуемую и цельную сетевую среду. Также это упрощает настройку сети между контейнерами вне зависимости от того, где они запущены. Единая виртуальная сеть может охватывать несколько хостов или подсетей, предназначенных для отдельных хостов.
Кроме того, виртуальную сеть можно использовать для построения распределённых вычислительных кластеров. В распределённом вычислительном окружении (англ. fabric computing) несколько хостов воспринимаются как более производительный целостный элемент. Внедрение техники распределённого программирования позволяет конечному пользователю управлять кластером как единым целым, устраняя необходимость администрирования каждого хоста в отдельности.
Продвинутые конфигурации сети
Существуют проекты, способные расширить возможности создания сети Docker путём повышения гибкости.
Стандартные настройки сети Docker довольно функциональны, но всё же просты. Эти ограничения проявляются особенно явно при построении кроссхостовой сети, но они могут также препятствовать применению более специализированных сетевых настроек в пределах одного хоста.
Проекты, предоставляющие дополнительные функции, не поставляются с настройками “из коробки”, но они позволяют связывать и перехватывать компоненты вручную, создавая сложные сетевые сценарии. Такие сторонние проекты открывают доступ к самым различным функциям, от простого построения частной сети между определёнными хостами до настройки мостов, виртуальных ЛВС (англ. VLAN), пользовательских субсетей и шлюзов.
Также существует ряд инструментов и проектов, которые часто используются в окружении Docker, хотя и не разрабатывались для этой цели. В частности, довольно часто внедряются зрелые технологии создания частных сетей и туннелирования, обеспечивающие безопасное взаимодействие между хостами и контейнерами.
Общие проекты для расширения функций Docker
Существует несколько наиболее популярных проектов, сфокусированных на создании оверлейных сетей для хостов Docker, среди которых:
- flannel: разработанный командой CoreOS, этот проект был изначально предназначен для предоставления каждой хост-системе собственной подсети и общей сети. В первую очередь он необходим для работы инструмента координации Google Kubernetes, но может быть полезен и в других ситуациях.
- weave: этот проект создаёт виртуальную сеть, соединяющую все хост-машины, упрощая маршрутизацию приложений путём предоставления информации о каждом контейнере, подключённом к одному сетевому коммутатору.
С точки зрения продвинутой настройки сети очень важен следующий проект:
- pipework: разработаный в качестве временной замены на период построения “родной” продвинутой сети Docker, этот проект позволяет без труда настраивать довольно сложные сети.
Ещё один важный дополнительный проект Docker:
- tinc: легковесное программное обеспечение для создания VPN, которое внедряется при помощи туннелирования и шифрования. Это надёжное решение, позволяющее настроить частную сеть для любого приложения.
Заключение
Предоставление внешних и внутренних сервисов в виде контейнерных компонентов – очень производительная модель, однако следует отдавать приоритет сетевым взаимодействиям. Docker изначально предоставляет некоторые из этих функциональных возможностей путём настройки виртуальных интерфейсов, подсетей, правил IPTables и управления NAT; кроме того, существуют другие проекты, обеспечивающие более продвинутую настройку.