логотип PurpleSchool
логотип PurpleSchool

Работа с адресацией IPs в Kubernetes

Автор

Олег Марков

Введение

В Kubernetes большое значение имеет то, как назначаются и используются IP-адреса для разных компонентов — Pod, Service, Node. Механизмы адресации влияют на доступность приложений, безопасность и масштабируемость кластера. Правильное понимание того, как Kubernetes управляет IP-адресами, поможет обезопасить инфраструктуру, избежать портовых конфликтов, расширить возможности сети и ускорить отладку проблем. Смотрите, я объясню, как работает адресация IP, покажу примеры кода и YAML-манифестов, а также расскажу и о тонкостях сетевой архитектуры Kubernetes.

Работа IP-адресации в Kubernetes: базовые понятия

Начнем с разбора основных типов IP-адресов в Kubernetes:

  • Pod IP — внутренний адрес, выдаваемый каждому Pod.
  • Service IP (ClusterIP, NodePort, LoadBalancer) — адрес, по которому сервис доступен внутри (или снаружи) кластера.
  • Node IP — адрес, по которому доступен узел кластера.

Давайте посмотрим, как и когда эти адреса появляются и для чего используются.

Откуда берутся IP-адреса для Pod

Когда вы создаете Pod, kubelet на Node взаимодействует с сетевым плагином (например, CNI), чтобы выделить Pod уникальный IP-адрес из заранее определенного пула подсети. Каждый Pod получает один IP-адрес, который используется всеми контейнерами внутри этого Pod для входящих и исходящих соединений.

Схематично это выглядит так:

  • Поднимается Pod.
  • kubelet вызывает плагин сети для назначения IP.
  • Плагин регистрирует новый IP в выбранной подсети Node.

Пример получения IP Pod:

kubectl get pod nginx -o wide

Вы получите что-то вроде:

NAME   READY   STATUS    RESTARTS   AGE   IP           NODE
nginx  1/1     Running   0          2m    10.244.1.12  node-1

Здесь 10.244.1.12 — это IP-адрес Pod. Обратите внимание: этот IP доступен только изнутри кластера.

Как назначаются IP-адреса Service

Сервисы нужны, чтобы обеспечить стабильный способ обращения к Pod, даже если их IP меняются. При создании Service Kubernetes берет IP-адрес из диапазона ClusterIP, настроенного в kube-apiserver.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

Сразу после создания сервис получает IP:

kubectl get service my-service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
my-service   ClusterIP   10.100.123.45   <none>        80/TCP    1m

10.100.123.45 — здесь это ClusterIP.

Виды Service и их IP:

  • ClusterIP: доступен только внутри кластера.
  • NodePort: ClusterIP + порт на каждом Node.
  • LoadBalancer: внешний IP через провайдера.

Node IP и его роль

Обычно Node IP — это адрес сетевого интерфейса машины (виртуального или физического), на которой работает kubelet. С него происходит обмен между Pod и внешней сетью, а также открываются NodePort сервисы.

Узнать Node IP:

kubectl get nodes -o wide
NAME      STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP
node-1    Ready    <none>   25d   v1.26.1   10.0.0.10     35.240.50.23
  • Internal-IP — адрес внутри облачной/локальной сети.
  • External-IP — публичный адрес (если есть).

Диапазоны подсетей для Pod и Service

В Kubernetes можно (и нужно) явно задавать диапазоны IP-адресов:

  • --pod-network-cidr: диапазон для Pod (обычно /16 или /24).
  • --service-cluster-ip-range: диапазон для Service.

Эти параметры задаются на этапе создания кластера или в настройках контроллера.

Пример в kubeadm:

kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12

Совет: правильное определение диапазонов IP убережет от пересечений с внутренними сетями офиса или облака.

Как работает сетевой плагин (CNI) и IPAM в Kubernetes

Каждый Pod, запускающийся на Node, получает IP-адрес благодаря выбранному сетевому плагину (например, Flannel, Calico, Cilium). Все сетевые плагины используют CNI — стандартный интерфейс, позволяющий Kubernetes подключать сеть к Pod.

Принцип работы CNI-плагина

  • kubelet вызывает плагин через бинарник и передает параметры Pod.
  • CNI-плагин проверяет, какие IP-адреса свободны в своей подсети.
  • IP назначается, интерфейсы и маршруты прописываются (обычно через veth).
  • Вся информация сохраняется локально на Node и в etcd-кластер Kubernetes.
# Получить все интерфейсы на Node
ip a
# Проверить маршруты для Pod
ip route

Часто для Pod выделяют отдельные virtual ethernet pair (veth), соединяющие сетевой namespace Pod и основную сеть Node.

IPAM: управление пулом IP

IP Address Management (IPAM) — этот компонент отслеживает выделенные IP, чтобы один и тот же адрес не достался нескольким Pod.

Для Flannel и Calico можно указать свои диапазоны:

# flannel-config.yaml
net-conf.json: |
  {
    "Network": "10.244.0.0/16",
    "Backend": {
      "Type": "vxlan"
    }
  }

Если IP заканчиваются или конфликтуют, новые Pod не будут запускаться — важно следить за размерами пулов и их освобождением.

Работа с IP-адресами в продакшене: советы, конфигурации, отладка

Как изменить диапазон IP после установки

Изменять диапазоны IP после запуска кластера проблематично. Придется пересобрать кластер с новыми параметрами, корректно удалять старые объекты и настройки сети.

Если диапазон мало используется или кластер маленький — иногда проще пересоздать.

Как резервировать статические IP для Service (например, в Google Cloud)

В некоторых случаях нужно, чтобы Service LoadBalancer имел фиксированный внешний IP. Например, для привязки DNS или разрешения через фаервол.

В GCP:

  1. Создайте статический IP:
gcloud compute addresses create my-static-ip --region=us-central1
  1. Добавьте его в Service:
apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  loadBalancerIP: 35.240.60.70
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 8080

В других облаках механизм похожий — уточняйте в документации провайдера.

Перезапуск Pod — меняется ли IP?

Да, Pod после удаления и повторного запуска получает новый IP, потому что Kubernetes динамически выделяет IP из пула. Если нужен постоянный адрес, используйте Service (или StatefulSet с Headless Service для DNS).

Как получить список всех занятых IP

Вариантов несколько:

# Вытащить все Pod IP
kubectl get pod -A -o jsonpath="{..podIP}"

Если хочется с деталями по Service, добавьте:

kubectl get svc -A -o wide

Для диагностики подсети лучше работать с сетевым плагином (см. документацию к вашему CNI).

Как ограничить IP-адреса для определённого Namespace

Иногда хочется изолировать Namespace с помощью подсети. Большинство CNI поддерживают такие возможности через свои политики, например:

  • В Calico через IPPool и label селектор Namespace.
  • В Cilium через CustomResource.

Пример для Calico:

apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  name: custom-ns-pool
spec:
  cidr: 10.10.0.0/24
  ipipMode: Always
  natOutgoing: true
  nodeSelector: all()
  namespaceSelector: has(label-key)

Показываю вам пример, который можно доработать под конкретные потребности.

Типовые проблемы с IP-адресами в Kubernetes

Адреса доступа снаружи: опции и ограничения

  • Для доступа снаружи используйте LoadBalancer или Ingress Controller.
  • NodePort подойдет только для "простых" тестов.
  • В Prod почти всегда применяют Ingress (с HTTPS и балансировкой).

Ошибки при нехватке пулов IP

Если вы видите ошибку типа "no IP addresses available in subnet", скорее всего:

  • Выбрали слишком маленький диапазон для Pod.
  • Часть IP заблокирована настройками CNI.
  • Старые Pod не освобождают адреса (например, при zombie state).

Проверьте состояние компонентов и ставки пулов.

Проблемы NAT и маршрутизации

Pod по умолчанию выходят наружу через SNAT (IP-адрес Node). Убедитесь, что:

  • Node имеют доступ наружу.
  • Ваш маршрутизатор знает о внутренней подсети Pod (на проде часто настраивают статические маршруты).

Ограничивать трафик лучше через NetworkPolicy, не через NAT.

Примеры для отладки сетевой адресации

Диагностика доступа между Pod

Проверьте доступность сети с помощью утилиты ping или curl внутри Pod.

Запуск временного Pod для диагностики:

kubectl run -it --rm debug --image=busybox -- /bin/sh
# Пропинговать нужный Pod
ping 10.244.1.12

Если запрос не проходит — скорее всего, проблемы в CNI или политиках сети.

Проверка конфликтов IP

Посмотреть текущие адреса на Node:

ip a
# Проверить процессы, занявшие порт
ss -tnlp

Можно поймать конфликты, если запускаете несколько кластеров в одной сети.

Установить ограничения по IP-диапазону Service

Используйте параметр --service-cluster-ip-range в настройках apiserver.

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
  extraArgs:
    service-cluster-ip-range: 10.96.0.0/12

После изменения — потребуется перезапуск apiserver.

Получить IP всех компонентов программно

Через Go или Python можно использовать клиент k8s:

// Получаем все Pod и их IP
pods, _ := clientset.CoreV1().Pods("").List(ctx, metav1.ListOptions{})
for _, p := range pods.Items {
    fmt.Printf("Pod %s IP %s\n", p.Name, p.Status.PodIP)
}

Заключение

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

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как узнать, какой CNI-плагин используется в кластере?

Выполните команду:

kubectl get pods -n kube-system

Посмотрите на Pod с именами flannel, calico, cilium, weave-net и другие. Там же в документации вашего кластера указано, какой CNI применяется.


Можно ли вручную освободить “зависший” IP пода, если он не вернулся в пул?

Да, нужно найти и удалить соответствующую запись на Node — обычно это JSON-файл или запись об интерфейсе в /var/lib/cni/networks/. После этого CNI-плагин должен снова отпустить IP, если Pod удален.


Как изменить IP-адрес у уже существующего Pod?

Стандартными средствами нельзя — IP выдается автоматически из пула при создании Pod, изменить его нельзя. Если нужно изменить IP, пересоздайте Pod (kubectl delete pod & потом create/apply).


Почему сервис ClusterIP иногда не доступен из Pod другого Namespace?

Возможны ограничения из-за сетевых политик (NetworkPolicy) или CNI-плагина. Проверьте правила NetworkPolicy — возможно, трафик между Namespace блокируется политиками.


Можно ли на одном Node назначить Pod из разных Namespace IP из разных подсетей?

Да, если CNI-плагин это поддерживает. Например, в Calico можно настроить IPPool с фильтрацией по Namespace через selector, тогда Pod в нужном Namespace получат адреса из отдельного пула.

Стрелочка влевоГайд по Certificate Management в KubernetesНастройка и примеры использования HTTPS в KubernetesСтрелочка вправо

Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!

Kubernetes — часть карты развития DevOps

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Kubernetes

Terraform и Kubernetes инфраструктура как кодНастройка и использование Runners в KubernetesНастройка и деплой PostgreSQL в KubernetesСравнение и интеграция Openshift и KubernetesПримеры интеграции GitHub Actions и KubernetesDeploy приложений в Kubernetes - пошаговое руководство для начинающих и не толькоКак настроить CD в KubernetesИнтеграция Ansible в KubernetesИнтеграция CI/CD с Jenkins и KubernetesИнтеграция Kubernetes с GitLab - Автоматизация CI CD в облачной инфраструктуреГайд по DevOps инструментам в KubernetesОсобенности платформы Deckhouse в Kubernetes
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Kubernetes и Helm

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Микросервисы

Антон Ларичев
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий