Современные приложения всё чаще разворачиваются не напрямую на серверах, а в изолированных окружениях - контейнерах. Контейнеризация позволяет упаковать приложение вместе со всеми его зависимостями и запускать его предсказуемо на любой машине
Фундаментом для контейнеров служат механизмы ядра Linux
В Linux для изоляции приложений используется механизм пространств имён
Пространство имён (Namespace) - механизм ядра Linux, который изолирует глобальные системные ресурсы между процессами, создавая для каждой группы процессов иллюзию собственного экземпляра ресурса
Пространств имен в Linux всего восемь:
iptablesБлагодаря пространствам имен можно изолировать приложения друг от друга
Разберем то, как работает пространство имен Network. Это пространство изолирует весь сетевой стек процесса и имеет собственные:
loopback)iptables/nftables/proc/net/)Благодаря этому два процесса в разных пространствах имен могут одновременно слушать один и тот же порт - они просто не знают друг о друге
Само по себе пространство изолировано и не имеет связи с внешним миром. Для соединения пространств используют пару виртуальных интерфейсов - veth (от virtual ethernet), работающий как патч-корд
Чтобы соединить несколько пространств имен между собой, используют виртуальный сетевой мост (Bridge). Он работает как обычный L2-коммутатор: получает кадры от подключённых интерфейсов и перенаправляет их нужному получателю по MAC-адресу
В качестве файрволла для фильтрации и предобработки сетевого трафика используется модуль netfilter, взаимодействие с которым обеспечивают утилиты iptables и nftables
Модуль netfilter может обрабатывать пакеты на разных этапах стека: входящие, транзитные, исходящие пакеты, трансформация пакетов и отслеживание соединений (подробнее об этом на лекции про безопасность сети)
Docker - платформа для упаковки, доставки и развертывания приложений в виде контейнеров. Контейнеры - это легкие и изолированные окружения, использующие ядро операционной системы хоста (чаще всего Linux)
Для изоляции сети Docker использует пространство имен Network, виртуальный сетевые интерфейс и функционал модуля netfilter
Docker использует несколько типов сетевых драйверов:
docker0 на хосте. Контейнеры в одной сети видят друг друга, наружу выходят через трансляцию адресовloopback). Полная сетевая изоляция, которая используется для задач, которым сеть не нужнаКаждый контейнер имеет свое отдельное пространство имен Network, в котором свои интерфейсы, таблицы маршрутизации и правила iptables
В Docker встроен свой DNS-сервер, что позволяет иметь доступ к Docker-контейнеру по его имени, а не IP-адресу
Также Docker предоставляет трансляцию адресов для общения контейнеров с сетью Интернет, а также публикацию портов для входящих подключений к контейнеру
Kubernetes - платформа для автоматизации развёртывания, масштабирования и управления контейнеризированными приложениями (или по-другому оркестратор контейнеров)
Сетевой узел (Node) в Kubernetes содержит несколько капсул (Pod), каждый из которых имеет уникальный IP-адрес в течение своей жизни. Коммуникация капсул происходит напрямую без трансляции адресов
Капсула представляет из себя один или несколько контейнеров
Также есть еще сервис - абстракция стабильной сетевой сущности, которая:
Когда создается сервис с определенным селектором, то менеджер контроллеров Kubernetes ищет капсулы, чьи метки совпадают с селектором сервиса, и добавляет их IP-адреса в список для доступа по конечной точке
По сути сервис представляет правила iptables, которыми управляет прокси Kubernetes kube-proxy. Прокси kube-proxy получает информацию о сервисе и конечных точках и составляет цепочки правил PREROUTING и OUTPUT для данного сетевого узла. Там же с помощью циклического алгоритма трафик отправляется на выбранную капсулу
Для более автоматической настройки есть CNI плагины, которые:
Если же сервис определяет, какой капсуле отправить трафик, то другой компонент Ingress Controller решает, какому сервису нужно направить HTTP-трафик. Ingress Controller является аналогом веб-сервера (например, его роль может исполнять nginx-ingress), но для кластера из узлов
Вместо прокси Kubernetes, который использует iptables и кучу абстракций, есть аналоги, которые в основном применимы в рамках нагруженных систем:
iptables использует eBPF - программы, исполняемые прямо в ядре Linuxkube-proxy, CNI-плагина и сетевого политика в одном компоненте