Сеть Kubernetes под капотом

Вступление

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

Kubernetes cluster networking documentation указывает, что основные требования к сети Kubernetes:

  • все контейнеры могут связываться со всеми другими контейнерами без NAT

  • все узлы могут общаться со всеми контейнерами (и наоборот) без NAT

  • IP-адрес, который контейнер видит сам как тот же IP-адрес, который другие видят как

В этой статье мы обсудим, как Kubernetes удовлетворяет этим сетевым требованиям в кластере: как данные перемещаются внутри модуля, между модулями и между узлами.

Мы также покажем, как KubernetesService может предоставить один статический IP-адрес и запись DNS для приложения, упрощая взаимодействие со службами, которые могут быть распределены между несколькими постоянно масштабируемыми и меняющимися модулями.

Если вы не знакомы с терминологией Kubernetespods иnodes или другими основами, наша статьяAn Introduction to Kubernetes охватывает общую архитектуру и задействованные компоненты.

Давайте сначала посмотрим на сетевую ситуацию в одном модуле.

Pod Networking

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

С точки зрения сети Kubernetes обрабатывает модули так же, как традиционная виртуальная машина или единственный хост без операционной системы: каждый модуль получает один уникальный IP-адрес, и все контейнеры в модуле используют этот адрес и взаимодействуют друг с другом черезlo loopback-интерфейс с использованием имени хостаlocalhost. Это достигается путем назначения всех контейнеров модуля в один и тот же сетевой стек.

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

Pod to Pod Networking

Большинству кластеров Kubernetes потребуется развернуть несколько модулей на узел. Связь между модулями может происходить между двумя модулями на одном узле или между двумя различными узлами.

Связь в стык Связь на одном узле

На одном узле вы можете иметь несколько модулей, которые должны напрямую взаимодействовать друг с другом. Прежде чем мы проследим маршрут пакета между модулями, давайте проверим сетевую настройку узла. На следующей диаграмме представлен обзор, который мы подробно рассмотрим:

Networking overview of a single Kubernetes node

У каждого узла есть сетевой интерфейс -eth0 в этом примере - подключенный к сети кластера Kubernetes. Этот интерфейс находится в сетевом пространстве имен узлаroot. Это пространство имен по умолчанию для сетевых устройств в Linux.

Так же, как пространства имен процессов позволяют контейнерам изолировать запущенные приложения друг от друга, сетевые пространства имен изолируют сетевые устройства, такие как интерфейсы и мосты. Каждому модулю на узле назначается свое собственное изолированное пространство имен сети.

Пространства имен Pod связаны обратно с пространством именroot с помощьюvirtual ethernet pair, по сути, канала между двумя пространствами имен с интерфейсом на каждом конце (здесь мы используемveth1 вroot) s иeth0 внутри модуля).

Наконец, модули подключаются друг к другу и к интерфейсу узлаeth0 через мост,br0 (ваш узел может использовать что-то вродеcbr0 илиdocker0). Мост по сути работает как физический коммутатор Ethernet, используя ARP (протокол разрешения адресов) или IP-маршрутизацию для поиска других локальных интерфейсов для направления трафика.

Давайте теперь проследим пакет отpod1 доpod2:

  • pod1 создает пакет с IP-адресомpod2 в качестве пункта назначения

  • Пакет проходит по виртуальной паре Ethernet в пространство имен корневой сети.

  • Пакет переходит к мостуbr0

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

  • пакет проходит через виртуальную пару Ethernet в сетевое пространство именpod2 и сетевой интерфейс модуляeth0

Теперь, когда мы отследили пакет от модуля к модулю в узле, давайте посмотрим, как трафик модуля перемещается между узлами.

Pod to Pod Связь между двумя узлами

Поскольку каждый модуль в кластере имеет уникальный IP-адрес, и каждый модуль может напрямую взаимодействовать со всеми другими модулями, пакет, перемещающийся между модулями на двух разных узлах, очень похож на предыдущий сценарий.

Давайте проследим пакет отpod1 доpod3, который находится на другом узле:

Networking diagram between two Kubernetes nodes

  • pod1 создает пакет с IP-адресомpod3 в качестве пункта назначения

  • Пакет проходит по виртуальной паре Ethernet в пространство имен корневой сети.

  • Пакет переходит к мостуbr0

  • Мост не находит локального интерфейса для маршрутизации, поэтому пакет отправляется по маршруту по умолчанию кeth0

  • Optional:, если вашему кластеру требуется наложение сети для правильной маршрутизации пакетов к узлам, пакет может быть инкапсулирован в пакет VXLAN (или другой метод виртуализации сети) перед отправкой в ​​сеть. Альтернативно, сама сеть может быть настроена с надлежащими статическими маршрутами, и в этом случае пакет перемещается к eth0 и выходит из сети без изменений.

  • Пакет поступает в сеть кластера и направляется на правильный узел.

  • Пакет поступает в узел назначенияeth0

  • Optional:, если ваш пакет был инкапсулирован, на этом этапе он будет деинкапсулирован

  • Пакет переходит к мостуbr0

  • Мост направляет пакет в виртуальную Ethernet-пару модуля назначения

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

Теперь, когда мы знакомы с тем, как пакеты маршрутизируются через IP-адреса модулей, давайте посмотрим на Kubernetesservices и на то, как они строятся на основе этой инфраструктуры.

Pod to Service Сеть

Было бы трудно отправлять трафик в конкретное приложение, используя только IP-адреса pod, поскольку динамическая природа кластера Kubernetes означает, что pods можно перемещать, перезапускать, обновлять или масштабировать как в масштабе, так и в прошлом. Кроме того, некоторые службы будут иметь много реплик, поэтому нам нужен какой-то способ балансировки нагрузки между ними.

Kubernetes решает эту проблему с помощьюServices. Сервис - это объект API, который отображает один виртуальный IP-адрес (VIP) на набор IP-пакетов. Кроме того, Kubernetes предоставляет запись DNS для имени каждой службы и виртуального IP-адреса, поэтому к службам можно легко обращаться по имени.

Сопоставление виртуальных IP-адресов с IP-адресами модулей в кластере координируется процессомkube-proxy на каждом узле. Этот процесс настраиваетiptables или IPVS для автоматического преобразования VIP-адресов в IP-адреса модулей перед отправкой пакета в сеть кластера. Индивидуальные соединения отслеживаются, поэтому пакеты могут быть надлежащим образом отменены при возвращении. IPVS и iptables могут выполнять балансировку нагрузки виртуального IP-адреса одной службы на несколько IP-адресов, хотя IPVS обладает гораздо большей гибкостью в алгоритмах балансировки нагрузки, которые он может использовать.

[.note] #Note: этот процесс трансляции и отслеживания соединений происходит полностью в ядре Linux. kube-proxy читает из Kubernetes API и обновляет iptables ip IPVS, но его нет в пути данных для отдельных пакетов. Это более эффективно и более производительно, чем предыдущие версии kube-proxy, которые функционировали как прокси на уровне пользователя.
#

Давайте проследим маршрут, по которому пакет снова идет от модуляpod1 к службеservice1:

Networking diagram between two Kubernetes nodes

  • pod1 создает пакет с IP-адресомservice1 в качестве пункта назначения

  • Пакет проходит по виртуальной паре Ethernet в пространство имен корневой сети.

  • Пакет переходит к мостуbr0

  • Мост не находит локального интерфейса для маршрутизации пакета, поэтому пакет отправляется по маршруту по умолчанию кeth0

  • Iptables или IPVS, настроенныеkube-proxy, сопоставляют IP-адрес назначения пакета и преобразуют его с виртуального IP-адреса на один из IP-адресов модуля службы, используя любые доступные или указанные алгоритмы балансировки нагрузки.

  • Optional: ваш пакет может быть инкапсулирован на этом этапе, как обсуждалось в предыдущем разделе

  • Пакет поступает в сеть кластера и направляется на правильный узел.

  • Пакет поступает в узел назначенияeth0

  • Optional:, если ваш пакет был инкапсулирован, на этом этапе он будет деинкапсулирован

  • Пакет переходит к мостуbr0

  • Пакет отправляется в виртуальную пару Ethernet черезveth1

  • Пакет проходит через виртуальную пару Ethernet и входит в пространство имён сети pod через свой сетевой интерфейсeth0.

Когда пакет возвращается вnode1, преобразование IP-адреса VIP в модуль будет обратным, и пакет вернется через мост и виртуальный интерфейс в правильный модуль.

Заключение

В этой статье мы рассмотрели внутреннюю сетевую инфраструктуру кластера Kubernetes. Мы обсудили строительные блоки, из которых состоит сеть, и подробно описали последовательность посылки пакетов в различных сценариях.

Дополнительные сведения о Kubernetes см. Вour Kubernetes tutorials tag иthe official Kubernetes documentation.

Related