Стадия жизненного цикла модуля: Preview
У модуля есть требования для установки

В этом разделе приведены базовые примеры публикации приложений через модуль alb.

Публикация приложения через объект ClusterALBInstance

Этот сценарий предполагает, что объект ClusterALBInstance уже создан администратором кластера и перешёл в состояние Ready. Имя и неймспейс управляемого объекта Gateway нужно взять из поля status объекта ClusterALBInstance.

Затем создайте объект ListenerSet, который будет привязан к нужному Gateway (параметр spec.parentRef.name) и объекты (маршруты) HTTPRoute для маршрутизации входящих запросов к приложению. Пример:

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 # Для HTTP трафика необходимо указывать 80 порт.
      protocol: HTTP
      hostname: app.example.com
    - name: app-https
      port: 443 # Для HTTPS трафика необходимо указывать 443 порт.
      protocol: HTTPS
      hostname: app.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-tls   # Наименование секрета, содержащего необходимый TLS-сертификат.
            namespace: prod
---
# Маршрут для HTTP-трафика
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-http-route
  namespace: prod
spec:
  parentRefs:
    - name: app-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: app-http
      port: 80
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: app-svc # Наименование сервиса приложения.
          port: 8080
---
# Маршрут для HTTPS-трафика
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-https-route
  namespace: prod
spec:
  parentRefs:
    - name: app-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: app-https
      port: 443
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: app-svc # Наименование сервиса приложения
          port: 8080

Публикация приложения через объект ALBInstance

В этом сценарии объекты ALBInstance, Gateway, ListenerSet и HTTPRoute находятся в одном неймспейсе.

Для публикации приложения через объект ALBInstance выполните следующие действия:

  1. Создайте объект ALBInstance с учетом необходимых настроек:

    apiVersion: network.deckhouse.io/v1alpha1
    kind: ALBInstance
    metadata:
      name: app-gw
      namespace: prod
    spec:
      gatewayName: app-gw
      inlet:
        type: LoadBalancer
  2. После того как объект ALBInstance перейдёт в состояние Ready, создайте объекты ListenerSet и HTTPRoute:

    apiVersion: gateway.networking.k8s.io/v1
    kind: ListenerSet
    metadata:
      name: app-listeners
      namespace: prod
    spec:
      parentRef:
        name: app-gw   # Имя объекта Gateway из поля status ALBInstance.
        namespace: prod
      listeners:
        - name: app-https
          port: 443 # Для HTTPS трафика необходимо указывать 443 порт.
          protocol: HTTPS
          hostname: app.example.com
          tls:
            mode: Terminate
            certificateRefs:
              - name: app-tls   # Наименование секрета содержащего необходимый TLS-сертификат.
                namespace: prod
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: app-route
      namespace: prod
    spec:
      parentRefs:
        - name: app-listeners # Имя ListenerSet.
          namespace: prod
          kind: ListenerSet
          group: gateway.networking.k8s.io
          sectionName: app-https
          port: 443
      hostnames:
        - app.example.com
      rules:
        - backendRefs:
            - name: app-svc # Наименование сервиса приложения.
              port: 8080

Объекты GRPCRoute, TLSRoute и TCPRoute

Объект GRPCRoute предназначен для маршрутизации gRPC-трафика. Для него создаётся объект ListenerSet со слушателем HTTPS, а затем добавляется объект GRPCRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: grpc-listeners
  namespace: prod
spec:
  parentRef:
    name: app-gw   # Имя объекта Gateway из поля status ALBInstance.
    namespace: prod
  listeners:
    - name: grpc-https
      port: 443 # Для HTTPS трафика необходимо указывать 443 порт.
      protocol: HTTPS
      hostname: grpc.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: grpc-tls   # Наименование секрета содержащего необходимый TLS-сертификат.
            namespace: prod
---
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-route
  namespace: prod
spec:
  parentRefs:
    - name: grpc-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: grpc-https
      port: 443
  hostnames:
    - grpc.example.com
  rules:
    - backendRefs:
        - name: grpc-svc # Наименование сервиса приложения.
          port: 9090

Для TLS passthrough, когда расшифровка трафика должна выполняться на стороне приложения, можно использовать либо TLS listener, либо HTTPS listener. Ниже показан вариант с TLS listener:

Дополнительно настройте в ALBInstance параметр additionalPorts для добавления TCP-обработчика:

apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
  name: app-gw
  namespace: prod
spec:
  gatewayName: app-gw
    inlet:
      type: LoadBalancer
      additionalPorts:
      - port: 8443    # Дополнительный TCP-порт для TLS-трафика.
        protocol: TCP

Далее настройте объекты ListenerSet и TLSRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: tls-pass-listeners
  namespace: prod
spec:
  parentRef:
    name: app-gw   # Имя объекта Gateway из поля status ALBInstance.
    namespace: prod
  listeners:
    - name: tls-pass
      port: 8443 # В данном примере для TLS трафика переиспользуется порт 8443.
      protocol: TLS
      hostname: pass.example.com
      tls:
        mode: Passthrough # Режим TLS - сквозной.
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: TLSRoute
metadata:
  name: tls-pass-route
  namespace: prod
spec:
  parentRefs:
    - name: tls-pass-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: tls-pass
      port: 8443 # В данном примере для TLS трафика переиспользуется порт 8443.
  hostnames:
    - pass.example.com
  rules:
    - backendRefs:
        - name: tls-pass-svc # Наименование сервиса приложения.
          port: 8443

Тот же сценарий можно реализовать и через HTTPS listener. Этот вариант особенно удобен, когда нужно использовать стандартный обработчик на порту 443 так как не требуется открывать дополнительный порт для TLS passthrough:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: https-pass-listeners
  namespace: prod
spec:
  parentRef:
    name: app-gw   # Имя объекта Gateway из поля status ALBInstance.
    namespace: prod
  listeners:
    - name: https-pass
      port: 443 # В данном примере для TLS трафика переиспользуется порт 443.
      protocol: HTTPS
      hostname: pass.example.com
      tls:
        mode: Passthrough # Режим TLS - сквозной.
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: TLSRoute
metadata:
  name: https-pass-route
  namespace: prod
spec:
  parentRefs:
    - name: https-pass-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: https-pass
      port: 443 # В данном примере для TLS трафика переиспользуется порт 443.
  hostnames:
    - pass.example.com
  rules:
    - backendRefs:
        - name: tls-pass-svc # Наименование сервиса приложения.
          port: 8443

Если TLS нужно терминировать на шлюзе, а затем передать трафик дальше как обычный TCP-поток, создайте объект ListenerSet со слушателем TLS и режимом Terminate, после чего подключите объект TCPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: tls-term-listeners
  namespace: prod
spec:
  parentRef:
    name: app-gw   # Имя объекта Gateway из поля status ALBInstance.
    namespace: prod
  listeners:
    - name: tls-term
      port: 443 # В данном примере для TLS трафика переиспользуется порт 443.
      protocol: TLS
      hostname: term.example.com
      tls:
        mode: Terminate     # Режим TLS - терминация.
        certificateRefs:
          - name: term-tls  # Наименование секрета содержащего необходимый TLS-сертификат.
            namespace: prod
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: tls-term-route
  namespace: prod
spec:
  parentRefs:
    - name: tls-term-listeners # Имя ListenerSet.
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: tls-term
      port: 443
  rules:
    - backendRefs:
        - name: tls-svc # Наименование сервиса приложения.
          port: 8080

Перевод приложения на публикацию через другой Gateway

Если приложение нужно опубликовать через другой объект Gateway, выполните следующие шаги:

  1. Создайте новый объект ClusterALBInstance или ALBInstance, чтобы контроллер создал новый объект Gateway.
  2. Создайте объект ListenerSet с теми же именами хостов, портами и TLS-настройками. В spec.parentRef укажите новый объект Gateway.
  3. В существующий объект TTPRoute, в parentRefsдобавьте ещё один объект, который указывает на новый объект ListenerSet.
  4. Проверьте доступность приложения через новый шлюз.
  5. После проверки удалите из parentRefs объекта HTTPRout ссылку на неактуальные ListenerSet.

Привязка маршрута в одном неймспейсе к ListenerSet объекту в другом неймспейсе

Если объект HTTPRoute создаётся в одном неймспейсе и должен подключаться к объекту ListenerSet в другом неймспейсе, в неймспейсе целевого объекта ListenerSet добавьте объект ReferenceGrant. В примере ниже показаны общий объект ListenerSet в неймспейсе shared-gw, прикладной объект HTTPRoute в неймспейсе prod и объект ReferenceGrant, который разрешает такую привязку:

apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
  name: shared-listeners
  namespace: shared-gw
spec:
  parentRef:
    name: public-gw
    namespace: d8-alb
  listeners:
    - name: app-https
      port: 443
      protocol: HTTPS
      hostname: app.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-tls
            namespace: shared-gw
---
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
  name: allow-prod-httproute-to-shared-listeners
  namespace: shared-gw
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      namespace: prod
  to:
    - group: gateway.networking.k8s.io
      kind: ListenerSet
      name: shared-listeners
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
  namespace: prod
spec:
  parentRefs:
    - name: shared-listeners
      namespace: shared-gw
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: app-https
      port: 443
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: app-svc
          port: 8080

Настройка параметров TLS через BackendTLSPolicy

Если трафик от шлюза к backend должен идти по TLS, необходимо создать объект BackendTLSPolicy в неймспейсе backend-объекта Service. В примере ниже показаны объект HTTPRoute, backend-объект Service с именованным портом, ConfigMap с CA bundle и объект BackendTLSPolicy, который задаёт TLS-валидацию для этого backend:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
  namespace: prod
spec:
  parentRefs:
    - name: app-listeners
      namespace: prod
      kind: ListenerSet
      group: gateway.networking.k8s.io
      sectionName: app-https
      port: 443
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: app-svc
          port: 8443
---
apiVersion: v1
kind: Service
metadata:
  name: app-svc
  namespace: prod
spec:
  selector:
    app: app
  ports:
    - name: https
      port: 8443
      targetPort: 8443
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-backend-ca
  namespace: prod
data:
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
  name: app-svc-tls
  namespace: prod
spec:
  targetRefs:
    - group: ""
      kind: Service
      name: app-svc
      sectionName: https
  validation:
    hostname: app.internal.example.com
    caCertificateRefs:
      - group: ""
        kind: ConfigMap
        name: app-backend-ca

Поддерживаемые аннотации HTTPRoute

Так как текущая спецификация Gateway API пока не покрывает все возможности, необходимые для корректной работы кластера DKP, модуль предоставляет постепенно расширяющийся набор аннотаций объекта HTTPRoute, который добавляет недостающие параметры конфигурации. Контроллер читает эти ключи из HTTPRoute.metadata.annotations.

Аннотация Описание
alb.network.deckhouse.io/tls-disable-protocol Отключает версию протокола TLS для обработчика с именем хоста этого маршрута (например значение http2). Может быть необходимо в редких случаях когда используется общий сертификат с несколькими DNS-именами в сочетании с перенаправлением запросов.
alb.network.deckhouse.io/whitelist-source-range Ожидает список подсетей в формате CIDR через запятую: фильтр по IP на уровне маршрута; переопределяет глобальный whitelist (например 10.1.1.10/32, 10.2.2.2/32)
alb.network.deckhouse.io/response-headers-to-add JSON-объект дополнительных заголовков ответа (например {“Strict-Transport-Security”: “max-age=31536000; includeSubDomains”}).
alb.network.deckhouse.io/session-affinity JSON для cookie session affinity (mode, path, cookieName, ttl и др.); не все поля обязательны, (например {“mode”: “cookie”, “path”: “/path”, “cookieName”: “mycookie”, “ttl”: 0}).
alb.network.deckhouse.io/hash-key Например source-ip: консистентный хэш для backend’ов Service у объекта HTTPRoute.
alb.network.deckhouse.io/service-upstream "true": трафик к upstream идёт через соответствующий сервис, а не напрямую к подам.
alb.network.deckhouse.io/basic-auth-secret namespace/secret с данными htpasswd для HTTP Basic Auth на этом маршруте.
alb.network.deckhouse.io/satisfy all или any: определяет необходимость удовлетворения обеих проверок (whitelist и basic-auth) или какой-либо одной (по умолчанию all).
alb.network.deckhouse.io/auth-url Определяет URL внешнего сервиса аутентификации.
alb.network.deckhouse.io/auth-signin Определяет URL редиректа для авторизации в случае получения 401 от внешней аутентификации.
alb.network.deckhouse.io/auth-response-headers Список через запятую: дополнительные заголовки из ответа auth для передачи в upstream (поверх стандартного allowlist).
alb.network.deckhouse.io/rewrite-target Позволяет переопределять пути для правил с типом RegularExpression используя regex capture groups (например /my-path/\1).
alb.network.deckhouse.io/buffer-max-request-bytes Определяет размер буфера, который допускается использовать в случае буферизации запросов (по умолчанию Envoy Proxy не буферизует запросы).
alb.network.deckhouse.io/limit-rps Лимит RPS на маршрут.
alb.network.deckhouse.io/backend-tls-settings Например {“mode”: “SIMPLE”, “insecureSkipVerify”: true, “clientCertificate”: “”, “privateKey”: “”, “caCertificates”: “”}; позволяет явно указать параметры TLS подключения к upstream.