Как Kubernetes определяет, куда отправлять запрос

«Как Kubernetes определяет, куда отправлять запрос» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Маршрутизация трафика в Kubernetes строится на нескольких абстракциях. Основной механизм для внутренней коммуникации — Service.

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

  1. Service — это абстракция, определяющая логический набор Pod (обычно через селектор selector) и политику доступа к ним.
  2. При создании Service с типом ClusterIP (по умолчанию) Kubernetes назначает ему статический виртуальный IP-адрес внутри кластера.
  3. Компонент kube-proxy, работающий на каждом узле, отслеживает изменения Service и Pod. Для каждого Service он настраивает правила (через iptables, ipvs или userspace), которые перенаправляют трафик с виртуального IP Service на IP-адреса реальных Pod.
  4. Когда Pod отправляет запрос на DNS-имя или IP Service, эти правила перехватывают пакет и балансируют нагрузку между всеми доступными Pod, соответствующими селектору Service. Алгоритм балансировки по умолчанию — случайный (не строгий round-robin).

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

apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend  # Ищет Pod с меткой app=backend
  ports:
    - port: 80       # Порт, на котором Service доступен внутри кластера
      targetPort: 8080 # Порт контейнера в Pod, на который будет перенаправлен трафик
  type: ClusterIP

Для внешнего входящего трафика используются:

  • Service типа LoadBalancer или NodePort — предоставляет внешний IP или порт на узлах.
  • Ingress — более интеллектуальный маршрутизатор уровня 7 (HTTP/HTTPS). Ingress-контроллер (например, Nginx Ingress) читает правила из ресурса Ingress (хосты, пути) и перенаправляет трафик на соответствующие внутренние Service.

Пример простого Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: backend-service # Трафик идёт на этот Service
            port:
              number: 80