Чем отличаются ClusterIP, NodePort и LoadBalancer?

Ключевые отличия ClusterIP, NodePort и LoadBalancer

ClusterIP — внутренняя абстракция L4: даёт стабильный IP и DNS-имя внутри кластера, маршрутизирует трафик между Pod-ами.
NodePort — расширение ClusterIP: дополнительно открывает фиксированный порт на каждом узле кластера, позволяя обращаться к сервису по nodeIP:nodePort снаружи кластера.
LoadBalancer — облачная (или сторонняя) интеграция: просит облако создать внешний балансировщик и связать его с ClusterIP/NodePort, чтобы обслуживать внешний трафик через провайдерский LB.

Поведение и сетевой путь (упрощённо)

  • ClusterIP: клиент в кластере → ClusterIP → kube-proxy (iptables/IPVS) → один из Pod'ов (endpoint).

  • NodePort: внешний клиент → nodeIP:nodePort на любой ноде → kube-proxy → ClusterIP → Pod.

  • LoadBalancer: внешний клиент → облачный LB (публичный IP/DNS) → (обычно) NodePort/ClusterIP → Pod. На облаках LB автоматически создаёт backend и health checks.

Технические отличия и параметры

  • **Область доступа:
    **

    • ClusterIP — только внутри кластера (службы, CronJob, другие поды).

    • NodePort — доступна снаружи по адресу любой ноды + порт.

    • LoadBalancer — внешний (или internal) публичный/приватный IP, управляемый провайдером.

  • **Порт:
    **

    • ClusterIP — порт сервиса внутри кластера.

    • NodePort — порт из диапазона (по умолчанию 30000–32767), используется на всех нодах.

    • LoadBalancer — обычно маппит frontend-порт LB на backend (NodePort/ClusterIP).

  • **Preserve client IP:
    **

    • По умолчанию при externalTrafficPolicy: Cluster исходный IP может быть потерян (или скрыт за node IP + X-Forwarded-For если L7).

    • externalTrafficPolicy: Local сохраняет исходный IP (LB направляет трафик только на ноды с локальными Pod и health check). Требует достаточного покрытия нод с Pod.

  • **Health checks:
    **

    • Cloud LB использует health checks; обычно проверяет NodePort/health path на нодах. При Local важно, чтобы ноды с Pod отвечали на проверки.
  • **Имплементация:
    **

    • ClusterIP/NodePort реализует kube-proxy (iptables/IPVS).

    • LoadBalancer приводит к созданию облачного ресурса (AWS ELB/ALB, GCP LB, Azure LB) или MetalLB для on-prem.

Примеры YAML

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

kind: Service
apiVersion: v1
metadata:
name: web-clusterip
spec:
selector: { app: web }
ports:
\- port: 80
targetPort: 8080
type: ClusterIP
NodePort:
spec:
type: NodePort
ports:
\- port: 80
targetPort: 8080
nodePort: 31234 # необязательно, если не указывать — выберется диапазон
LoadBalancer:
spec:
type: LoadBalancer
ports:
\- port: 80
targetPort: 8080

# в облаках можно добавить annotations: service.beta.kubernetes.io/...

Когда что использовать (практические рекомендации)

  • ClusterIP — внутренняя коммуникация микросервисов; всегда предпочтителен для внутреннях API.

  • NodePort — быстрый тестовый доступ извне, bootstrap в облаках без LB, или когда нужно пробросить трафик через фаервол/нат. На прод лучше не экспонировать напрямую.

  • LoadBalancer — публичные сервисы в облаке: предоставляет управляемый IP/DNS, health checks, SSL offload (в некоторых случаях). Для on-prem можно использовать MetalLB.

Ограничения и подводные камни

  • NodePort открывает порт на всех нодах — риск безопасности и конфликтов портов; диапазон ограничен.

  • LoadBalancer стоит денег и может вносить задержку; провайдерские аннотации и поведение различаются между облаками.

  • externalTrafficPolicy: Local уменьшает балансировку по кластеру и требует распределённых Pod по нодам, иначе LB может направлять трафик на ноды без Pod (и health checks отфильтруют их).

  • Для L7-фич (path, host routing, TLS termination) лучше Ingress / Ingress Controller поверх ClusterIP/LoadBalancer.

Security и наблюдаемость

  • Для внешних сервисов ставьте WAF/CDN перед LB, используйте NetworkPolicy/NSG и firewall rules.

  • Логи LB + kube-proxy/iptables/endpoint metrics + readiness probes важны для корректного health-management.