﻿# Установка Envoy Gateway

> [HTML Version](envoy-gateway.html)

Envoy Gateway — это инструмент для управления трафиком в Kubernetes, с помощью которого можно предоставить доступ к сервисам приложения ELMA365 через единый шлюз — Gateway API. 

Envoy Gateway позволяет:

- маршрутизировать и перенаправлять трафик;

- обеспечивать расшифровку TLS и управление запросами;

- реализовывать балансировку нагрузки;

- использовать расширенные возможности наблюдения за сетями.

Установка и настройка Envoy Gateway состоит из нескольких этапов:

1. [Скачивание helm-чарта и конфигурационного файла](#download-chart).

2. [Заполнение конфигурационного файла](#config-file).

3. [Установка с помощью helm в Kubernetes-кластер](#install-chart).

4. [Создание GatewayClass](#create-gatewayclass).

5. [Создание TLS-сертификата](#tls-certificate).

6. [Создание Gateway](#create-gateway).

7. [Настройка внешнего IP-адреса через MetalLB (опционально)](#metallb-external-ip).

8. [Настройка ELMA365 для работы с Gateway API](#gateway-api-support).

**Важно**: рекомендуем использовать в кластере только один Gateway‑контроллер, чтобы избежать конфликта ресурсов HTTPRoute и Gateway, непредсказуемой маршрутизации и повышенной нагрузки. Два контроллера можно разворачивать только временно, например при миграции, или в строго изолированных namespace с разными ресурсами `GatewayClass`.

## Шаг 1. Скачать helm-чарт и конфигурационный файл

Для установки через интернет получите конфигурационный файл `values-envoy-gateway.yaml`, выполнив команду:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm show values elma365/envoy-gateway > values-envoy-gateway.yaml

````
**Получение конфигурационного файла для установки в закрытом контуре без доступа в интернет**

1. На компьютере с доступом в интернет скачайте архив актуальной версии (latest) чарта **envoy-gateway**, используя команду:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm pull elma365/envoy-gateway

2. ````
Скопируйте полученный архив чарта `envoy-gateway-X.Y.Z.tgz` на сервер, где будет выполняться установка.

3. Распакуйте чарт `envoy-gateway-X.Y.Z.tgz` и создайте копию конфигурационного файла `values.yaml` с названием `values-envoy-gateway.yaml`:

````
tar -xf envoy-gateway-X.Y.Z.tgz  
cp envoy-gateway/values.yaml values-envoy-gateway.yaml
````

## ````
Шаг 2. Заполнить конфигурационный файл

Задайте настройки для установки Envoy Gateway в конфигурационном файле `values-envoy-gateway.yaml`. 

Пример содержания файла values-envoy-gateway.yaml

````
\## Настройки envoy-gateway  
gateway-helm:  
  deployment:  
    envoyGateway:  
      resources:  
        limits:  
          memory: 1024Mi  
        requests:  
          cpu: 100m  
          memory: 256Mi  
\## Настройки конфигурации  
  config:  
    envoyGateway:  
      gateway:  
        controllerName: gateway.envoyproxy.io/gatewayclass-controller  
      provider:  
        type: Kubernetes
````

````
**Заполнение параметров подключения к приватному registry для установки в закрытом контуре без доступа в интернет**

  
Для подключения к приватному registry:

1. Скачайте образы ELMA365 и загрузите их в локальный реестр образов. Подробнее читайте в статье [«Загрузка образов ELMA365»](downloadin-images-elma365.md).

2. В файле `values-envoy-gateway.yaml`:

	- в параметре `image.repository` — задайте путь к приватному registry в формате `registry.example.com`;

	- в параметре `imagePullSecrets` — укажите наименование секрета с правами доступа к приватному registry. Он должен быть создан вручную и зашифрован в Base64.

````
\## Настройки envoy-gateway  
gateway-helm:  
  global:  
\## Параметры подключения к приватному registry  
    imageRegistry: "registry.example.com/docker/addons/envoyproxy"  
    imagePullSecrets: \[\]  
    images:  
      envoy:  
\## Адрес и секрет для приватного registry  
        image: envoy  
        tag: distroless-v1.37.2  
      envoyGateway:  
\## Адрес и путь для приватного registry  
        image: /gateway:v1.7.2  
        pullSecrets: \[\]  
      ratelimit:  
\## Адрес и путь для приватного registry  
        image: "/ratelimit:05c08d03"  
        pullSecrets: \[\]
````

## ````
Шаг 3. Установить чарт envoy-gateway в Kubernetes-кластер 

С помощью helm установите чарт **envoy-gateway** в namespace `envoy-gateway-system`:

- для установки через интернет:

````
helm upgrade --install -n envoy-gateway-system envoy-gateway elma365/envoy-gateway -f values-envoy-gateway.yaml

- ````
для установки без доступа в интернет перейдите в каталог с загруженным чартом и выполните команду:

````
helm upgrade --install envoy-gateway ./envoy-gateway -f values-envoy-gateway.yaml -n envoy-gateway-system

## ````
Шаг 4. Создать GatewayClass

Ресурс `GatewayClass` определяет, какой контроллер будет обрабатывать ресурсы `Gateway` в кластере.

Чтобы создать `GatewayClass`, выполните команду:

````
kubectl apply -f - <<EOF  
apiVersion: gateway.networking.k8s.io/v1  
kind: GatewayClass  
metadata:  
  name: envoy-gateway  
spec:  
  controllerName: gateway.envoyproxy.io/gatewayclass-controller  
  parametersRef:  
    group: gateway.envoyproxy.io  
    kind: EnvoyProxy  
    name: custom-envoy-proxy  
    namespace: envoy-gateway-system  
EOF

## ````
Шаг 5. Создать TLS-сертификат

Для обеспечения доступа по протоколу HTTPS создайте TLS-сертификат и добавьте его в Kubernetes в виде секрета.

Вы можете использовать:

- самоподписанный сертификат — подробнее читайте в [статье о создании самоподписанных сертификатов с помощью OpenSSL](ssl-certificates.md);

- сертификат, выданный доверенным центром сертификации.

Добавьте созданный сертификат в Kubernetes. Для этого в пространстве имён `kube-system` создайте TLS-секрет с полученным файлом сертификата в формате **.crt** и ключом в формате **.key**:

````
kubectl create secret tls elma365-tls -n envoy-gateway-system \\  
\--cert=/etc/ssl/certs/selfsigned.crt \\  
\--key=/etc/ssl/private/selfsigned.key

````
где:

- `elma365-tls` — имя секрета, которое будет использоваться в ресурсе `Gateway`;

- `--cert` — путь к сертификату;

- `--key` — путь к приватному ключу.

## Шаг 6. Создать Gateway

Ресурс `Gateway` определяет правила обработки входящего трафика в кластере. Он описывает, какие порты и протоколы используются, а также какие сертификаты применяются для HTTPS. Чтобы настроить его:

1. Добавьте ресурс `Gateway` и свяжите с ресурсом `GatewayClass`:

````
kubectl apply -n envoy-gateway-system -f - <<EOF  
apiVersion: gateway.networking.k8s.io/v1  
kind: Gateway  
metadata:  
   name: envoy-gateway  
spec:  
   gatewayClassName: envoy-gateway  
   listeners:  
   - name: http  
     port: 80  
     protocol: HTTP  
     allowedRoutes:  
       namespaces:  
        from: All  
   - name: https  
     port: 443  
     protocol: HTTPS  
     tls:  
       mode: Terminate  
       certificateRefs:  
       - name: elma365-tls  
     allowedRoutes:  
       namespaces:  
         from: All  
EOF

````
где:

- `gatewayClassName` — контроллер, который будет обрабатывать ресурс `Gateway`;

- `listeners` — список точек входа: 

	- `port` — порт;

	- `protocol` — протокол: HTTP или HTTPS;

	- `tls.mode: Terminate` — завершение TLS‑соединения на стороне `Gateway`;

	- `certificateRefs` — ссылка на ранее созданный TLS-секрет. Значение в поле `name` должно совпадать с [именем сертификата в Kubernteres](#add-certificate);

- `allowedRoutes` — определяет, из каких пространств имён разрешено подключение маршрутов.

2. Опубликуйте сервис `envoy-gateway` одним из способов:

	- с помощью стороннего балансировщика — например, [установите решение MetalLB](#metallb-external-ip);

	- с помощью встроенных возможностей `Gateway` — чтобы присвоить сервису тип `LoadBalancer`, выполните команду, указав вместо `<node\_ip>` IP‑адрес узла, на котором доступен сервис, например 192.168.1.10:

````
kubectl patch svc \$(kubectl get svc -n envoy-gateway-system -o name | grep envoy-gateway | head -1 | sed 's|service/||') -n envoy-gateway-system -p '\{"spec": \{"type": "LoadBalancer", "externalIPs":\["<node\_ip>"\]\}\}'

## ````
Шаг 7. Настроить внешний IP-адрес через MetalLB (опционально)

Для правильной работы Gateway API требуется прямой выход в интернет с публичным IP-адресом на узле кластера с использованием сервиса типа `NodePort`. После создания `Gateway` автоматически создаётся сервис типа `LoadBalancer`, c помощью которого поступает входящий трафик.

Вы можете установить инструмент MetalLB, который работает так же, как облачные балансировщики нагрузки. В нём используются механизмы L2 (ARP/NDP) или протокол BGP для предоставления IP‑адреса сервисам типа `LoadBalancer`, которые создаёт `Gateway`.

**Когда использовать MetalLB**

  
Балансировщик MetalLB нужен в случаях, когда:

1. **На узле нет публичного IP-адреса**. MetalLB предоставляет виртуальный IP-адрес (VIP) из заранее сконфигурированного пула. В L2‑режиме активный узел принимает трафик на этот VIP, реализуя keepalive-подобное поведение.

2. **Требуется отказоустойчивый Gateway**. При выходе текущего активного узла из строя в L2-режиме VIP автоматически перехватывается другим узлом после обновления ARP/NDP. BGP‑режим обеспечивает более быстрое переключение за счёт протокола маршрутизации.

3. **Требуется обращение к сервисам Gateway API из внешних источников**. Сервисам типа `LoadBalancer`, на которые ссылается ресурс `Gateway`, нужно получать реальный IP‑адрес, доступный вне кластера. Кроме того, прямой доступ требуется, если для `Gateway` настроены определённые IP‑адреса в поле `addresses`.

Установка MetalLB не требуется, если:

1. **Уже существует публичный IP-адрес на узле**. Достаточно использовать `NodePort` с прямым доступом к узлу, например, для `Gateway` с параметром `hostNetwork: true` или при указании `NodePort` вручную.

2. **Кластер развёрнут в облаке, например Yandex Cloud**. У облачного провайдера есть свой балансировщик (NLB, ALB, L7 Load Balancer), который может выделить IP для сервиса типа `LoadBalancer`, используемого ресурсом `Gateway`.

3. **Gateway-контроллер принимает подключения напрямую на портах хоста**. Если для параметра `hostNetwork` установлено значение` true`, то Gateway-контроллер, например `envoy-gateway` или `istio`, принимает подключения напрямую. Тогда дополнительный балансировщик не нужен.

4. **В тестовом окружении без требований к доступам**. Более простым и быстрым решением является использование `Gateway` с сервисом типа `NodePort` и IP‑адреса узла.

5. **Уже установлен OpenELB или другой балансировщик**. MetalLB будет конфликтовать с существующим компонентом при попытке управлять одинаковыми пулами IP.

Чтобы узнать о наличии внешнего IP‑адреса для сервиса `Gateway`, посмотрите настройки сервисов с помощью команды:

````
kubectl get svc -n envoy-gateway-system

````
Проверьте значение в колонке `EXTERNAL-IP`:

- если указан IP-адрес — внешний доступ уже настроен; 

- если установлено значение `<pending>` или `<none>` — в кластере отсутствует внешний балансировщик:

	- в облачных Kubernetes-кластерах — внешний балансировщик создастся автоматически, поэтому дополнительных действий не требуется;

	- в локальных или тестовых окружениях — можно использовать MetalLB.

### Установить MetalLB

Чтобы применять MetalLB для настройки внешнего доступа к `Gateway`:

1. Установите MetalLB:

````
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml

2. ````
Запустите команду для отслеживания состояния подов и дождитесь запуска компонентов:

````
kubectl get pods -n metallb-system -w

3. ````
Настройте пул IP-адресов:

````
kubectl apply -f - <<EOF  
apiVersion: metallb.io/v1beta1  
kind: IPAddressPool  
metadata:  
  name: host-ip-pool  
  namespace: metallb-system  
spec:  
  addresses:  
  - 192.168.29.176-192.168.29.176  
\---  
apiVersion: metallb.io/v1beta1  
kind: L2Advertisement  
metadata:  
  name: host-ip-adv  
  namespace: metallb-system  
spec:  
  ipAddressPools:  
  - host-ip-pool  
EOF

````
где `192.168.29.176` — пример IP‑адреса хоста, на котором установлен Kubernetes. Используйте IP‑адрес узла в вашем кластере, который доступен для внешнего трафика.

4. Проверьте настройки сервиса `Gateway`:

````
kubectl get svc -n envoy-gateway-system

````
Ресурс `Gateway` готов к использованию для маршрутизации трафика ELMA365.

## Шаг 8. Настроить ELMA365 для работы с Gateway API

После установки `Gateway` включите поддержку Gateway API в конфигурации ELMA365.

Для этого в конфигурационном файле `values-elma365.yaml` добавьте или измените параметры:

````
global:  
 …  
  gatewayAPI:  
    ## включение Gateway API (HTTPRoute)  
    enabled: true  
    parentRefs:  
    - name: envoy-gateway  
      namespace: envoy-gateway-system

````
где:

- `enabled` — включает использование Gateway API вместо Ingress;

- `parentRefs` — указывает `Gateway`, через который публикуется ELMA365.

Значения должны соответствовать параметрам ранее созданного ресурса `Gateway`.

Подробнее о редактировании конфигурационного файла читайте в [статье об изменении параметров ELMA365](change-settings-enterprise.md).