﻿# Установка Cilium Gateway

> [HTML Version](cilium-gateway.html)

Cilium Gateway API служит единой точкой входа в кластер для работы с внешним трафиком в ELMA365. Использование Gateway API позволяет управлять доступом к ELMA365 через единый интерфейс и передавать данные с помощью Cilium в eBPF‑программы.

Cilium Gateway позволяет:

- определять доступ к сервисам из внешних источников;

- автоматически настраивать L7‑маршрутизацию (HTTP/gRPC);

- обеспечивать расшифровку TLS;

- реализовывать балансировку нагрузки. 

Установка и настройка Cilium Gateway состоит из нескольких этапов:

1. [Скачивание helm-чарта и конфигурационного файла](#download-chart).

2. [Заполнение конфигурационного файла](#config-file).

3. [Установка с помощью helm в Kubernetes-кластер](#install-cilium-chart).

4. [Создание TLS-сертификата](#tls-certificate).

5. [Создание Gateway](#create-gateway).

6. [Настройка внешнего IP-адреса через MetalLB (опционально)](#metallb-external-ip).

7. [Настройка ELMA365 для работы с Gateway API](#gateway-api-support).

**Важно**: рекомендуем использовать в кластере только один Gateway‑контроллер, чтобы избежать конфликта ресурсов `HTTPRoute` и `Gateway`, непредсказуемой маршрутизации и повышенной нагрузки. Два контроллера можно разворачивать только временно, например при миграции, или в строго изолированных namespace с разными ресурсами `GatewayClass`.

## Шаг 1. Скачать helm-чарт и конфигурационный файл

Для установки через интернет получите конфигурационный файл `values-cilium.yaml`, выполнив команду:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm show values elma365/cilium > values-cilium.yaml

````
**Получение конфигурационного файла для установки в закрытом контуре без доступа в интернет**

1. На компьютере с доступом в интернет скачайте архив актуальной версии (latest) чарта **cilium**, используя команду:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm pull elma365/cilium

2. ````
Скопируйте полученный архив чарта `cilium-X.Y.Z.tgz` на сервер, где будет выполняться установка.

3. Распакуйте чарт `cilium-X.Y.Z.tgz` и создайте копию конфигурационного файла `values.yaml` с названием `values-cilium.yaml`:

````
tar -xf cilium-X.Y.Z.tgz  
cp cilium/values.yaml values-cilium.yaml
````

## ````
Шаг 2. Заполнить конфигурационный файл

Задайте настройки для установки Cilium в конфигурационном файле `values-cilium.yaml`. 



Пример содержания файла values-cilium.yaml

````
\## Настройки cilium  
cilium:  
  gatewayAPI:  
    enabled: true  
\## Использовать hostNetwork для Gateway (иначе CNI) необходимо расскомментировать envoy.securityContext.capabilities  
    hostNetwork:  
      enabled: false  
  
\## Включить Envoy внутри Cilium  
  envoy:  
    enabled: true  
\##  При включенном hostNetwork.enabled=true, раскомметировать securityContext  
    securityContext:  
      capabilities:  
        keepCapNetBindService: true  
        envoy: \[NET\_BIND\_SERVICE,BPF,SYS\_ADMIN,NET\_ADMIN,NET\_RAW\]
````

````
**Заполнение параметров подключения к приватному registry для установки в закрытом контуре без доступа в интернет**

  
Для подключения к приватному registry:

1. Скачайте образы ELMA365 и загрузите их в локальный реестр образов. Подробнее читайте в статье [«Загрузка образов ELMA365»](downloadin-images-elma365.md).

2. В файле `values-cilium.yaml`:

	- в параметре `image.repository` — задайте путь к приватному registry в формате `registry.example.com`;

	- в параметре `imagePullSecrets` — укажите наименование секрета с правами доступа к приватному registry. Он должен быть создан вручную и зашифрован в Base64.

````
cilium:  
\## параметры подключения к приватному registry  
  image:  
    repository: "registry.example.com/docker/addons/cilium/cilium"  
    tag: "v1.19.3"  
    useDigest: false  
\## секрет с правами доступа к приватному registry должен быть создан вручную, зашифрованный в Base64  
  imagePullSecrets: \[\]  
\## На каких узлах запускать Cilium  
  nodeSelector:  
    kubernetes.io/os: linux  
  tolerations:  
    - operator: Exists  
  
  
  envoy:  
    image:  
\## параметры подключения к приватному registry  
      repository: "registry.example.com/docker/addons/cilium/cilium-envoy"  
      tag: "v1.36.6-1776000132-2437d2edeaf4d9b56ef279bd0d71127440c067aa"  
\## На каких узлах запускать Cilium  
    nodeSelector:  
      kubernetes.io/os: linux  
    tolerations:  
      - operator: Exists
````

## ````
Шаг 3. Установить чарт cilium в Kubernetes-кластер

1. Установите CRD из Gateway API версии 1.5.1 согласно инструкциям в [документации Cilium Gateway API](https://docs.cilium.io/en/latest/network/servicemesh/gateway-api/gateway-api/).   
Вы также можете установить их с помощью команды:

````
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_gatewayclasses.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_gateways.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_httproutes.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_referencegrants.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_grpcroutes.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.1/config/crd/standard/gateway.networking.k8s.io\_backendtlspolicies.yaml   
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.5.0/config/crd/experimental/gateway.networking.k8s.io\_tlsroutes.yaml

2. ````
С помощью helm установите чарт **cilium** в namespace `kube-system`:

	1. Для установки через интернет выполните команду:

````
helm upgrade --install -n kube-system cilium elma365/cilium -f values-cilium.yaml

	2. ````
Для установки без доступа в интернет перейдите в каталог с загруженным чартом и выполните команду:

````
helm upgrade --install cilium ./cilium -f values-cilium.yaml -n kube-system

## ````
Шаг 4. Создать TLS-сертификат

Для обеспечения доступа по протоколу HTTPS создайте TLS-сертификат и добавьте его в Kubernetes в виде секрета.

Вы можете использовать:

- самоподписанный сертификат — подробнее читайте в [статье о создании самоподписанных сертификатов с помощью OpenSSL](ssl-certificates.md);

- сертификат, выданный доверенным центром сертификации.

Добавьте созданный сертификат в Kubernetes. Для этого в пространстве имён `kube-system` создайте TLS-секрет с полученным файлом сертификата в формате **.crt** и ключом в формате **.key**:

````
kubectl create secret tls elma365-tls -n kube-system \\  
\--cert=/etc/ssl/certs/selfsigned.crt \\  
\--key=/etc/ssl/private/selfsigned.key

````
где:

- `elma365-tls` — имя секрета, которое будет использоваться в ресурсе `Gateway`;

- `--cert` — путь к сертификату;

- `--key` — путь к приватному ключу.

## Шаг 5. Создать Gateway

Ресурс `Gateway` определяет правила обработки входящего трафика в кластере. Он описывает, какие порты и протоколы используются, а также какие сертификаты применяются для HTTPS.

Чтобы создать ресурс `Gateway` и связать с ресурсом `GatewayClass`:

````
kubectl apply -n kube-system -f - <<EOF  
apiVersion: gateway.networking.k8s.io/v1  
kind: Gateway  
metadata:  
   name: cilium-gateway  
spec:  
   gatewayClassName: cilium  
   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` — определяет, из каких пространств имён разрешено подключение маршрутов.

После создания `Gateway` можно подключать маршруты для публикации сервисов с помощью ресурса `HTTPRoute`.

## Шаг 6. Настроить внешний 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 kube-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 kube-system

````
`Gateway` готов к использованию для маршрутизации трафика ELMA365.

## Шаг 7. Настроить ELMA365 для работы с Gateway API

После установки `Gateway` включите поддержку Gateway API в конфигурации ELMA365.

Для этого в конфигурационном файле `values-elma365.yaml` добавьте или измените параметры:

````
global:  
 …  
  gatewayAPI:  
    ## включение Gateway API (HTTPRoute)  
    enabled: true  
    parentRefs:  
    - name: cilium-gateway  
      namespace: kube-system

````
где:

- `enabled` — включает использование Gateway API вместо Ingress;

- `parentRefs` — указывает `Gateway`, через который публикуется ELMA365.

Значения должны соответствовать параметрам ранее созданного ресурса `Gateway`.

Подробнее о редактировании конфигурационного файла читайте в [статье об изменении параметров ELMA365](change-settings-enterprise.md).