Как обратиться к внешнему IP-адресу Load Balancer сервиса через Ingress-контроллер в Kubernetes

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

Ответ

Обращение происходит через единую точку входа — внешний IP или DNS-имя LoadBalancer-сервиса самого Ingress-контроллера. Внутри кластера Ingress-контроллер маршрутизирует трафик на соответствующие backend-сервисы на основе правил, описанных в ресурсах Ingress.

Типичная архитектура:

  1. Ingress-контроллер (например, ingress-nginx) развернут как Deployment.
  2. К этому Deployment'у привязан Service типа LoadBalancer.
  3. Облачный провайдер (AWS ELB, GCP Load Balancer, Azure LB) или MetalLB в on-prem среде назначают этому сервису внешний IP-адрес.
  4. Пользователь или DNS обращается к этому внешнему IP.
  5. Ingress-контроллер анализирует HTTP-запрос (Host header, путь) и направляет его на внутренний ClusterIP-сервис вашего приложения, указанный в правиле Ingress.

Пример манифестов:

Сервис Ingress-контроллера (LoadBalancer):

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx

Ресурс Ingress для приложения:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx # Указываем класс контроллера
  rules:
  - host: app.mycompany.com # Домен, по которому доступно приложение
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-api-service # Внутренний сервис приложения
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-web-service
            port:
              number: 80

Как это работает на практике:

  1. После применения манифестов получаем внешний IP:
    kubectl get svc -n ingress-nginx ingress-nginx-controller
    # NAME                         TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)
    # ingress-nginx-controller   LoadBalancer   10.96.45.211   203.0.113.100   80:32678/TCP,443:31484/TCP
  2. Настраиваем DNS-запись app.mycompany.com, указывающую на IP 203.0.113.100.
  3. Запрос http://app.mycompany.com/api/users попадает на IP 203.0.113.100:80, его принимает ingress-nginx.
  4. Контроллер, видя Host app.mycompany.com и путь /api, перенаправляет запрос на порт 8080 внутреннего сервиса backend-api-service.

Важно: Для HTTPS необходимо настроить TLS-терминацию на Ingress-контроллере, указав секрет с сертификатом в спецификации Ingress (tls секция).