Разверните OpenClaw в облаке в один клик
Вход/ Регистрация
На главную
Облачные сервисы

Envoy Gateway

Envoy Gateway — это контроллер Gateway API для Kubernetes, который использует Envoy Proxy для обработки входящего трафика. С его помощью можно публиковать HTTP, HTTPS, gRPC, TCP и UDP-сервисы, настраивать маршрутизацию по доменам и путям, управлять TLS и применять политики трафика через стандартные Kubernetes-ресурсы.

Gateway API можно рассматривать как развитие Ingress. Вместо одного ресурса Ingress используются несколько объектов с разными зонами ответственности:

  • GatewayClass — указывает, какой контроллер будет обслуживать шлюзы.

  • Gateway — описывает точку входа: порты, протоколы и TLS-настройки.

  • HTTPRoute — задает правила маршрутизации HTTP-трафика к сервисам.

  • GRPCRoute, TCPRoute, UDPRoute, TLSRoute — используются для других типов трафика.

Envoy Gateway отслеживает эти ресурсы и на их основе создает Envoy Proxy, который принимает внешний трафик и направляет его к сервисам внутри кластера.

Установка

Для установки Envoy Gateway откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите Envoy Gateway.

В открывшемся мастере установки можно оставить параметры по умолчанию или включить продвинутую установку и изменить values.yaml. Для начала работы достаточно настроек по умолчанию.

Нажмите «Установить» и дождитесь завершения установки. После этого проверьте, что поды Envoy Gateway запущены:

    
kubectl get pods -n envoy-gateway-system

Все поды должны находиться в статусе Running.

Также можно проверить, что в кластере появились ресурсы Gateway API:

    
kubectl api-resources | grep gateway.networking.k8s.io

Пример использования

Рассмотрим пример, в котором Envoy Gateway будет принимать HTTP-трафик на одном внешнем IP-адресе и направлять запросы в два разных сервиса:

  • http://app.example.com/service1 — в сервис service1;

  • http://app.example.com/service2 — в сервис service2.

Для примера создадим отдельный неймспейс:

    
kubectl create namespace envoy-example

Создание ConfigMap

Создайте файл configmap.yaml с HTML-страницами для двух сервисов:

    
apiVersion: v1 kind: ConfigMap metadata: name: nginx-pages namespace: envoy-example data: service1.html: | <html> <head><title>Service 1</title></head> <body><h1>Service 1</h1></body> </html> service2.html: | <html> <head><title>Service 2</title></head> <body><h1>Service 2</h1></body> </html>

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

    
kubectl apply -f configmap.yaml

Создание Deployment и Service

Создайте файл service1.yaml:

    
apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: envoy-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service1.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: envoy-example spec: selector: app: service1 ports: - name: http port: 80 targetPort: 80 type: ClusterIP

Создайте файл service2.yaml:

    
apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: envoy-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service2.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: envoy-example spec: selector: app: service2 ports: - name: http port: 80 targetPort: 80 type: ClusterIP

Примените манифесты:

    
kubectl apply -f service1.yaml kubectl apply -f service2.yaml

Проверьте, что поды запущены:

    
kubectl get pods -n envoy-example

Создание GatewayClass

GatewayClass связывает Gateway API с контроллером Envoy Gateway. Создайте файл gatewayclass.yaml:

    
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: envoy-gateway spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller

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

    
kubectl apply -f gatewayclass.yaml

Проверьте статус:

    
kubectl get gatewayclass envoy-gateway

В колонке ACCEPTED должно быть значение True. Это означает, что Envoy Gateway принял GatewayClass и будет обслуживать связанные с ним ресурсы Gateway.

Создание Gateway

Gateway описывает внешний вход в приложение. Создайте файл gateway.yaml:

    
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: app-gateway namespace: envoy-example spec: gatewayClassName: envoy-gateway listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same

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

    
kubectl apply -f gateway.yaml

Когда Gateway будет создан, Envoy Gateway развернет Envoy Proxy и балансировщик нагрузки. Создание балансировщика можно отследить в панели управления или проверить командой:

    
kubectl get gateway app-gateway -n envoy-example

Дождитесь, когда в колонке PROGRAMMED появится значение True, а в колонке ADDRESS — внешний IP-адрес.

Также можно посмотреть созданный сервис:

    
kubectl get svc -n envoy-gateway-system \ -l gateway.envoyproxy.io/owning-gateway-namespace=envoy-example,gateway.envoyproxy.io/owning-gateway-name=app-gateway

Envoy Gateway по умолчанию создает балансировщик для каждого Gateway. Поэтому отдельный манифест Service типа LoadBalancer, как в классическом сценарии с Ingress-контроллером, не требуется.

Создание HTTPRoute

HTTPRoute задает правила маршрутизации. Создайте файл httproute.yaml:

    
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-route namespace: envoy-example spec: parentRefs: - name: app-gateway hostnames: - app.example.com rules: - matches: - path: type: PathPrefix value: /service1 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service1 port: 80 - matches: - path: type: PathPrefix value: /service2 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service2 port: 80

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

    
kubectl apply -f httproute.yaml

Проверьте, что маршрут принят:

    
kubectl get httproute app-route -n envoy-example -o yaml

В статусе ресурса должно быть:

    
status: "True" type: Accepted

В этом манифесте HTTPRoute принимает запросы с доменом app.example.com и направляет их в разные сервисы по префиксу пути. Фильтр URLRewrite заменяет префиксы /service1 и /service2 на /, чтобы Nginx внутри каждого сервиса отдавал свою главную страницу.

Проверка работы

Получите внешний IP-адрес Gateway:

    
kubectl get gateway app-gateway -n envoy-example

Пропишите этот IP-адрес в DNS-настройках домена app.example.com в виде A-записи. После обновления DNS проверьте доступность сервисов:

    
curl http://app.example.com/service1 curl http://app.example.com/service2

Если DNS еще не обновился, можно выполнить проверку по IP-адресу, передав заголовок Host:

    
curl -H "Host: app.example.com" http://<EXTERNAL_IP>/service1 curl -H "Host: app.example.com" http://<EXTERNAL_IP>/service2

В ответе должны отображаться страницы Service 1 и Service 2.

Удаление примера

Чтобы удалить ресурсы, созданные в примере, выполните:

    
kubectl delete namespace envoy-example kubectl delete gatewayclass envoy-gateway

Дополнение Envoy Gateway при этом останется установленным в кластере. Удалить его можно во вкладке «Дополнения» в панели управления кластером.

Миграция с Nginx Ingress на Envoy Gateway

Envoy Gateway можно развернуть рядом с Nginx Ingress и переносить маршруты постепенно. Такой подход позволяет сначала проверить ресурсы Gateway API на отдельном внешнем IP-адресе, а затем переключить DNS-записи или трафик на новый Gateway.

Для автоматической конвертации Ingress-ресурсов можно использовать утилиту ingress2gateway. Она читает существующие Ingress-ресурсы из кластера и выводит эквивалентные ресурсы Gateway API: Gateway, HTTPRoute и другие объекты.

ingress2gateway помогает подготовить миграцию, но не заменяет ручную проверку. Некоторые аннотации Nginx Ingress могут быть не поддержаны или потребовать ручной настройки после конвертации.

Требования

Перед миграцией подготовьте кластер:

  • установите Envoy Gateway;

  • создайте GatewayClass для Envoy Gateway;

  • проверьте, что исходные Ingress-ресурсы работают через Nginx Ingress.

Проверьте, что в кластере есть нужные классы:

    
kubectl get ingressclass kubectl get gatewayclass

В выводе должны быть:

  • IngressClass с именем nginx;

  • GatewayClass с именем envoy-gateway.

Установка ingress2gateway

Если на локальной машине установлен Go, установите ingress2gateway командой:

    
go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0

После установки бинарный файл будет доступен в директории $(go env GOPATH)/bin. Убедитесь, что эта директория добавлена в PATH.

Также можно установить ingress2gateway через Homebrew:

    
brew install ingress2gateway

Или скачать готовый бинарный файл со страницы релизов проекта.

Исходный пример

В примере ниже миграция выполняется для приложения, которое уже опубликовано через Nginx Ingress.

В кластере есть неймспейс ingress-migration-demo. В нем находятся:

  • Ingress migration-source;

  • Service service1 и service2;

  • два правила маршрутизации для домена ingress-migration.example.com:

    • /service1 направляет трафик в service1;

    • /service2 направляет трафик в service2.

Проверьте исходный Ingress:

    
kubectl get ingress -n ingress-migration-demo

В колонке CLASS должно быть значение nginx.

Конвертация Ingress-ресурсов

Чтобы сконвертировать этот Ingress в ресурсы Gateway API, выполните:

    
ingress2gateway print \ --providers=ingress-nginx \ --emitter=envoy-gateway \ --ingress-nginx-ingress-class=nginx \ --namespace=ingress-migration-demo > gateway-migration.yaml

В этой команде:

  • print — режим, в котором ingress2gateway выводит сгенерированные ресурсы в стандартный вывод. За счет перенаправления > результат сохраняется в файл gateway-migration.yaml.

  • --providers=ingress-nginx — указывает тип исходного Ingress-контроллера. В этом примере исходные маршруты обслуживает Nginx Ingress, поэтому используется значение ingress-nginx.

  • --emitter=envoy-gateway — указывает, для какого Gateway API-контроллера подготовить результат. В этом примере целевой контроллер — Envoy Gateway.

  • --ingress-nginx-ingress-class=nginx — выбирает только Ingress-ресурсы класса nginx. Такой класс создает аддон Nginx Ingress в Timeweb Cloud.

  • --namespace=ingress-migration-demo — ограничивает чтение ресурсов неймспейсом ingress-migration-demo, где находится исходный Ingress из примера.

Откройте файл gateway-migration.yaml и проверьте сгенерированные ресурсы перед применением.

Проверьте gatewayClassName у ресурса Gateway. ingress2gateway может сгенерировать это значение на основе имени исходного IngressClass. Например, если исходный Ingress использует класс nginx, в сгенерированном Gateway может появиться:

    
spec: gatewayClassName: nginx

Envoy Gateway не будет обрабатывать такой Gateway, если в кластере нет GatewayClass с именем nginx. Для GatewayClass из примера замените значение на envoy-gateway:

    
spec: gatewayClassName: envoy-gateway

Применение ресурсов Gateway API

После проверки примените файл:

    
kubectl apply -f gateway-migration.yaml

Проверьте, что Gateway создан и получил внешний IP-адрес:

    
kubectl get gateway -A

Тестирование перед переключением трафика

Пока DNS-записи указывают на старый Nginx Ingress, новый Gateway можно проверить по внешнему IP-адресу с заголовком Host:

    
curl -H "Host: app.example.com" http://<EXTERNAL_IP>/<path>

Где:

  • app.example.com — домен из HTTPRoute;

  • <EXTERNAL_IP> — IP-адрес нового Gateway;

  • <path> — путь, который должен обрабатываться маршрутом.

Сравните ответы старого Ingress и нового Gateway.

Если все работает корректно, можно изменить DNS-записи на IP нового балансировщика.

Была ли статья полезна?
Ваша оценка очень важна
Пока нет комментариев