Вопрос или проблема
Я прочитал это в документации:
Каждый Pod получает свой собственный IP-адрес … pods на узле могут общаться со всеми pods на всех узлах без NAT.
Следует ли мне понимать это как “каждый pod получает свой собственный уникальный IP-адрес по кластеру“?
Я предполагал, что это так, но причина, по которой я спрашиваю, в том, что я заметил pods с одинаковыми IP-адресами просто на разных узлах сразу после инициализации нового кластера, следуя инструкциям здесь. Кластер имеет 3 узла test-vm{4,5,6}
, с test-vm4
как мастером, работающим в локальной фиктивной сети 10.1.4.0/16. Я использовал flannel для CNI и настроил его так:
kubectl patch node test-vm{4..6} -p '{ "spec": { "podCIDR": "10.244.0.0/16" } }' # Мне нужно было сделать это, потому что я не настроил это при инициализации кластера. См. https://stackoverflow.com/a/60944959/2038383.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Обратите внимание, что 3 IP-адреса встречаются дважды для 2 различных pods – 10.244.0.{2,3,4}:
$ kubectl get pods --all-namespaces -o wide -w
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default curl 1/1 Running 0 14m 10.244.0.4 test-vm6 <none> <none>
default my-nginx-cf54cdbf7-d6s9m 1/1 Running 0 17m 10.244.0.3 test-vm6 <none> <none>
default my-nginx-cf54cdbf7-twrvw 1/1 Running 0 17m 10.244.0.2 test-vm6 <none> <none>
default my-nginx-cf54cdbf7-xpff6 1/1 Running 0 17m 10.244.0.4 test-vm5 <none> <none>
default my-nginx-more-5f79688b9d-4c9jk 1/1 Running 0 3m10s 10.244.0.6 test-vm5 <none> <none>
default my-nginx-more-5f79688b9d-7htsn 1/1 Running 0 3m18s 10.244.0.5 test-vm5 <none> <none>
default my-nginx-more-5f79688b9d-gqz9b 1/1 Running 0 3m4s 10.244.0.7 test-vm5 <none> <none>
default nginx1 1/1 Running 0 9s 10.244.0.8 test-vm5 <none> <none>
kube-system coredns-64897985d-kt82d 1/1 Running 0 41m 10.244.0.2 test-vm5 <none> <none>
kube-system coredns-64897985d-rd7gz 1/1 Running 0 41m 10.244.0.3 test-vm5 <none> <none>
kube-system etcd-test-vm4 1/1 Running 0 41m 10.1.4.36 test-vm4 <none> <none>
kube-system kube-apiserver-test-vm4 1/1 Running 0 41m 10.1.4.36 test-vm4 <none> <none>
kube-system kube-controller-manager-test-vm4 1/1 Running 0 41m 10.1.4.36 test-vm4 <none> <none>
kube-system kube-flannel-ds-snkhk 1/1 Running 0 29m 10.1.4.38 test-vm6 <none> <none>
kube-system kube-flannel-ds-wtmqg 1/1 Running 0 29m 10.1.4.37 test-vm5 <none> <none>
kube-system kube-flannel-ds-x46xw 1/1 Running 0 29m 10.1.4.36 test-vm4 <none> <none>
kube-system kube-proxy-mjl69 1/1 Running 0 41m 10.1.4.37 test-vm5 <none> <none>
kube-system kube-proxy-vz2p2 1/1 Running 0 41m 10.1.4.36 test-vm4 <none> <none>
kube-system kube-proxy-xg4gg 1/1 Running 0 41m 10.1.4.38 test-vm6 <none> <none>
kube-system kube-scheduler-test-vm4 1/1 Running 0 41m 10.1.4.36 test-vm4 <none> <none>
Несмотря на то, что говорят документы, все pods не могут общаться друг с другом. Они могут общаться только с pods на одном узле, и это вызывает ошибки. Интересно, является ли это сигналом тревоги, что что-то не так, и я ищу разъяснение по этому вопросу о уникальности IP-адресов pods.
Я разобрался. Во-первых, да, pods абсолютно должны иметь уникальный IP-адрес по кластеру. Это основа работы k8s. Ссылка на k8s документацию не очень хороша и оставляет вопрос открытым. Лучше сформулированные источники:
Платформы, такие как Kubernetes, предполагают, что каждый контейнер (pod) имеет уникальный, маршрутизируемый IP внутри кластера. Преимущество этой модели заключается в том, что она устраняет сложности с отображением портов, возникающие из-за совместного использования одного IP-адреса хоста. — https://github.com/flannel-io/flannel#networking-details
Одним из основных требований модели сетевого взаимодействия Kubernetes является то, что каждый pod должен получать свой собственный IP-адрес, и что каждый pod в кластере должен иметь возможность общаться с этим IP-адресом. — https://ronaknathani.com/blog/2020/08/how-a-kubernetes-pod-gets-an-ip-address/
Теперь вопрос в том, почему моим pods назначаются одинаковые IP-адреса? В общем, это делать так на инициализации flannel CNI неправильно (я скопировал это предложение из этого SO ответа):
kubectl patch node test-vm{4..6} -p '{ "spec": { "podCIDR": "10.244.0.0/16" } }' # Мне нужно было сделать это, потому что я не настроил это при инициализации кластера.
podCIDR должен быть уникальным для каждого узла. Именно так k8s гарантирует, что каждый запланированный pod имеет уникальный IP-адрес – каждый узел назначает некоторый IP в своем podCIDR. См. этот отличный пост в блоге, объясняющий это. Вышеуказанное не эквивалентно установке --pod-network-cidr
при kubeadm init
, как это должно быть. Команда --pod-network-cidr
фактически соответствует ClusterConfiguration networking.podSubnet
. Поэтому, если вам нужно установить это позже, вам нужно удалить flannel и отредактировать конфигурацию кластера (я еще не тестировал этот подход, я просто заново инициализировал с установленным --pod-network-cidr
):
kubectl delete -f kube-flannel.yml
kubectl edit cm -n kube-system kubeadm-config # и добавьте настройку.
Как только будет установлено:
контрольная плоскость автоматически назначит CIDR для каждого узла. — https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/.
Если вы собираетесь установить podCIDR
для каждого узла, то он должен быть уникальным для каждого узла. Вам следует избегать его ручной установки, если ожидается, что узлы будут приходить и уходить динамически – что является нормальным сценарием.
ОБНОВЛЕНИЕ: Указанный выше метод установки ClusterConfiguration networking.podSubnet
после инициализации на самом деле не работает. Это даже не работает, если вы отрегестрируете и повторно зарегистрируете все узлы-рабочие, что довольно раздражает. Насколько я знаю, единственный способ заставить автоматическую настройку podCIDR узла работать – это уничтожить ваш кластер и заново инициализировать его с установленным --pod-network-cidr
или networking.podSubnet
в начальной конфигурации (см. опцию --config
).
Я сталкиваюсь с той же проблемой, как вы ее решили?
Вижу, что у моих узлов разные podCIDR
root@controller195442:/home/admin# kubectl get no controller195442 -o json | jq ‘.spec.podCIDR’
“10.244.0.0/24”
root@controller195442:/home/admin# kubectl get no worker1954466 -o json | jq ‘.spec.podCIDR’
“10.244.2.0/24”
root@controller195442:/home/admin# kubectl get no worker195443 -o json | jq ‘.spec.podCIDR’
“10.244.1.0/24”
Ответ или решение
В Kubernetes каждый под действительно должен иметь уникальный IP-адрес на уровне всего кластера. Это основополагающий принцип сетевой архитектуры Kubernetes, который обеспечивает возможность прямого общения между подами без необходимости применения NAT (перевод сетевых адресов). Это означает, что каждый под получает свой собственный IP-адрес, который должен быть рутингуем внутри кластера, позволяя таким образом всем подам общаться друг с другом, используя их IP-адреса.
Проблема дублирования IP-адресов подов
Если вы столкнулись с ситуацией, когда поды на разных нодах имеют одинаковые IP-адреса, это, скорее всего, указывает на неправильную конфигурацию сети. В вашем случае, при использовании Flannel в качестве CNI (Container Network Interface), причиной проблемы является установка одного и того же podCIDR
(подсети для подов) на всех нодах кластера.
Как связаны podCIDR
и уникальность IP-адресов?
Каждая нода должна иметь уникальный podCIDR
, который определяет диапазон IP-адресов, который может быть назначен подам, работающим на этой ноде. Если вы вручную устанавливаете одно и то же значение podCIDR
для всех нод, это ведет к ситуации, когда различным подам назначаются одинаковые IP-адреса. Например, если все ноды имеют podCIDR
равный 10.244.0.0/16
, то Flannel может попытаться выделить IP-адреса из одного и того же диапазона для подов на разных нодах, что и приводит к конфликтам.
Рекомендации по устранению проблемы
-
Инициализация кластера с правильной конфигурацией: Лучше всего настроить
podCIDR
при инициализации кластера с помощью флага--pod-network-cidr
. Это гарантирует, что каждый узел получит уникальный набор IP-адресов при автоматическом выделении.kubeadm init --pod-network-cidr=10.244.0.0/16
-
Корректное изменение конфигурации: Если вы уже инициализировали кластер, и требуется изменить
podCIDR
, правильный подход заключается в удалении Flannel и редактировании конфигурации кластера. Это можно сделать следующим образом:kubectl delete -f kube-flannel.yml kubectl edit cm -n kube-system kubeadm-config
Добавьте параметр
networking.podSubnet
с уникальными значениями для каждой ноды, что обеспечит корректное распределение IP-адресов. -
Пересоздание кластера при необходимости: Если вы не можете исправить конфигурацию после инициализации, могут потребоваться более радикальные меры, такие как полное удаление кластера и новая инициализация с правильной конфигурацией.
Заключение
Уникальность IP-адресов подов в Kubernetes – это критически важный аспект для нормального функционирования кластера. Понимание того, как назначаются и управляются IP-адреса, поможет вам избежать проблем с дублированием адресов и обеспечит стабильную работу взаимодействия между подами. В случае возникновения конфликтов IP-адресов всегда следует проверять правильность конфигурации podCIDR
и корректную инициализацию сетевого плагина.