Встроенная реализация сетевого взаимодействия от Docker
Сам Docker предоставляет много базового функционала сетевого взаимодействия, необходимого для связей типа “контейнер-контейнер” и “контейнер-хост”.
При запуске Docker-процесса, он создает новый виртуального интерфейс типа “мост” с названием docker0
в хост-системе. Этот интерфейс позволяет Docker создать виртуальную подсеть для использования контейнерами, которые он будет запускать. Мост будет служить основной точкой взаимодействия между сетью внутри контейнера и сетью хоста.
Когда Docker запускает контейнер, создается новый виртуальный интерфейс и ему назначается адрес в диапазоне подсети моста. IP-адрес связан с внутренней сетью контейнера, предоставляя путь для сети контейнера к мосту docker0
на системе хоста. Docker автоматически конфигурирует правила в iptables
для обеспечения переадресации и конфигурирует NAT для трафика из docker0
во внешнюю сеть.
Как контейнеры делают свои сервисы доступными для потребителей?
Другие контейнеры на том же хосте способны осуществлять доступ к сервисам, предоставляемым соседями, без какой-либо дополнительной конфигурации. Хост-система просто будет направлять запросы к интерфейсу docker0
в соответствующее место.
Контейнеры могут открывать свои порты для хоста, на которые они могут принимать трафик, приходящий из внешнего мира. Открытые порты могут быть отображены (mapped) на хост-систему либо путем выбора конкретного порта, либо разрешением Docker выбрать случайный неиспользуемый порт с большим адресом. В этих случаях Docker позаботится о всех правилах переадресации и конфигурации iptables
для корректной маршрутизации пакетов.
В чем разница между открытием (Exposing) и публикацией (Publishing) порта?
При создании образа контейнера или его запуске у Вас есть выбор между открытием и публикацией портов. Разница между эти вариантами значительная, но может быть заметна не сразу.
Открытие (exposing) порта просто означает, что Docker будет иметь ввиду, что данный порт используется контейнером. Это используется в целях обнаружения и связи. Например, проверка (inspecting) контейнера даст Вам информацию об открытых портах. Когда контейнеры связаны, переменные окружения в новом контейнере будут установлены необходимым образом, в соответствие с открытыми портами исходного контейнера.
По умолчанию, контейнеры будут доступны для хост-системы и любых других контейнеров, расположенных на том же хосте, независимо от того, открыты ли порты. Открытие порта просто документирует факт использования порта и делает эту информацию доступной для автоматизированных маппирования и соединений.
В отличие от этого, публикация (publishing) порта маппирует его на интерфейс хоста, делая его доступным для внешнего мира. Порты контейнера могут быть привязаны к конкретному порту хоста, или Docker может автоматически выбрать высокий неиспользуемый порт с большим адресом.
Что такое Docker-связи (Docker links)?
Docker предоставляет механизм под названием Docker-связи для конфигурации взаимодействия между контейнерами. Если новый контейнер связан с существующим посредством Docker-связи, новый контейнер получит информацию о подключении к существующему через переменные окружения.
Это позволяет легко устанавливать связи между двумя контейнерами путем передачи новому контейнеру явной информации о том, как осуществлять доступ к его “партнеру”. Переменные окружения устанавливаются в соответствии с портами, открытыми другим контейнером. IP-адрес и другая информация будет настроена самим Docker.
Проекты, расширяющие сетевое взаимодействие Docker
Описанная выше модель сетевого взаимодействия является хорошей базовой моделью для организации сетевого взаимодействия между контейнерами. Взаимодействие между контейнерами на одном и том же хосте достаточно просто реализуется, взаимодействие между хостами может происходить посредством использования публичных сетей при условии правильной настройки портов и передачи информации, необходимой для настройки этого взаимодействия, непосредственно хостам, участвующем в этом взаимодействии.
Тем не менее, многие приложения требуют особых условий сетевого взаимодействия из соображений безопасности или для их правильного функционирования в целом. Для этих случаев нативных решений Docker оказывается недостаточно. По этой причине, существует множество проектов, расширяющих функциональность экосистемы Docker.
Создание оверлейных сетей для абстрагирования от топологии сети
Сразу несколько проектов сфокусировали свои усилия на создании оверлейных сетей. Оверлейная сеть — это виртуальная сеть, построенная поверх существующей сети.
Создание оверлейной сети позволяет Вам создать более предсказуемую и единообразную сетевую среду между хостами. Это упрощает сетевое взаимодействие между контейнерами вне зависимости от того, где они физически запущены. Одна виртуальная сеть может охватывать множество хостов или отдельных физических подсетей.
Ещё одним примером использования оверлейных сетей является создание полносвязной вычислительной среды (fabric computing clusters). В полносвязной вычислительной среде множество хостов представляется в виде более абстрактной и высокоуровневой сущности. Реализация полносвязной вычислительной среды позволяет конечному пользователю управлять кластером, как единым целым, вместо того, чтобы работать с отдельными хостами. Организация сетевого взаимодействия играет при этом ключевую роль.
Организация продвинутого сетевого взаимодействия
Существуют проекты, расширяющие сетевые возможности Docker и предоставляющие большую гибкость его использования.
Предоставляемые Docker сетевые настройки функциональны, но ограничены по своим возможностям. Эти ограничения особенно заметны при организации взаимодействия между хостами, а также при необходимости настроить более нестандартное сетевое взаимодействие на одном хосте.
Дополнительная функциональность предоставляется при помощи “встраиваемых” возможностей. Эти проекты не предоставляют конфигурацию “из коробки”, но при этом позволяют Вам вручную настроек то, что вам необходимо для реализации более сложных сценариев сетевого взаимодействия. Примерами такого “нестандартного” сетевого взаимодействия могут быть настройка приватной сети между определёнными хостами, настройка мостов (bridges), виртуальных локальных сетей, подсетей, шлюзов (gateways).
Существует ряд инструментов и проектов, которые изначально были разработаны не для применения с Docker, но, тем не менее, часто используются в Docker для обеспечения необходимой функциональности. В частности, существующие решения для построения приватных сетей и технологии туннелирования часто используются для обеспечения безопасного взаимодействия между хостами и контейнерами.
Наиболее популярные проекты для улучшения сетевых возможностей Docker
Существует несколько проектов, фокусирующихся на построении оверлейных сетей для Docker-хостов. Наиболее распространенными являются:
- flannel: Изначально разработан командой CoreOS для обеспечения хоста возможностью создавать свою собственную подсеть в общей сети. Это, в первую очередь, необходимо для функционирования инструмента для оркестровки от Google под названием kubernetes, но полезно и в некоторых других ситуациях.
- weave: Weave создает виртуальную сеть, объединяющую каждый хост в единое целое. Это упрощает маршрутизацию, поскольку при этом каждый контейнер выглядит так, как будто от подключен к единой сети.
Для “продвинутого” управления сетью используются следующие проекты:
- pipework: созданный как временное решение до того, как встроенные сетевые средства Docker стали более или менее “продвинутыми”, этот проект предоставляет возможность “продвинутой” настройки сетевой конфигурации для контейнеров.
Ещё одним примером существующего программного обеспечения для добавления функциональности в Docker является:
- tinc: Tinc — это “лёгкое” средство для построения VPN, реализующее туннелирование и шифрование. Tinc представляет собой надёжное решение для построения частных сетей “прозрачных” для любых приложений.