Для реализации прикладного балансировщика нагрузки (Application Load Balancer, ALB) средствами Kubernetes Gateway API используется модуль alb.

Модуль alb реализует прикладной балансировщик нагрузки и позволяет публиковать приложения с помощью Kubernetes Gateway API. Он разворачивает и настраивает инфраструктуру для приёма и маршрутизации внешних запросов, а также проверяет пользовательскую конфигурацию Gateway API.

ALB средствами Kubernetes Gateway API может использоваться в кластере совместно с ALB средствами Ingress NGINX Controller. О совместном использовании с другими модулями и сторонними решениями читайте в разделе «Совместное использование с другими модулями и сторонними решениями».

Обзор и схема

Модуль построен на Kubernetes Gateway API — API маршрутизации входящего трафика, расширяющий модель Ingress API. Объект ClusterALBInstance или ALBInstance создаёт управляемый Gateway. К Gateway привязывается ListenerSet, который описывает обработчики входящих запросов. Маршруты направляют трафик к сервисам приложений.

Схема прохождения трафика Gateway API

Модуль поддерживает:

  • единый декларативный API для HTTP/HTTPS, gRPC, TCP, UDP и TLS passthrough;
  • разделение ответственности между администратором кластера (ClusterALBInstance или ALBInstance), администратором неймспейса (ALBInstance и ListenerSet — hostname, TLS, порты) и разработчиками приложения (маршруты);
  • обработку запросов: WAF на уровне маршрута, внешнюю аутентификацию, списки разрешённых IP-адресов, ограничение частоты запросов, закрепление сессии (session affinity), GeoIP, BackendTLSPolicy, Proxy Protocol и HTTP/3.

Kubernetes Gateway API и API Gateway — разные понятия. Kubernetes Gateway API — это набор ресурсов Kubernetes для описания маршрутизации трафика к приложениям. API Gateway — архитектурный компонент, предоставляющий единую точку входа к API приложений. Модуль alb реализует Kubernetes Gateway API.

Сравнение возможностей модулей alb и ingress-nginx приведено в разделе «Сравнение возможностей модулей ingress-nginx и alb».

Роли объектов

Gateway API разделяет ответственность между администраторами кластера и неймспейса и разработчиками приложений:

  • Администратор кластера — управляет инфраструктурой приёма трафика через ClusterALBInstance или ALBInstance (общекластерный Gateway).
  • Администратор неймспейса — управляет ALBInstance и ListenerSet (hostname, TLS, порты) в неймспейсе.
  • Разработчики приложения — задают маршруты (HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute).

Зачем нужен ListenerSet

ListenerSet — расширение Gateway API. Объект ListenerSet описывает системные и пользовательские обработчики трафика: имя хоста, режим TLS, порт и протокол. Каждый ListenerSet связывается с родительским Gateway через spec.parentRef. Затем к нему подключаются маршруты.

Каждый объект Gateway по умолчанию создаёт два обработчика: d8-http (порт 80) и d8-https (порт 443). Они предназначены для служебных целей — например, для проверки доступности шлюза или работы cert-manager (HTTP-01). Для публикации приложений эти обработчики использовать не рекомендуется. Используйте ListenerSet.

ClusterALBInstance и ALBInstance

При создании управляемого объекта Gateway для публикации пользовательских приложений используются кастомные ресурсы ClusterALBInstance (общекластерный объект) и ALBInstance (объект в неймспейсе).

Особенности и разница между ними описаны в таблице:

  ClusterALBInstance ALBInstance
Назначение Развёртывание общекластерного Gateway Развёртывание Gateway в неймспейсе
Сценарии использования - Общая точка входа (общекластерный шлюз).
- Системный шлюз для публикации веб-интерфейсов служебных компонентов Deckhouse Platform (DP) и других модулей (может требоваться «Действия перед включением и настройкой ALB в кластере»).
- Платформенный шлюз
Отдельный шлюз для приложения или команды в выделенном неймспейсе
Поддерживаемые типы инлета LoadBalancer, HostPort LoadBalancer, ClusterIP
Реализация прокси Envoy Proxy Envoy Proxy
Тип развёртывания DaemonSet Deployment
Локализация объектов ListenerSet и маршрутов В любом пользовательском неймспейсе В том же неймспейсе, что и объект ALBInstance (обязательно)
Права доступа Администратор кластера Администратор неймспейса

После создания ClusterALBInstance или ALBInstance в кластере появляется управляемый объект Gateway (шлюз). При этом:

  • Каждый объект Gateway обслуживается как минимум одним экземпляром Envoy Proxy.
  • Трафик в него приходит через сервис с типом LoadBalancer или напрямую с использованием параметров HostPort.
  • На один объект Gateway могут ссылаться несколько объектов ClusterALBInstance или ALBInstance через поле gatewayName. В этом случае они используют общий Gateway. Конфигурация инфраструктуры для приёма и обработки трафика при этом может различаться. Поле gatewayName можно рассматривать как аналог ingressClass для объектов IngressNginxController. Итоговая конфигурация берётся из инстанса с наиболее ранним creationTimestamp (то есть созданного раньше остальных). У остальных инстансов в статусе устанавливается conflictPorts: true, а в conflictPortsOwner указывается имя «управляющего» инстанса.

Валидация конфигурации

Помимо настройки инфраструктуры Gateway API выполняется проверка пользовательских настроек перед применением, чтобы не допустить конфликта. Это позволяет выявлять конфликты между одинаковыми обработчиками трафика в разных объектах ListenerSet, если они ссылаются на один и тот же объект Gateway.

Инлеты

Инлет определяет, как внешний трафик попадает на Envoy Proxy, обслуживающий объект Gateway:

  • LoadBalancer — приём трафика через сервис с типом LoadBalancer (облачные провайдеры или bare metal с MetalLB). Доступен и для ClusterALBInstance, и для ALBInstance.
  • HostPort — приём трафика на портах узлов без внешнего балансировщика. Доступен только для ClusterALBInstance.
  • ClusterIP — приём трафика через сервис с типом ClusterIP, без внешней точки входа (например, для внутреннего трафика). Доступен только для ALBInstance.

Таблица соответствия типов инлета при миграции с ingress-nginx — в разделе «Настройка инлета». Подробные примеры — в разделе «Примеры для разных окружений».

Как настроить ALB

Публикация приложения предполагает включение модуля, создание управляемого Gateway, ListenerSet и маршрутов.

Действия перед включением и настройкой ALB в кластере

Перед включением и настройкой ALB в кластере DP выполните следующее:

  • Проверьте выполнение требований к работе модуля alb.
  • Если нужно публиковать служебные домены — веб-интерфейсы служебных компонентов DP и других модулей, — укажите глобальный параметр publicDomainTemplate. Без этого параметра системные объекты HTTPRoute, Gateway и ListenerSet для служебных доменов не будут работать корректно, и веб-интерфейсы не опубликуются. Если публикация служебных доменов не требуется, параметр можно не указывать. Подробности — в разделе «Публикация служебных доменов».
  • Проверьте совместимость версий API в разделе «Совместно со сторонними реализациями Gateway API», если такие решения уже используются в кластере.
  • На bare metal для инлета LoadBalancer подготовьте внешний балансировщик или модуль metallb. Инлет HostPort доступен только для ClusterALBInstance и не требует MetalLB.

Включение модуля и создание Gateway

Включите модуль alb, как описано в разделе «Включение модуля».

Создайте ClusterALBInstance или ALBInstance. Это приведёт к созданию и настройке управляемого объекта Gateway.

Ручная модификация объектов Gateway, управляемых модулем, не допускается.

  • ClusterALBInstance
  • ALBInstance

Пример манифеста ClusterALBInstance для создания общекластерного шлюза:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: public-gw
spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}

Пример минимальной рабочей конфигурации ALBInstance для публикации шлюза в неймспейсе:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: app-gw
  namespace: prod
spec:
  gatewayName: app-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}

После перехода ALBInstance в состояние Ready создайте в том же неймспейсе объекты ListenerSet и HTTPRoute. Порядок их настройки и пример публикации приложения приведены в разделе «Публикация приложения с ListenerSet и HTTPRoute».

Создание ListenerSet

Объект ListenerSet описывает системные и пользовательские обработчики трафика: имя хоста, режим TLS, порт и протокол. Каждый ListenerSet связывается с родительским Gateway через spec.parentRef. Затем к нему подключаются маршруты.

Расположение объектов ListenerSet зависит от используемого типа объекта Gateway:

  • Для ClusterALBInstance объекты ListenerSet могут располагаться в любом неймспейсе.
  • Для ALBInstance объекты ListenerSet должны располагаться в том же неймспейсе, что и родительский ALBInstance.

В обоих случаях рекомендуется размещать ListenerSet в одном неймспейсе со связанными объектами HTTPRoute, GRPCRoute и TLSRoute. В этом случае дополнительные настройки, например создание ReferenceGrant, не требуются.

В ListenerSet для HTTP/HTTPS указывайте порты 80 и 443. Это порты слушателей Gateway API. Они не совпадают с параметрами hostPort.httpPort и hostPort.httpsPort инлета HostPort, которые задают порты на узле.

Объекты TCPRoute и UDPRoute, использующие TCP и UDP-порты из additionalPorts, привязываются непосредственно к соответствующему слушателю объекта Gateway.

Пример манифеста ListenerSet для управления приёмом входящих HTTP и HTTPS-запросов через общекластерный шлюз:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: app-listeners
  namespace: prod
spec:
  parentRef:
    name: public-gw   # Имя общекластерного Gateway из status ClusterALBInstance.
    namespace: d8-alb
  listeners:
    - name: app-http
      port: 80 # В ListenerSet для HTTP указывайте порт 80. Это не параметр hostPort.httpPort инлета HostPort на узле.
      protocol: HTTP
      hostname: app.example.com
    - name: app-https
      port: 443 # В ListenerSet для HTTPS указывайте порт 443. Это не параметр hostPort.httpsPort инлета HostPort на узле.
      protocol: HTTPS
      hostname: app.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-tls   # Наименование объекта Secret, содержащего необходимый TLS-сертификат.
            namespace: prod

Создание маршрутов

Для маршрутизации входящих запросов используются следующие типы маршрутов:

  • HTTPRoute — для маршрутизации HTTP/HTTPS/TLS запросов. Объекты HTTPRoute поддерживают расширенные настройки с помощью аннотаций, которые дополняют текущую спецификацию Gateway API.
  • GRPCRoute — для маршрутизации gRPC-трафика.
  • TLSRoute — для сквозной маршрутизации TLS-трафика.
  • TCPRoute — для маршрутизации TCP-трафика. Для TCP-портов из additionalPorts объект TCPRoute привязывается напрямую к слушателю Gateway, а не к ListenerSet.
  • UDPRoute — для маршрутизации UDP-трафика. Для UDP-портов из additionalPorts объект UDPRoute привязывается напрямую к слушателю Gateway, а не к ListenerSet.

Объекты HTTPRoute, GRPCRoute и TLSRoute привязываются к ListenerSet. TCPRoute и UDPRoute для TCP/UDP-портов из additionalPorts привязываются напрямую к слушателю объекта Gateway.

Пример создания HTTPRoute для HTTP и HTTPS-трафика и другие сценарии публикации — в разделе «Публикация приложения с ListenerSet и HTTPRoute».

Публикация служебных доменов

Если нужно публиковать служебные домены, укажите глобальный параметр publicDomainTemplate — без него системные объекты HTTPRoute/Gateway/ListenerSet для служебных доменов не будут работать корректно, и веб-интерфейсы служебных компонентов DP и других модулей не будут опубликованы. Если публикация служебных доменов не нужна, параметр можно не указывать.

Для предоставления доступа к служебным доменам кластера DP укажите шлюз по умолчанию. Создайте ClusterALBInstance с нужным типом инлета и настройками и установите для него параметр spec.defaultDeckhouseGateway: true.

Пример манифеста ClusterALBInstance с параметром spec.defaultDeckhouseGateway: true:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: public-gw
spec:
  gatewayName: public-gw
  defaultDeckhouseGateway: true
  inlet:
    type: LoadBalancer
    loadBalancer: {}

После применения изменений проверьте статус ClusterALBInstance:

d8 k get clusteralbinstances

ClusterALBInstance должен перейти в состояние Ready и создать управляемый Gateway. После этого в соответствующих системных неймспейсах появятся ListenerSet и HTTPRoute.

В настоящее время не все модули DP доступны через Gateway API. Не отключайте модуль ingress-nginx и не удаляйте связанные с ним объекты, пока необходимые веб-интерфейсы не будут опубликованы через Gateway API и не пройдут проверку.

После настройки шлюза по умолчанию выполните следующую команду, чтобы увидеть, какие модули уже опубликовали служебные HTTPRoute через Gateway API в этом кластере. Команда показывает фактический список уже опубликованных маршрутов, а не полный перечень возможностей платформы:

d8 k get httproutes -A -l heritage=deckhouse -o json \
  | jq -r '
["MODULE","GATEWAY API SUPPORT"],
(.items
  | map(.metadata.labels.module // "UNKNOWN")
  | unique[]
  | ["d8-" + ., "yes"])
| @tsv
' \
  | column -t -s $'\t'

Выбор шлюза DP по умолчанию при использовании нескольких ClusterALBInstance

В кластере может быть одновременно несколько общекластерных Gateway, помеченных как шлюз по умолчанию (флаг spec.defaultDeckhouseGateway: true в параметрах соответствующих ClusterALBInstance). В этом случае шлюзом по умолчанию становится Gateway, созданный объектом ClusterALBInstance с наиболее ранним creationTimestamp (то есть созданный раньше остальных).

Если ни один объект ClusterALBInstance не отмечен как шлюз по умолчанию, DP допускает использование объекта Gateway, созданного модулем alb для инстанса ClusterALBInstance с именем main.

Смена шлюза DP по умолчанию

Если системные домены DP необходимо перевести на обслуживание другим объектом Gateway, выполните следующие шаги:

  1. Создайте новый объект ClusterALBInstance, описывающий необходимые настройки, и задайте в нём параметр spec.defaultDeckhouseGateway: true.
  2. В текущем объекте ClusterALBInstance, который предоставляет шлюз DP по умолчанию, задайте spec.defaultDeckhouseGateway: false.
  3. Проверьте, что все системные объекты ListenerSet теперь ссылаются на новый объект Gateway в spec.parentRef.

Примеры для разных окружений

В этом разделе описаны приём трафика в разных окружениях и операции с уже развёрнутым ALB. Полное описание полей кастомных ресурсов приведено в документации ClusterALBInstance и ALBInstance. Дополнительные примеры — в примерах модуля alb.

  • Облачный провайдер
  • Bare metal с MetalLB
  • Bare metal с HostPort
  • Внешний L7-балансировщик

Пример ClusterALBInstance с инлетом LoadBalancer для облачного провайдера:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: main
spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}

Чтобы настроить облачный балансировщик, укажите необходимые аннотации для создаваемого объекта Service типа LoadBalancer в параметре spec.inlet.loadBalancer.serviceAnnotations. Пример использования Network Load Balancer (NLB) в AWS:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: main
spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer:
      serviceAnnotations:
        service.beta.kubernetes.io/aws-load-balancer-type: "nlb"

Чтобы принимать трафик на bare metal с помощью балансировщика MetalLB, включите модуль metallb и создайте объект MetalLoadBalancerClass с пулом адресов. Разместите балансировщики MetalLB на тех же узлах, что и поды Envoy Proxy модуля alb (обычно frontend-узлы с лейблом node-role.deckhouse.io/frontend):

apiVersion: network.deckhouse.io/v1alpha1
kind: MetalLoadBalancerClass
metadata:
  name: alb
spec:
  addressPool:
    - 192.168.2.100-192.168.2.150
  isDefault: false
  nodeSelector:
    node-role.deckhouse.io/frontend: ""
  type: L2

Затем создайте объект ClusterALBInstance и укажите spec.inlet.loadBalancer.loadBalancerClass:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: main
spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer:
      loadBalancerClass: alb
      serviceAnnotations:
        # Число адресов, выделяемых из пула MetalLoadBalancerClass.
        network.deckhouse.io/l2-load-balancer-external-ips-count: "1"

Пример ClusterALBInstance с инлетом HostPort для bare metal без внешнего балансировщика:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: main
spec:
  gatewayName: public-gw
  inlet:
    type: HostPort
    hostPort:
      httpPort: 80
      httpsPort: 443

Чтобы поды Envoy Proxy размещались только на выделенных узлах, задайте nodeSelector и tolerations для ClusterALBInstance.

Если модуль alb работает за внешним L7-балансировщиком (например, Cloudflare или Qrator), включите useProxyProtocol, чтобы получать реальные адреса клиентов. Дополнительно ограничьте с помощью spec.originalIPDetection список подсетей, из которых разрешено доверять заголовкам с адресом клиента.

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: main
spec:
  gatewayName: public-gw
  inlet:
    type: HostPort
    hostPort:
      httpPort: 80
      httpsPort: 443
  useProxyProtocol: true
  originalIPDetection:
    setRealIPFrom:
      - 10.0.0.0/16

Proxy Protocol и HTTP/3 нельзя включать одновременно: если задать оба параметра, контроллер модуля alb отклонит конфигурацию как конфликтующую.

Смена инлета с сохранением текущего Gateway

Чтобы сменить инлет, используемый для уже созданного объекта Gateway, выполните следующие действия:

  1. Создайте новый объект ClusterALBInstance или объект ALBInstance с другим именем, но с тем же значением spec.gatewayName, используя нужный тип инлета.
  2. Проверьте, что новый путь приёма трафика работает корректно.
  3. Удалите неактуальный объект ClusterALBInstance или объект ALBInstance.

Так как gatewayName не меняется, объект Gateway остаётся прежним. В большинстве случаев объект ListenerSet и маршруты при этом можно не пересоздавать.

Открытие дополнительного TCP/UDP-порта на общекластерном Gateway

Если кроме стандартных HTTP/HTTPS-слушателей на шлюзе нужен отдельный TCP/UDP-порт, добавьте в соответствующий ClusterALBInstance поле spec.inlet.additionalPorts, например:

spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}
    additionalPorts:
      - port: 9000
        protocol: TCP

Контроллер добавит в управляемый объект Gateway слушатель TCP/UDP-трафика с именем секции (sectionName), например, tcp-port-9000. Чтобы привязать к нему TCPRoute, укажите в маршруте имя Gateway и соответствующее значение sectionName:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: app-tcp
  namespace: prod
spec:
  parentRefs:
    - name: public-gw
      namespace: d8-alb
      sectionName: tcp-port-9000
      port: 9000
  rules:
    - backendRefs:
        - name: tcp-svc
          port: 9000

Если объект TCPRoute или UDPRoute создаётся в неймспейсе, отличном от неймспейса целевого Gateway, дополнительно создайте в неймспейсе Gateway объект ReferenceGrant, разрешающий ссылки из неймспейса маршрута.

Примеры UDPRoute и шаги публикации приложений — в разделе «Работа с объектами GRPCRoute, TLSRoute, TCPRoute и UDPRoute».

Разделение публичной и административной зон

Для публичного и административного трафика можно использовать отдельные объекты Gateway. Это позволяет задать для каждой зоны отдельную точку входа и собственные правила доступа. Такой подход аналогичен использованию отдельного Ingress NGINX Controller и IngressClass для административной зоны.

Создайте отдельный объект Gateway для каждой зоны и ограничьте приём административного трафика с помощью spec.acceptRequestsFrom. Решение о допуске соединения принимается по реальному адресу подключения, а не по заголовкам запроса.

Пример создания двух объектов ClusterALBInstance — для публичной и административной зон:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: public
spec:
  gatewayName: public-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}
---
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: admin
spec:
  gatewayName: admin-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}
  acceptRequestsFrom:
    - 1.2.3.4/32
    - 10.0.0.0/16

Далее для каждого шлюза создайте отдельные объекты ListenerSet и маршруты. Примеры публикации приложений приведены в разделе «Публикация приложения с ListenerSet и HTTPRoute».

Публикация в неймспейсе (ALBInstance)

Пример минимальной рабочей конфигурации ALBInstance для публикации шлюза в неймспейсе:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: app-gw
  namespace: prod
spec:
  gatewayName: app-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}

После перехода ALBInstance в состояние Ready создайте в том же неймспейсе объекты ListenerSet и HTTPRoute. Порядок их настройки и пример публикации приложения приведены в разделе «Публикация приложения с ListenerSet и HTTPRoute».

Выпуск TLS-сертификатов с cert-manager

Модуль alb использует cert-manager для автоматического выпуска TLS-сертификатов. Слушатели d8-http и d8-https обслуживают запросы HTTP-01 (HTTP-01 challenge) при выпуске сертификата. Чтобы выпустить сертификат для приложения, создайте объект Certificate, который сохранит сертификат в Secret, и укажите этот Secret в certificateRefs соответствующего ListenerSet.

Пример сертификата, который создаёт Secret app-tls для ListenerSet:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-tls
  namespace: prod
spec:
  secretName: app-tls
  issuerRef:
    name: letsencrypt
    kind: ClusterIssuer
  dnsNames:
    - app.example.com

Сертификаты выпускает модуль cert-manager. Если модуль alb используется вместе с ingress-nginx, используйте отдельный ClusterIssuer для каждого типа ALB, как описано в разделе «Совместно с ingress-nginx».

Совместное использование с другими модулями и сторонними решениями

ALB средствами Kubernetes Gateway API в кластере DP можно использовать совместно с ALB средствами Ingress NGINX Controller, а также с ALB на основе сторонних решений Gateway API. Пошаговый переход — в разделе «Миграция с ingress-nginx на alb».

Совместно с ingress-nginx

ALB средствами Kubernetes Gateway API может использоваться в кластере совместно с «ALB средствами Ingress NGINX Controller». В таком случае для каждого из типов ALB рекомендуется использовать отдельный объект ClusterIssuer, чтобы раздельно управлять настройками и жизненными циклами сертификатов. Один и тот же внешний hostname не должен одновременно обслуживаться обоими ALB без разделения на уровне DNS или внешнего балансировщика.

Для шлюза DP по умолчанию объект ClusterIssuer создаётся автоматически. Этот же объект ClusterIssuer используется для выпуска сертификатов системных доменов.

Совместно со сторонними реализациями Gateway API

Использование сторонних решений Gateway API допускается при условии, что в кластере используются следующие, совместимые с контроллером модуля alb, версии API для объектов Gateway API:

  • BackendTLSPolicy: v1;
  • GatewayClass: v1;
  • Gateway: v1;
  • ListenerSet: v1;
  • GRPCRoute: v1;
  • HTTPRoute: v1;
  • ReferenceGrant: v1beta1;
  • TCPRoute: v1alpha2/v1;
  • UDPRoute: v1alpha2/v1;
  • TLSRoute: v1.

Контроллер модуля alb в процессе запуска проверяет текущие хранимые версии объектов Gateway API. В случае обнаружения расхождения между установленными и требуемыми версиями контроллер прекращает работу. Если же в кластере полностью отсутствует тот или иной тип объекта Gateway API, нужная версия будет создана контроллером автоматически и он продолжит работу.

Для ручной проверки совместимости версий установленных в кластере объектов Gateway API с требуемыми версиями используйте команду:

declare -A want=(
    [gatewayclasses.gateway.networking.k8s.io]=v1
    [gateways.gateway.networking.k8s.io]=v1
    [grpcroutes.gateway.networking.k8s.io]=v1
    [httproutes.gateway.networking.k8s.io]=v1
    [listenersets.gateway.networking.k8s.io]=v1
    [referencegrants.gateway.networking.k8s.io]=v1beta1
    [tcproutes.gateway.networking.k8s.io]="v1|v1alpha2"
    [udproutes.gateway.networking.k8s.io]="v1|v1alpha2"
    [tlsroutes.gateway.networking.k8s.io]=v1
    [backendtlspolicies.gateway.networking.k8s.io]=v1
)

for crd in "${!want[@]}"; do
    got="$(
        d8 k get crd "$crd" \
          -o jsonpath='{.spec.versions[?(@.storage==true)].name}' \
          2>/dev/null || true
    )"
    if [[ -n "$got" && "$got" =~ ^(${want[$crd]})$ ]]; then
        echo "$crd OK storage=$got"
    else
        echo "$crd FAILED cluster=${got:-MISSING} expected=${want[$crd]}"
    fi
done | sort

В остальном модуль конфигурирует и управляет только объектами Gateway определённого GatewayClass, что минимизирует риск возникновения конфликтов при использовании сторонних решений Gateway API.

Включение HTTP/3

По умолчанию шлюз принимает HTTP/1.1 и HTTP/2. Чтобы включить HTTP/3, задайте spec.enableHTTP3: true в ClusterALBInstance или ALBInstance:

apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: public-gw
spec:
  gatewayName: public-gw
  enableHTTP3: true
  inlet:
    type: LoadBalancer
    loadBalancer: {}

Параметры enableHTTP3 и useProxyProtocol нельзя включать одновременно: если задать оба параметра, контроллер модуля alb отклонит конфигурацию как конфликтующую.

Учитывайте следующее:

  • HTTP/3 использует QUIC поверх UDP. Убедитесь, что балансировщик и сетевые правила пропускают UDP на порт HTTPS (обычно 443), а не только TCP.
  • Для инлета LoadBalancer проверьте, что облачный или MetalLB-балансировщик принимает UDP на нужном порту.
  • Клиенты должны поддерживать HTTP/3. Проверка с рабочей станции:
curl -vk --http3 https://app.example.com/

Если curl собран без HTTP/3, используйте клиент с поддержкой QUIC или проверьте доступность UDP-порта и журналы Envoy Proxy.

Использование GeoIP и GeoLite2

Модуль alb поддерживает добавление полей GeoIP в заголовки HTTP-запросов на основе данных баз MaxMind GeoIP/GeoLite2.

На данный момент возможно подключение следующих редакций баз:

  • GeoIP2-Anonymous-IP;
  • GeoIP2-City;
  • GeoIP2-ISP;
  • GeoIP2-ASN;
  • GeoLite2-ASN;
  • GeoLite2-City.

Текущая интеграция GeoIP поддерживает одновременное использование до 4 баз.

Выберите способ получения баз GeoIP:

  • Скачивание баз с MaxMind
  • Локальное зеркало

Для подключения GeoIP и скачивания баз непосредственно с серверов MaxMind необходимо предварительно создать Secret, содержащий лицензионный ключ, например:

d8 k -n prod create secret generic geoip-license \
  --from-literal=licenseKey='<MAXMIND_LICENSE_KEY>'

При настройке GeoIP для ClusterALBInstance Secret может быть размещён в любом неймспейсе, но рекомендуется разместить его в d8-alb.

Для объектов ALBInstance Secret должен располагаться строго в том же неймспейсе, что и объект ALBInstance.

После создания Secret укажите его в параметре spec.geoIP.licenseKeySecretRef объекта ClusterALBInstance или ALBInstance, например:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: main
  namespace: prod
spec:
  envoyLogLevel: Warning
  gatewayName: custom-gateway
  geoIP:
    licenseKeySecretRef:
      name: geoip-license

Для подключения GeoIP и скачивания баз с локального зеркала укажите его адрес в параметре spec.geoIP.maxmindMirror.url, например:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: main
  namespace: prod
spec:
  envoyLogLevel: Warning
  gatewayName: custom-gateway
  geoIP:
    maxmindMirror:
      url: "https://local.geoip:8443"

В качестве URL допускается указание адреса локального кеширующего сервера GeoIP в другом неймспейсе, например:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: main
  namespace: prod
spec:
  envoyLogLevel: Warning
  gatewayName: custom-gateway
  geoIP:
    maxmindMirror:
      url: "http://geoproxy-cluster.d8-alb.svc:8080/download"

Использование заголовков GeoIP

В результате настройки GeoIP в неймспейсе, где работают прокси ClusterALBInstance или ALBInstance, будет запущен сервер кеширования и обновления баз GeoIP. Поды Envoy Proxy затем поочерёдно перезапускаются, чтобы скачивать базы с локального сервера GeoIP.

Для добавления полей GeoIP в заголовки HTTP-запросов укажите имена HTTP-заголовков в параметре spec.geoIP.headers, например:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: main
  namespace: prod
spec:
  envoyLogLevel: Warning
  gatewayName: custom-gateway
  geoIP:
    headers:
      city: geoip_city
      country: geoip_country
    licenseKeySecretRef:
      name: geoip-license
    maxmindEditionIDs:
      - GeoLite2-City

Обновление баз GeoIP осуществляется раз в сутки: сначала на кеширующем сервере, а затем в каждом отдельном поде Envoy Proxy, который обращается к этому серверу.

Параметр storageClass модуля alb задаёт PVC для компонентов GeoIP.

Настройка трассировки OpenTelemetry

Модуль alb поддерживает экспорт трассировок OpenTelemetry из Envoy Proxy.

Для включения экспорта укажите адрес OpenTelemetry Collector в параметре spec.openTelemetry.tracing.url — в формате http://, https:// или grpc://, с указанием хоста, порта и, при необходимости, пути (например, для OTLP/HTTP).

Долю запросов, которые Envoy Proxy случайно выбирает для трассировки, задаёт параметр randomSamplingPercentage (по умолчанию — 25%).

При необходимости настройте подключение с использованием TLS.

При использовании TLS рекомендуется явно задать параметр sni, если OpenTelemetry Collector находится за прокси или балансировщиком, который выбирает upstream на основе Server Name Indication.

Настройка TLS для OpenTelemetry

Чтобы передавать данные трассировки OpenTelemetry по TLS, создайте Secret с CA-сертификатом и укажите его в параметре spec.openTelemetry.tracing.tls.caSecretName.

  • Для ClusterALBInstance или шлюза DP по умолчанию разместите секрет в неймспейсе d8-alb.
  • Для ALBInstance разместите Secret в том же неймспейсе, что и объект ALBInstance.

CA-сертификат должен быть сохранён в ключе cacert. Дополнительные Subject Alternative Names для проверки сертификата OpenTelemetry Collector задаются параметром subjectAltNames, а параметр insecureSkipVerify отключает эту проверку.

apiVersion: v1
kind: Secret
metadata:
  name: otel-tracing-ca
  namespace: d8-alb
type: Opaque
stringData:
  cacert: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
---
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
  name: proxy-gw
spec:
  gatewayName: proxy-gw
  inlet:
    type: LoadBalancer
    loadBalancer: {}
  openTelemetry:
    tracing:
      url: https://otel-collector.monitoring.svc.cluster.local:4318/v1/traces
      tls:
        sni: otel-collector.monitoring.svc.cluster.local
        caSecretName: otel-tracing-ca

Диагностика и проверка

В этом разделе — проверка готовности шлюза и типичные вопросы при первой настройке. Дополнительные сценарии — в «FAQ модуля alb».

  • После создания ClusterALBInstance или ALBInstance дождитесь состояния Ready и возьмите имя и неймспейс Gateway из status. Описание полей — в ClusterALBInstance status и ALBInstance status:

    d8 k get clusteralbinstance
    d8 k -n <NAMESPACE> get albinstance
    d8 k -n d8-alb get gateway
    
  • При инлете LoadBalancer возьмите адрес у сервиса балансировщика (обычно в неймспейсе d8-alb) и укажите его в DNS для hostname из ListenerSet:

    d8 k -n d8-alb get svc
    
  • Проверьте, не используется ли один и тот же hostname для двух ALB. Модули alb и ingress-nginx могут работать в одном кластере, но один и тот же внешний hostname не должен одновременно обслуживаться двумя ALB без явного разделения на уровне DNS или внешнего балансировщика.

  • Проверьте, нет ли конфликта в объектах ListenerSet. Если два ListenerSet с одинаковыми обработчиками ссылаются на один Gateway, контроллер отклонит конфликтующую конфигурацию. Измените hostname, порт или протокол либо удалите дублирующий ListenerSet.

  • Для диагностики, можно просмотреть конфигурацию, переданную контроллером и конфигуратором прокси в Envoy Proxy, обслуживающий объект Gateway.

    1. Выберите под Envoy Proxy для нужного объекта Gateway:

      d8 k -n d8-alb get pods -l alb.deckhouse.io/gateway=shared-gateway
      
    2. Получите конфигурацию пода с помощью команды (вместо <ENVOY_PROXY_POD_NAME> используйте имя пода Envoy Proxy, полученное на предыдущем шаге):

      d8 k -n d8-alb exec -it <ENVOY_PROXY_POD_NAME> -- pilot-agent request GET /config_dump
      

      Если нужен только отдельный раздел конфигурации, явно укажите его:

      d8 k -n d8-alb exec -it <ENVOY_PROXY_POD_NAME> -- pilot-agent request GET /config_dump?resource=dynamic_listeners
      d8 k -n d8-alb exec -it <ENVOY_PROXY_POD_NAME> -- pilot-agent request GET /config_dump?resource=dynamic_route_configs
      d8 k -n d8-alb exec -it <ENVOY_PROXY_POD_NAME> -- pilot-agent request GET /config_dump?resource=dynamic_active_clusters
      

    Так можно проверить, появились ли ожидаемые обработчики трафика, виртуальные хосты и upstream-кластеры после изменения объекта ListenerSet или объекта Route.

Дополнительные ресурсы