Что такое Service в Kubernetes и какие его типы вы знаете?

Что такое Service в Kubernetes

Service — это абстракция, которая даёт стабильную сеть доступ к набору Pod’ов (обычно выбранных по selector). Pod’ы приходят и уходят, у них меняются IP — Service обеспечивает постоянный DNS-имя и стабильный IP/порт (ClusterIP) и реализует маршрутизацию запросов к «живым» Pod’ам (endpoints/EndpointSlices).

Service решает две задачи: discovery (Service DNS имя) и L4-маршрутизация трафика к подам.

Ключевые поля (коротко)

  • spec.selector — метки для выбора Pod’ов (не у всех типов требуется).

  • spec.ports[] — port (порт сервиса), targetPort (порт в контейнере), nodePort (для NodePort). Можно указывать имена портов (важно для health checks/HTTP).

  • spec.type — тип сервиса (см. ниже).

  • sessionAffinity — None или ClientIP (sticky sessions).

  • externalTrafficPolicy — Cluster (по умолчанию) или Local (сохранение IP клиента).

Типы Service и когда использовать

ClusterIP (по умолчанию)

Внутрикластерный IP. Используется для internal-микросервисов и обычно вместе с Ingress/Ingress Controller для внешнего HTTP. Самый распространённый тип.

NodePort

Открывает фиксированный порт на всех нодах (по умолчанию диапазон 30000–32767). Внешний трафик к любому node:nodePort перенаправляется в ClusterIP сервис → Pod. Удобно для простого экспонирования без облачного LB, но не гибко и небезопасно на прод.

LoadBalancer

Просит облако создать внешний балансировщик (L4/L7 в зависимости от cloud/annotations) и привязывает его к Service. Удобно для публичных сервисов; на облаках создаёт ресурсы и стоит денег. externalTrafficPolicy: Local сохраняет исходный IP, но тогда трафик будет направлен только на ноды с локальными Pod’ами.

ExternalName

Не создаёт проксирования — делает запись DNS CNAME на указанное externalName (например, db.example.com). Нет селектора, используется для интеграции с внешними сервисами через DNS.

Headless Service (clusterIP: None)

Нет ClusterIP — kube-dns возвращает A-record’ы для Pod’ов (или SRV), полезно для stateful-приложений (StatefulSet), когда нужен прямой доступ к каждому Pod или собственное discovery (например, Kafka, Cassandra).

Механика маршрутизации

  • kube-proxy реализует Service routing в одном из режимов: iptables или IPVS (IPVS более производительно). Новые EndpointSlices оптимизируют масштабирование сетевого состояния.

  • Для L7-функций (path/host routing, TLS termination) используют Ingress или сервис-mesh (Envoy, Istio). Service — L4 (TCP/UDP) по умолчанию.

Дополнительные опции и поведение

  • sessionAffinity: ClientIP даёт «липкие» сессии по IP (но лучше хранить сессии в Redis).

  • externalTrafficPolicy: Local сохраняет исходный IP (нужны node-level health checks и достаточный coverage нод).

  • readinessProbe на Pods исключает их из endpoints до готовности — важно для корректной маршрутизации.

  • Annotations на Service часто управляют поведением cloud-LB (health check path, static IP, internal/external LB).

Best practices

  • Для HTTP-приложений — ClusterIP + Ingress (L7) вместо прямого LoadBalancer.

  • Для production не использовать NodePort как основной способ экспонирования.

  • Для stateful — headless service + StatefulSet, использовать DNS/SRV если нужно.

  • Для сохранения client IP — externalTrafficPolicy: Local, но планировать capacity и health checks.

  • Минимизировать sessionAffinity; проектировать stateless-поды.

  • Следить за именами портов (например http), некоторые cloud health checks требуют именованных портов.

Примеры (микро)

ClusterIP:
kind: Service
spec:
type: ClusterIP
selector: { app: web }
ports: \[{ port: 80, targetPort: 8080 }\]
Headless:
kind: Service
spec:
clusterIP: None
selector: { app: db }
ports: \[{ port: 9042 }\]

Service — фундамент сетевой модели Kubernetes: даёт стабильность адресации, балансировку L4 и интеграцию с облачными балансировщиками, а headless/ExternalName расширяют возможности для stateful и внешних интеграций.