Что такое 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 и внешних интеграций.