ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Kubernetes Service и kube-proxy: ClusterIP, NodePort, LoadBalancer и отладка сетевых проблем

Разбираем, как kube-proxy реализует Kubernetes Service в режиме iptables, чем отличаются ClusterIP/NodePort/LoadBalancer и как быстро дебажить типовые симптомы: clusterIP unreachable, nodeport not working, пустые Endpoints и эффекты externalTrafficPolicy.
Kubernetes Service и kube-proxy: ClusterIP, NodePort, LoadBalancer и отладка сетевых проблем

Зачем вообще нужен Service и при чём тут kube-proxy

Pod’ы в Kubernetes живут недолго: пересоздаются, меняют IP, переезжают на другие ноды. Если ходить к Pod’ам напрямую по их IP, приложение развалится при первом же рескейле или рестарте. Поэтому в Kubernetes есть абстракция Service — стабильная точка входа (виртуальный IP и порт), за которой прячется динамический набор Pod’ов.

За «приземление» этой абстракции на реальные сетевые правила обычно отвечает kube-proxy. В большинстве кластеров он делает это, программируя правила на нодах: чаще всего через iptables (режим iptables), реже через IPVS (режим ipvs). Дальше фокус — на сценарии kube-proxy iptables, потому что именно там чаще всего приходится разбираться руками.

Важно: kube-proxy не является прокси в привычном смысле (не «слушает порт» и не форвардит трафик пользовательским процессом). Он настраивает dataplane (iptables/ipvs), чтобы пакеты, идущие на Service IP/порт, перенаправлялись на один из Pod’ов.

Три базовых типа Service: ClusterIP, NodePort, LoadBalancer

ClusterIP

ClusterIP — сервис доступен только внутри кластера. Kubernetes выделяет виртуальный IP из диапазона Service CIDR (например, 10.96.0.0/12), и весь трафик на этот IP перенаправляется на backend Pod’ы.

Типичный кейс: внутренние API, базы, кэши, микросервисы.

NodePort

NodePort — открывает порт на каждой ноде (обычно диапазон 30000-32767). При обращении к nodeIP:nodePort трафик попадает в Service и дальше — в Pod.

Типичный кейс: простой внешний доступ без облачного балансировщика, тестовые стенды, bare metal.

LoadBalancer

LoadBalancer — поверх Service появляется внешний балансировщик. В managed-кластерах это обычно интеграция с облачным LB. В on-prem/bare metal часто используют MetalLB или другие контроллеры. С точки зрения kube-proxy, LoadBalancer почти всегда опирается на механику NodePort/ClusterIP, а внешний балансировщик лишь доставляет трафик внутрь.

Схема потока трафика Kubernetes Service: ClusterIP, NodePort и LoadBalancer

Как kube-proxy «сшивает» Service с Pod’ами

У Service есть селектор (labels), по которому выбираются Pod’ы. По факту Kubernetes создаёт объект Endpoints (или EndpointSlice), где перечислены IP:port реальных backend’ов. kube-proxy смотрит на Endpoints и строит правила, чтобы трафик на Service уходил в один из этих адресов.

Базовая проверка, которую делают первой при отладке Service:

kubectl get svc -n NAMESPACE
kubectl describe svc SERVICE -n NAMESPACE
kubectl get endpoints SERVICE -n NAMESPACE -o wide
kubectl get endpointslice -n NAMESPACE -l kubernetes.io/service-name=SERVICE -o wide

Если у Service нет Endpoints, kube-proxy обычно не сможет направить трафик «в никуда». Это одна из самых частых причин симптома clusterip unreachable.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

kube-proxy и iptables: что именно он добавляет

В режиме iptables kube-proxy создаёт цепочки и правила NAT/фильтрации. На ноде можно увидеть «фирменные» цепочки вида KUBE-SERVICES, KUBE-NODEPORTS, KUBE-SVC-*, KUBE-SEP-*.

Диагностика на ноде (нужен root):

iptables -t nat -S | grep KUBE | head
iptables -t nat -S KUBE-SERVICES | head
iptables -t nat -S KUBE-NODEPORTS | head

На что смотреть:

  • есть ли правила для нужного Service (по ClusterIP:port и/или по NodePort);
  • есть ли привязка к цепочкам endpoint’ов (обычно KUBE-SEP-*), иначе трафик будет «проваливаться»;
  • не перехватывают ли пакеты другие правила (локальный firewall, политики безопасности, nftables-совместимость).

Если вы как раз упёрлись в нюансы совместимости, полезно держать под рукой шпаргалку по iptables/nftables на Linux: как читать правила iptables и где мешает nftables-обвязка.

Практика: быстрая шпаргалка для kubernetes service debug

Когда «сервис не открывается», важно разделить проблему по слоям: DNS, Service/Endpoints, kube-proxy dataplane, CNI/маршрутизация, firewall, приложение в Pod’е.

1) Проверяем, что backend вообще жив

Сначала убедитесь, что Pod слушает порт и readiness зелёный:

kubectl get pods -n NAMESPACE -o wide
kubectl describe pod POD -n NAMESPACE
kubectl logs -n NAMESPACE POD --tail=200

Если readiness probe не проходит, Pod не попадёт в Endpoints — Service будет пустым.

2) Проверяем Endpoints и соответствие селектора

kubectl get svc SERVICE -n NAMESPACE -o yaml
kubectl get endpoints SERVICE -n NAMESPACE -o yaml

Частая ошибка: селектор Service не совпадает с labels Pod’ов. Тогда Endpoints пустой, а вы получаете «как будто сеть сломалась».

3) Проверяем доступ к ClusterIP изнутри кластера

Запускаем временный Pod и тестируем:

kubectl run -n NAMESPACE netshoot --rm -it --image=nicolaka/netshoot -- sh

Внутри:

nslookup SERVICE
nc -vz SERVICE PORT
curl -sS -m 3 http://SERVICE:PORT/

Если DNS не резолвит — это уже история про CoreDNS. Если DNS резолвит, но ClusterIP не отвечает — смотрим Endpoints, kube-proxy и CNI.

4) Проверяем kube-proxy и его режим

kubectl -n kube-system get ds kube-proxy -o wide
kubectl -n kube-system logs ds/kube-proxy --tail=200

Полезно понять, что используется: iptables или ipvs. В логах kube-proxy обычно видно, какой proxier активен. Если ожидали iptables, а включён IPVS (или наоборот), диагностика будет другой.

Симптом: clusterip unreachable

Под «ClusterIP недоступен» обычно скрывается один из сценариев:

  • Нет Endpoints: селектор не совпал, readiness не проходит, Pod’ы не в Running.
  • kube-proxy не применил правила: kube-proxy не запущен на ноде, упал, конфликтует с nftables-режимом, проблемы с conntrack.
  • Проблема маршрутизации/overlay: CNI не поднялся, нет маршрутов между нодами, MTU/encapsulation, dropped пакеты.
  • NetworkPolicy режет трафик к Pod’ам.

Если Service существует, DNS резолвит имя в ClusterIP, но TCP connect зависает или получает timeout — чаще всего проблема не в DNS, а в цепочке Service → Endpoints → правила dataplane → достижимость Pod IP.

Минимальный план действий:

kubectl get endpoints SERVICE -n NAMESPACE -o wide
kubectl get pods -n NAMESPACE -o wide --show-labels
kubectl describe svc SERVICE -n NAMESPACE

Дальше — тест напрямую до Pod IP (минуя Service). Если Pod IP недоступен с другой ноды, это CNI/маршрутизация/политики, а не kube-proxy:

kubectl get pod POD -n NAMESPACE -o wide

Затем из netshoot:

nc -vz POD_IP POD_PORT

Симптом: nodeport not working

Когда nodeport not working, часто путают два разных «не работает»:

  • не доступно снаружи (ваша сеть/интернет) до nodeIP:nodePort;
  • внутри кластера NodePort тоже не открывается.

Если изнутри кластера NodePort работает, а снаружи нет — в большинстве случаев виноваты security group/ACL/iptables на нодах, маршрутизация до nodeIP или отсутствие публичного IP.

Проверка на ноде: слушать процесс NodePort не будет (это нормально), но правила должны быть:

iptables -t nat -S KUBE-NODEPORTS | grep NODEPORT

Ещё одна классика: NodePort открыт на всех нодах, но вы пытаетесь подключаться к ноде, которая недоступна извне (например, internal-only). Тогда корректнее использовать внешний LB или выносить точку входа на edge.

NodePort и health checks

Если вы используете внешний балансировщик (включая on-prem решения) поверх NodePort, проверьте, как он делает health check. Часто проверки приходят с адресов, которые попадают под ограничения firewall или не учтены в allowlist.

Просмотр цепочек iptables KUBE-SERVICES и KUBE-NODEPORTS на ноде Kubernetes

LoadBalancer: где заканчивается kube-proxy и начинается инфраструктура

Service типа LoadBalancer обычно создаёт:

  • ClusterIP (как базу);
  • часто — NodePort (как точку входа для внешнего LB);
  • объект статуса с внешним адресом.

kube-proxy отвечает за доставку трафика после того, как он попал на ноду (через NodePort или напрямую). А вот «попасть на ноду» — это уже зона ответственности облачного провайдера/MetalLB/вашей сети.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Endpoints и EndpointSlice: почему это важно в реальной отладке

Исторически Service опирался на объект Endpoints. В новых версиях активно используются EndpointSlice — это более масштабируемый вариант, особенно при большом количестве Pod’ов.

В отладке это полезно так:

  • Если Endpoints пустой, но EndpointSlice есть — проверьте версии компонентов и корректность контроллеров (обычно они синхронизированы, но в проблемных кластерах встречаются несостыковки).
  • Если в EndpointSlice адреса есть, но трафик не ходит — ищите проблему ниже: dataplane, CNI, политики.

ExternalTrafficPolicy: Local vs Cluster — что меняется и почему ломается доступ

Ключ externalTrafficPolicy (поле externalTrafficPolicy в Service) особенно важен для NodePort/LoadBalancer.

Два режима:

  • Cluster (по умолчанию): трафик, пришедший на ноду, может быть отправлен на Pod’ы на других нодах. Это повышает шанс успешной доставки, но часто «прячет» реальный клиентский IP (в зависимости от схемы и SNAT).
  • Local: трафик будет направлен только на Pod’ы, которые локально есть на той ноде, куда пришёл запрос. Клиентский IP сохраняется чаще, но появляется риск 503/timeout, если LB шлёт трафик на ноды без локальных endpoint’ов.

Если включили externalTrafficPolicy: Local и внезапно получили «частично не работает», проверьте: есть ли backend Pod’ы на каждой ноде, куда направляет трафик внешний балансировщик.

Что делать на практике:

kubectl describe svc SERVICE -n NAMESPACE | grep -i ExternalTrafficPolicy -n
kubectl get endpoints SERVICE -n NAMESPACE -o wide
kubectl get pods -n NAMESPACE -o wide

Если LB балансирует по всем нодам, а Pod’ы есть только на части — либо меняйте политику обратно на Cluster, либо настраивайте LB так, чтобы он слал трафик только на «здоровые» ноды, либо обеспечьте присутствие Pod’ов на всех нодах (DaemonSet/anti-affinity/реплики).

Частые причины «всё настроено, но всё равно не ходит»

Конфликт iptables и nftables

На современных дистрибутивах iptables может быть «обёрткой» над nftables. В некоторых комбинациях версий ядра/iptables/nft и Kubernetes-компонентов возникают странные эффекты: правила как будто есть, но трафик не соответствует ожиданиям. Если вы подозреваете это, зафиксируйте, какой backend используется:

update-alternatives --display iptables

И проверьте, что в кластере выбран поддерживаемый путь для вашей версии Kubernetes и ОС. Если нужно навести порядок с firewall на ноде, пригодится отдельный разбор: практическое руководство по nftables для серверов.

Conntrack и перегрузка таблицы соединений

При большой нагрузке или сетевых штормах может упираться conntrack. Симптомы похожи на «случайные таймауты» к Service/Pod. Смотрите счётчики и лимиты на ноде:

sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count

Если nf_conntrack_count стабильно близок к максимуму — это инфраструктурная задача: тюнинг, снижение количества коротких соединений, keepalive, правильные таймауты.

NetworkPolicy блокирует трафик

Если вы используете CNI с поддержкой NetworkPolicy, убедитесь, что разрешён входящий трафик к Pod’ам со стороны нужных источников (namespaceSelector/podSelector/ports). При включённом default-deny Service будет существовать, Endpoints будут, но пакеты будут дропаться на уровне dataplane CNI.

Мини-чеклист: что собрать в тикет/инцидент

Если вы дебажите не в одиночку (или передаёте в поддержку/сетевикам), соберите минимум артефактов:

  • kubectl get svc, kubectl get endpoints, kubectl get endpointslice по проблемному сервису;
  • пример Pod IP и нода, где он запущен (kubectl get pod -o wide);
  • как именно тестировали (изнутри кластера или снаружи), к какому адресу/порту;
  • логи kube-proxy за момент проблемы;
  • фрагменты iptables -t nat -S KUBE-SERVICES и iptables -t nat -S KUBE-NODEPORTS по нужному Service/NodePort.

Итоги

Service в Kubernetes — это не «магия», а довольно конкретная связка: Service IP/порт + Endpoints/EndpointSlice + правила, которые на нодах настраивает kube-proxy. Когда возникают симптомы вроде clusterip unreachable или nodeport not working, быстрее всего двигаться сверху вниз: Endpoints → проверка доступа к Pod IP → kube-proxy rules (iptables) → CNI/маршрутизация → firewall/политики → особенности externalTrafficPolicy для внешнего трафика.

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

Поделиться статьей

Вам будет интересно

Kubernetes CronJob: concurrencyPolicy, startingDeadlineSeconds, timeZone и работа с Job OpenAI Статья написана AI (GPT 5)

Kubernetes CronJob: concurrencyPolicy, startingDeadlineSeconds, timeZone и работа с Job

CronJob в Kubernetes часто «ломается» не из‑за приложения, а из‑за нюансов планирования: параллельные запуски, пропущенные окна, т ...
Kernel panic на VDS: сбор диагностики через kdump и анализ vmcore OpenAI Статья написана AI (GPT 5)

Kernel panic на VDS: сбор диагностики через kdump и анализ vmcore

Kernel panic на VDS случается редко, но приводит к внезапному ребуту и потере контекста. В статье — пошаговый план: быстрый triage ...
SPF, DKIM и DMARC: как читать заголовки письма и SMTP-логи, чтобы повысить доставляемость OpenAI Статья написана AI (GPT 5)

SPF, DKIM и DMARC: как читать заголовки письма и SMTP-логи, чтобы повысить доставляемость

Практическое руководство по диагностике доставляемости: как по заголовкам письма (Authentication-Results, Received-SPF, ARC) прове ...