Что такое сервис (Service) в Kubernetes?

«Что такое сервис (Service) в Kubernetes?» — вопрос из категории Kubernetes, который задают на 29% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сервис (Service) в Kubernetes — это абстракция, которая определяет логический набор Pod'ов (обычно выбираемых по селектору selector) и политику доступа к ним. Его основная задача — обеспечить стабильную сетевую конечную точку для набора динамически меняющихся Pod'ов. Pod'ы могут пересоздаваться, масштабироваться и перемещаться между узлами, но сервис предоставляет клиентам постоянный DNS-имя и IP-адрес (ClusterIP).

Как это работает:

  1. Вы разворачиваете Deployment с Pod'ами, помеченными лейблами (например, app: backend).
  2. Вы создаёте Service с селектором app: backend.
  3. Контроллер сервиса в Kubernetes непрерывно отслеживает Pod'ы, соответствующие селектору, и обновляет Endpoints (или более современный EndpointSlices) — список их IP-адресов и портов.
  4. Когда трафик поступает на виртуальный IP-адрес сервиса (ClusterIP), kube-proxy (работающий на каждом узле) перенаправляет его на один из живых Pod'ов из списка Endpoints, выполняя балансировку нагрузки.

Основные типы сервисов:

Тип Назначение Пример использования
ClusterIP (по умолчанию) Предоставляет внутренний IP-адрес, доступный только внутри кластера. Связь между микросервисами (backend -> database).
NodePort Открывает статический порт на каждом узле кластера. Внешний трафик на <NodeIP>:<NodePort> перенаправляется на сервис. Для тестирования или когда нет внешнего Load Balancer.
LoadBalancer Созёт внешний балансировщик нагрузки в облачном провайдере (AWS ELB, GCP Load Balancer). Автоматически создаёт NodePort и ClusterIP. Публикация веб-сервиса в интернет.
ExternalName Маппит сервис на DNS-имя, указанное в spec.externalName. Не использует проксирование. Предоставление внешнего сервиса (например, БД вне кластера) под внутренним DNS-именем.

Пример манифеста Service типа ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: backend-api # Селектор для поиска Pod'ов
    tier: api
  ports:
    - name: http
      protocol: TCP
      port: 80       # Порт, на котором сервис доступен внутри кластера
      targetPort: 8080 # Порт контейнера в Pod'е, на который будет перенаправлен трафик
  type: ClusterIP

Дополнительные возможности, важные для DevOps:

  • Headless Service: Если установить clusterIP: None, сервис не получит ClusterIP. DNS-запрос вернёт все IP-адреса Pod'ов напрямую. Используется для StatefulSet (например, кластеры БД).
  • Session Affinity: sessionAffinity: ClientIP позволяет направлять запросы от одного клиента на один и тот же Pod.
  • Readiness Probes и Service: Сервис направляет трафик только на Pod'ы, у которых readiness probe успешна. Это обеспечивает плавный запуск и обновление приложений.