Олег Марков
Работа с адресацией 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:
- Создайте статический IP:
gcloud compute addresses create my-static-ip --region=us-central1
- Добавьте его в 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/
Как изменить 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 получат адреса из отдельного пула.
Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!
Kubernetes — часть карты развития DevOps
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Kubernetes
Лучшие курсы по теме

Kubernetes и Helm
Антон Ларичев
Docker и Ansible
Антон Ларичев