NGINX Gateway Fabric — это контроллер Gateway API для Kubernetes, который использует NGINX для обработки входящего трафика. С его помощью можно публиковать HTTP, HTTPS, gRPC, TCP и UDP-сервисы, настраивать маршрутизацию по доменам и путям, управлять TLS и постепенно переходить от Ingress к Gateway API.
Gateway API можно рассматривать как развитие Ingress. Вместо одного ресурса Ingress используются несколько объектов с разными зонами ответственности:
-
GatewayClass— указывает, какой контроллер будет обслуживать шлюзы. -
Gateway— описывает точку входа: порты, протоколы, домены и TLS-настройки. -
HTTPRoute— задает правила маршрутизации HTTP-трафика к сервисам. -
GRPCRoute,TCPRoute,UDPRoute,TLSRoute— используются для других типов трафика.
NGINX Gateway Fabric отслеживает ресурсы Gateway API и на их основе создает NGINX data plane: поды NGINX и сервис, через который внешний трафик попадает в кластер и направляется к Kubernetes-сервисам.
Установка
Перед установкой NGINX Gateway Fabric из панели управления нужно вручную установить CRD Gateway API.
В команде укажите версию NGINX Gateway Fabric в параметре ref. Например, для версии v2.6.3:
kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.6.3" | kubectl apply -f -
После установки CRD откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите NGINX Gateway Fabric.
В открывшемся мастере установки можно оставить параметры по умолчанию или включить продвинутую установку и изменить values. Для начала работы достаточно настроек по умолчанию.
Нажмите «Установить» и дождитесь завершения установки. После этого проверьте, что поды NGINX Gateway Fabric запущены:
kubectl get pods -n nginx-gateway
Все поды должны находиться в статусе Running.
Также можно проверить, что в кластере появились ресурсы Gateway API:
kubectl api-resources | grep gateway.networking.k8s.io
При стандартной установке NGINX Gateway Fabric создает GatewayClass с именем nginx. Проверьте его статус:
kubectl get gatewayclass nginx
В колонке ACCEPTED должно быть значение True.
Использование
Рассмотрим пример, в котором NGINX Gateway Fabric будет принимать HTTP-трафик на одном внешнем IP-адресе и направлять запросы в два разных сервиса:
-
http://app.example.com/service1— в сервисservice1; -
http://app.example.com/service2— в сервисservice2.
Для примера создадим отдельный неймспейс:
kubectl create namespace nginx-gateway-example
Создание ConfigMap
Создайте файл configmap.yaml с HTML-страницами для двух сервисов:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-pages
namespace: nginx-gateway-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: nginx-gateway-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: nginx-gateway-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: nginx-gateway-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: nginx-gateway-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 nginx-gateway-example
Создание Gateway
Gateway описывает внешний вход в приложение. При стандартной установке NGINX Gateway Fabric обслуживает Gateway с gatewayClassName: nginx.
Создайте файл gateway.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
namespace: nginx-gateway-example
spec:
gatewayClassName: nginx
listeners:
- name: http
hostname: app.example.com
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
Примените манифест:
kubectl apply -f gateway.yaml
Когда Gateway будет создан, NGINX Gateway Fabric развернет NGINX data plane и балансировщик нагрузки в неймспейсе nginx-gateway-example. Проверить статус можно командой:
kubectl get gateway app-gateway -n nginx-gateway-example
Дождитесь, когда в колонке PROGRAMMED появится значение True, а в колонке ADDRESS — внешний IP-адрес.
Также можно посмотреть созданные ресурсы:
kubectl get deployments -n nginx-gateway-example kubectl get svc -n nginx-gateway-example
NGINX Gateway Fabric создает отдельный NGINX data plane для каждого Gateway. Поэтому отдельный манифест Service типа LoadBalancer, как в классическом сценарии с Ingress-контроллером, не требуется.
Создание HTTPRoute
HTTPRoute задает правила маршрутизации. Создайте файл httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
namespace: nginx-gateway-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 nginx-gateway-example -o yaml
В статусе ресурса должны быть условия:
status: "True"
type: Accepted
status: "True"
type: ResolvedRefs
В этом манифесте HTTPRoute принимает запросы с доменом app.example.com и направляет их в разные сервисы по префиксу пути. Фильтр URLRewrite заменяет префиксы /service1 и /service2 на /, чтобы NGINX внутри каждого сервиса отдавал свою главную страницу.
Проверка работы
Пропишите 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 nginx-gateway-example
Дополнение NGINX Gateway Fabric при этом останется установленным в кластере. Удалить его можно во вкладке «Дополнения» в панели управления кластером.
Миграция с Nginx Ingress на NGINX Gateway Fabric
NGINX Gateway Fabric можно развернуть рядом с Nginx Ingress и переносить маршруты постепенно. Такой подход позволяет сначала проверить ресурсы Gateway API на отдельном внешнем IP-адресе, а затем переключить DNS-записи или трафик на новый Gateway.
Для автоматической конвертации Ingress-ресурсов можно использовать утилиту ingress2gateway. Она читает существующие Ingress-ресурсы из кластера или из YAML-файлов и выводит эквивалентные ресурсы Gateway API: Gateway, HTTPRoute и другие объекты.
ingress2gateway помогает подготовить миграцию, но не заменяет ручную проверку. Некоторые аннотации Nginx Ingress могут быть не поддержаны или потребовать ручной настройки после конвертации.
Требования
Перед миграцией подготовьте кластер:
-
установите NGINX Gateway Fabric;
-
проверьте, что исходные Ingress-ресурсы работают через Nginx Ingress;
-
проверьте, что в кластере есть
GatewayClassс именемnginx.
Если Nginx Ingress установлен из панели управления Timeweb Cloud, для него используется IngressClass с именем nginx. Это имя понадобится при запуске ingress2gateway.
Проверьте классы:
kubectl get ingressclass kubectl get gatewayclass
В выводе должны быть:
-
IngressClassс именемnginx; -
GatewayClassс именемnginx.
Установка ingress2gateway
Если на локальной машине установлен Go, установите ingress2gateway командой:
go install github.com/kubernetes-sigs/ingress2gateway@v1.1.0
После установки бинарный файл будет доступен в директории $(go env GOPATH)/bin. Убедитесь, что эта директория добавлена в PATH.
Также можно установить ingress2gateway через Homebrew:
brew install ingress2gateway
Или скачать готовый бинарный файл со страницы релизов проекта.
Исходный пример
В примере ниже миграция выполняется для приложения, которое уже опубликовано через Nginx Ingress.
В кластере есть неймспейс ingress-migration-demo. В нем находятся:
-
Ingress migration-source;
-
Service
service1иservice2; -
два правила маршрутизации для домена
app.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 \
--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-ingress-class=nginx— выбирает только Ingress-ресурсы класса nginx. -
--namespace=ingress-migration-demo— ограничивает чтение ресурсов неймспейсомingress-migration-demo, где находится исходный Ingress из примера.
Откройте файл gateway-migration.yaml и проверьте сгенерированные ресурсы перед применением.
Проверьте gatewayClassName у ресурса Gateway. Для NGINX Gateway Fabric при стандартной установке значение должно быть nginx:
spec:
gatewayClassName: nginx
Также проверьте правила HTTPRoute. Некоторые Ingress-аннотации могут быть преобразованы в фильтры или типы совпадений, которые нужно скорректировать вручную. Например, для обычной маршрутизации по префиксу пути используйте PathPrefix:
rules:
- matches:
- path:
type: PathPrefix
value: /service1
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: service1
port: 80
Если в сгенерированном файле есть RegularExpression-маршруты или неподдержанные аннотации, проверьте их совместимость с NGINX Gateway Fabric и замените на поддерживаемые правила Gateway API.
Применение ресурсов 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 нового балансировщика.