В чем разница между headless-сервисом и обычным сервисом (например, ClusterIP) в Kubernetes?

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

Ответ

Основное отличие — в модели доступа и балансировки нагрузки.

Обычный сервис (например, ClusterIP):

  • Служит единой точкой входа (статический виртуальный IP-адрес) для группы подов.
  • Выполняет балансировку нагрузки (по умолчанию, round-robin) между подами.
  • DNS-имя сервиса резолвится в этот один виртуальный IP.
  • Идеален для stateless-приложений (веб-серверы, API), где любой под может обработать запрос.

Headless-сервис (Headless Service): Создается путем установки clusterIP: None в спецификации.

  • Не имеет виртуального IP-адреса и не балансирует нагрузку.
  • Его DNS-имя возвращает список всех A-записей (IP-адресов) подов, отобранных селектором сервиса.
  • Позволяет клиенту подключаться напрямую к конкретному поду, что критически важно для stateful-приложений.

Пример использования для StatefulSet (например, база данных):

# Headless Service для кластера PostgreSQL
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  clusterIP: None  # Делаем сервис headless
  selector:
    app: postgres
  ports:
  - port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"  # StatefulSet привязан к этому headless-сервису
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15

Что это дает:

  • Каждый под получает стабильное DNS-имя: postgres-0.postgres.default.svc.cluster.local, postgres-1.postgres... и т.д.
  • Запрос nslookup postgres.default.svc.cluster.local вернет все 3 IP-адреса подов.
  • Приложение может использовать эту информацию для прямого подключения к мастер-ноде (postgres-0) или для организации репликации между инстансами. Я использовал headless-сервисы для развертывания кластеров Redis Sentinel и Elasticsearch, где каждый инстанс должен знать обо всех остальных.