Network in Pods
Подключимся к тестовому поду и посмотрим что у нас там есть.
kubectl exec -ti <podName> -- /bin/bash
Если не установлен ip, то можно его установить, используя команду.
Также установим дополнительные утилиты для анализа сети.
apt -y update
apt -y install iproute2 iputils-ping netcat-traditional telnet
Дамп трафика на сети пода.
Проверим номер интерфейса, который данный под использует для работы.
cat /sys/class/net/eth0/iflink
# В ответе будет номер интерфейса. Например, 24.
С помощью ssh можно зайти на ноду, где расположен данный под и подампить трафик по этому поду.
ssh <ipaddr_node>
sudo -i
ip link |grep ^24 # Здесь 24 - это номер интерфейса пода. Этой командой узнаем его имя.
tcpdump -i <interface_name> -w pod.out
Контейнеры на одном хосте.
Один из способов организации связи по IP-адресам между контейнерами, работающими на одном и том же хосте, предполагает создание Linux-моста.
Для организации сети в Kubernetes используются виртуальные устройства veth. Один конец veth-устройства подключается к сетевому пространству имен контейнера, другой — к Linux-мосту в сети хоста.
У всех контейнеров на одном хосте один из концов veth подключен к мосту, через который они могут связываться друг с другом по IP-адресам. У Linux-моста также имеется IP-адрес, и он выступает в качестве шлюза для исходящего (egress) трафика из pod'ов, предназначенного для других узлов.
Контейнеры на разных хостах.
В кластере Kubernetes Flannel создает устройство vxlan и соответствующим образом дополняет таблицу маршрутов на каждом из узлов. Каждый пакет, предназначенный для контейнера на другом хосте, проходит через устройство vxlan и инкапсулируется в пакет UDP. В пункте назначения вложенный пакет извлекается и перенаправляется на нужный pod.
Выделение подсетей узлам для назначения IP-адресов pod'ам
Поскольку каждый pod кластера должен иметь IP-адрес, важно убедиться в том, чтобы этот адрес был уникальным. Это достигается путем выделения каждому узлу уникальной подсети, из которой затем pod'ам на этом узле назначаются IP-адреса.
Контроллер IPAM узла
Когда nodeipam передается в качестве параметра флага --controllers
kube-controller-manager'а, он каждому узлу выделяет отдельную подсеть (podCIDR) из CIDR кластера (т.е. диапазона IP-адресов для сети кластера). Поскольку эти podCIDR'ы не пересекаются, становится возможным каждому pod'у выделить уникальный IP-адрес.
Узлу Kubernetes присваивается podCIDR в момент его начальной регистрации в кластере. Чтобы изменить podCIDR у узлов, необходимо их дерегистрировать и затем повторно зарегистрировать, в промежутке внеся соответствующие изменения в конфигурацию управляющего слоя Kubernetes.
Вывести podCIDR узла можно с помощью следующей команды:
kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
Взаимодействие среды запуска контейнеров и плагинов CNI
У каждого сетевого провайдера имеется свой плагин CNI. Runtime контейнера запускает его, чтобы сконфигурировать сеть для pod'a в процессе его запуска. В случае containerd запуском CNI-плагина занимается плагин Containerd CRI.
При этом у каждого провайдера есть свой агент. Он устанавливается во все узлы Kubernetes и отвечает за сетевую настройку pod'ов. Этот агент идет либо в комплекте с конфигом CNI, либо самостоятельно создает его на узле. Конфиг помогает CRI-плагину установить, какой плагин CNI вызывать.
Местонахождение конфига CNI можно настроить; по умолчанию он лежит в /etc/cni/net.d/<config-file>
. Администраторы кластера также отвечают за установку плагинов CNI на каждый узел кластера. Их местонахождение также настраивается; директория по умолчанию — /opt/cni/bin