Одной из самых революционных технологий стала виртуализация/контейнеризация, буквально, разъединив понятие одна машина – один сервис. Если до этого компании арендовывали целый сервер для решения своих задач, то теперь это открытая услуга по управлению виртуальными пространствами, где у каждого из есть отдельная файловая, процессная и сетевая среды.
Многие проекты уже построены на подобной концепции, где информационные системы могут крутиться на одном сервере. Но в таких случаях необходимо четко понимать, как работает сеть в платформах виртуализации. В данном материале мы рассмотрим практическую реализацию построения сетевой инфраструктуры для контейнеров.
Алгоритм работы сетей в ОС
Для понимания принципа коммуникации контейнеров необходимо рассмотреть подсистему сети в ОС. Она представляет собой набор интерфейсов, конфигов, netfilter механизма, и таблицы маршрутизации.
- Сетевой пакет приходит на интерфейс после обработки драйвером, с этой точки ОС начинает работу с ним;
- После он попадает на механизм маршрутизации, который представлен схемой с двумя возможными вариантами разветвления: на перенаправление и в сетевой стек приложению на обработку;
- В точках маршрутизации трафика существует фильтрация пакетов, которая позволяет изменять их содержимое и фильтровать по мере прохождения основной цепочки;
- После трафик выходит в сеть с интерфейса машины.
В представленном наборе объектов есть практически все для работы виртуальной инфраструктуры, интерфейсы, маршрутизатор в виде таблицы из маршрутов, только не хватает коммутатора, который бы организовывал канальную среду. Поэтому для того, чтобы сети работали корректно появились виртуальные сетевые устройства.
Теперь схема сетевого стека с сетями контейнеров выглядит так:
Для каждого контейнера создан свой namespace, где есть интерфейсы, свой netfilter и таблица маршрутизации, но нам здесь интересны только их интерфейсы. Фактически без дополнительных виртуальных решений два пространства не могут коммуницировать.
Необходимо вынести их в один хостовой namespace, для копирования трафика будем использовать пару виртуальных интерфейсов veth. Они позволят передавать копии трафика от одного к другому интерфейсу в разных средах. Тем самым мы получим трафик наших изолированных пространств, осталось только прикрепить их к виртуальному устройству/интерфейсу стека – bridge.
Название может вас запутать, но это полноценный коммутатор L3, так как он является интерфейсом и подключен к нашему хвостовому стеку, то может и маршрутизировать трафик на ОС. Теперь зная, как устроена классическая виртуальная инфраструктура можно просмотреть предлагаемые варианты сети в Docker Network и реализовать из них свои!
Типы подключения контейнеров
Классически представлены несколько драйверов для формирования сети в стеке ОС:
- bridge – сеть с коммутатором, позволяет создать скрытые сети внутри ОС со своим коммутированием и маршрутизацией;
- host – для процессов задается хостовой namespace, без создания дополнительных сетевых сред;
- none – отсутствие сетевого стека у контейнера, а значит и подключения к каким либо сетям;
- overlay – использование нескольких dockerd для формирования единой сети;
- macvlan – представляет классический bridge, где для хостового интерфейса задаются sub-интерфейсы, которые уже используются для коммуникации с внешней сетью самими контейнерами;
- ipvlan – аналогично macvlan, только на основе IP-адресов.
В данном материале рассмотрим настройку основных и приоритетных из представленных способов!
В справке представлена основная информация о возможностях подключения новых сетей и контейнеров к ним.
Подключение мостом или MacVlan
Рассмотрим сугубо рабочую задачу, где у нас совокупность контейнеров представляет собой ИС или же информационную систему. В таких случаях стараются придерживаться концепции легкого управления узлами, а так же высокой производительностью сети.
Значит настраиваем MacVlan или же bridge, который позволит через хостовой канал связи обращаться от sub-интерфейса связанного с хостовым, но уже со своими конфигурационными параметрами. Тем самым устройство будет считаться отдельным в сети! Обратите внимание, что для перенаправления трафика используется veth, который представляет собой не классический интерфейс.
--subnet=192.168.58.0/24 \
--gateway=192.168.58.1 \
-o parent=eth0 macvlan_network
Где параметр -d определяет драйвер, который будет использоваться, –subnet адрес сети, в котором будет проходить идентификация, –gateway шлюз подключения, а parent родительский интерфейс через чей канал пойдет трафик. Далее создадим контейнер, где укажем основные опции:
Где к контейнеру указали сеть macvlan_network и его IP-адрес вручную, но если вы его не укажете, то Docker выберет самостоятельно значение, что может привести к коллизиям.
Отлично! Контейнер в режиме моста был запущен, проверим с него доступность маршрутизатора сети, а так же иных ресурсов:
После проверки можем начинать пользоваться интерфейсом и прописывать сегментацию сети под новую инфраструктуру!
Подключение через NAT/LAN или драйвер bridge
Так же можно использовать альтернативные способы подключения, где более жесткая сегментация сети или если вы еще не выделили адреса под будущую ИС. Драйвер bridge позволяет за счет внутреннего коммутатора и таблицы маршрутизации создать скрытую сеть внутри хоста и использовать его соединение с внешними сегментами.
Для этого так же предварительно создадим сетку, где укажем ее основные параметры:
А после произведем подключение контейнера к ней командой:
После чего проверим доступность нашего нового узла через команду:
Отлично, все функционирует корректно, если в предыдущем кейсе можно занимать сокеты без проброса портов, то в данном случае необходимо маршрутизировать трафик для приложения в скрытую сеть:
После чего, при обращении к нашему устройству по порту 80 сервис Docker проксирует соединение на нужный контейнер. Для просмотра конфигурации текущего бриджа можно использовать команду:
Там же можно найти IP-адрес адрес хоста в этой сети, обычно он обозначается, как gateway.
Типы подключения с драйверами none и host
Остальные типы подключения представляют собой варианты isolated сети и хостового стека. В первом случае у контейнера есть свой созданный сетевой стек, однако, он не подключен ни к одному хвостовому интерфейсу, поэтому коммуникация не возможна. Задается он так же, как и остальные решения:
Заметьте, что такая “сеть“ может быть только одна, потому что все подключенные к ней контейнеры будут априори без veth, а значит изолированы. Такие решения могут быть полезны, когда необходим сетевой стек на ОС, но без сетевых подключений в инфраструктуре.
Драйвер host заменяет создание нового сетевого namespace на использование хостового, к процессу, как и всем стандартным прикрепляется этот стек и позволяет напрямую работать с интерфейсами и сокетами сетевого стека. Задается он командой:
После чего нам доступны все классические интерфейсы нашего хоста через, которые можно начинать коммуницировать. Любой из выше представленных типов подключения к сети в Docker позволяет решить конкретно поставленные задачи, для macvlan прямое соединение с сетью, для bridge использование скрытых сетей с помощью технологии NAT, а host и none – использование хостового стека и изоляции контейнера, соответственно.
Для выполнения тестов, вы можете использовать изолированную среду VPS сервера, на любой из двух платформ vStack cloud или же VMware cloud. Нажмем на кнопку Создать сервер и выберем конфигурацию, подходящую под наши задачи, затем нажмем кнопку Создать.
Потребуется некоторое время для развертывания серверных мощностей. После чего вы можете подключиться любым из удобных способов.