Настройка HTTPS-доступа к приложению с помощью Gateway API, NGINX Gateway Fabric и cert-manager
Kubernetes Gateway API — это набор ресурсов Kubernetes для настройки маршрутизации входящего трафика к приложениям. Для работы Gateway API необходим контроллер, который реализует спецификацию Gateway API и управляет сетевой инфраструктурой. В этом руководстве используется контроллер NGINX Gateway Fabric.
Для организации HTTPS-доступа к приложению нужно выпустить TLS-сертификат и настроить его использование в ресурсе Gateway. Автоматизировать выпуск и продление сертификатов позволяет оператор cert-manager. В качестве центра сертификации в этом руководстве выступает Let’s Encrypt
Чтобы развернуть приложение и настроить HTTPS-доступ к нему через Gateway API с использованием сертификатов:
- Подготовьте окружение для работы с кластером Managed Kubernetes.
Перед началом работы
Заголовок раздела «Перед началом работы»Создайте сервисный аккаунт с именем
sa-mk8sи рольюregistry.puller.Для сервисного аккаунта
sa-mk8sсоздайте API-ключ и сохраните его.Создайте кластер Managed Kubernetes с публичным эндпоинтом и группу узлов для него. При создании группы используйте сервисный аккаунт
sa-mk8s.Создайте NAT-шлюз для подсети, в которой развернут кластер Managed Kubernetes.
Для прохождения руководства вам понадобится устройство, поддерживающее работу с командной строкой. Используйте личный компьютер или создайте промежуточную ВМ в той же сети, где расположен кластер Managed Kubernetes.
1. Подготовьте окружение
Заголовок раздела «1. Подготовьте окружение»Подключитесь к терминалу на вашем компьютере или к промежуточной ВМ.
Установите и настройте утилиту MWS CLI:
Аутентифицируйтесь в Artifact Registry:
bash helm registry login -u apikey -p <API-ключ> registry.mwsapis.ruУстановите утилиту командной строки
kubectl.
2. Установите Kubernetes Gateway API
Заголовок раздела «2. Установите Kubernetes Gateway API»Установите Gateway API:
bash kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yamlУбедитесь, что установка прошла успешно:
bash kubectl api-resources --api-group=gateway.networking.k8s.ioОжидаемый результат:
bash NAME SHORTNAMES APIVERSION NAMESPACED KINDbackendtlspolicies btlspolicy gateway.networking.k8s.io/v1 true BackendTLSPolicygatewayclasses gc gateway.networking.k8s.io/v1 false GatewayClassgateways gtw gateway.networking.k8s.io/v1 true Gatewaygrpcroutes gateway.networking.k8s.io/v1 true GRPCRoutehttproutes gateway.networking.k8s.io/v1 true HTTPRoutelistenersets lset gateway.networking.k8s.io/v1 true ListenerSetreferencegrants refgrant gateway.networking.k8s.io/v1 true ReferenceGranttlsroutes gateway.networking.k8s.io/v1 true TLSRoute
3. Разверните тестовое приложение
Заголовок раздела «3. Разверните тестовое приложение»Чтобы развернуть тестовое приложение httpbin в новом пространстве имен gateway-test, выполните команду:
kubectl apply -f - <<EOFapiVersion: v1kind: Namespacemetadata: name: gateway-test---apiVersion: v1kind: ServiceAccountmetadata: name: httpbin namespace: gateway-test
---apiVersion: v1kind: Servicemetadata: name: httpbin namespace: gateway-test labels: app: httpbin service: httpbinspec: ports: - name: http port: 8000 targetPort: 8080 selector: app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata: name: httpbin namespace: gateway-testspec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: registry.mwsapis.ru/mws-mk8s-images/customer/go-httpbin:v2.15.0 imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 8080EOFОжидаемый результат:
namespace/gateway-test createdserviceaccount/httpbin createdservice/httpbin createddeployment.apps/httpbin created4. Установите контроллер NGINX Gateway Fabric
Заголовок раздела «4. Установите контроллер NGINX Gateway Fabric»Установите NGINX Gateway Fabric:
bash helm upgrade --install ngf oci://registry.mwsapis.ru/mws-mk8s-images/customer/charts/nginx-gateway-fabric \--version 2.4.2 \--create-namespace \-n nginx-gateway \--set nginx.service.externalTrafficPolicy=ClusterОжидаемый результат:
bash NAME: ngfLAST DEPLOYED: Tue Jun 16 20:55:50 2026NAMESPACE: nginx-gatewaySTATUS: deployedREVISION: 1TEST SUITE: NoneУбедитесь, что контроллер запущен:
bash kubectl -n nginx-gateway get podsОжидаемый результат:
bash NAME READY STATUS RESTARTS AGEngf-nginx-gateway-fabric-6b6d84fb47-t7dzr 1/1 Running 0 2m3s
5. Установите cert-manager
Заголовок раздела «5. Установите cert-manager»Установите cert-manager:
bash helm upgrade --install cert-manager oci://registry.mwsapis.ru/mws-mk8s-images/customer/charts/cert-manager \--version v1.20.0 \--namespace cert-manager \--create-namespace \--set crds.enabled=true \--set config.enableGatewayAPI=trueУбедитесь, что установка прошла успешно:
bash kubectl get pods -n cert-managerОжидаемый результат:
bash NAME READY STATUS RESTARTS AGEcert-manager-6ff98c57db-2rjpg 1/1 Running 0 10mcert-manager-cainjector-7ccc4cf444-hrxlg 1/1 Running 0 10mcert-manager-webhook-67f6dbc76f-jz4rh 1/1 Running 0 10m
6. Создайте ресурс ClusterIssuer
Заголовок раздела «6. Создайте ресурс ClusterIssuer»Оператор cert-manager использует ресурс ClusterIssuer для выпуска сертификатов через Let’s Encrypt. Сертификаты выпускаются после прохождения проверки HTTP-01.
Создайте ресурс ClusterIssuer:
cat <<EOF > clusterissuer.yamlapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencryptspec: acme: email: <адрес электронной почты для уведомлений> server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: issuer-account-key solvers: - http01: gatewayHTTPRoute: {}EOFkubectl apply -f clusterissuer.yamlОжидаемый результат:
clusterissuer.cert-manager.io/letsencrypt createdЕсли сертификаты требуются только в одном пространстве имен, вместо ClusterIssuer используйте ресурс Issuer.
7. Создайте ресурсы Gateway и HTTPRoute
Заголовок раздела «7. Создайте ресурсы Gateway и HTTPRoute»Ресурс Gateway определяет правила приема входящего трафика, а ресурс HTTPRoute — правила маршрутизации входящего трафика к приложениям, запущенным в кластере.
Создайте ресурс
Gatewayв пространстве именgateway-test, в котором развернуто тестовое приложение:bash cat <<EOF > gateway.yamlapiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: httpbin-gateway-nginx-httpsnamespace: gateway-testannotations:cert-manager.io/cluster-issuer: letsencryptspec:gatewayClassName: nginxlisteners:- name: httphostname: <доменное имя>port: 80protocol: HTTPallowedRoutes:namespaces:from: All- name: httpshostname: <доменное имя>port: 443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:# cert-manager автоматически создаст секрет, где будет храниться сертификат- name: httpbin-tls-secretkind: SecretEOFkubectl apply -f gateway.yamlОжидаемый результат:
bash gateway.gateway.networking.k8s.io/httpbin-gateway-nginx-https createdПодробнее конфигурация ресурса
Gatewayописана в официальной документации.
После создания ресурса
Gatewayконтроллер автоматически создаст сервис типаLoadBalancer(балансировщик нагрузки). Если вы хотите закрепить за балансировщиком внешний IP-адрес, зарезервируйте его и добавьте вspec.infrastructureаннотацию:yaml infrastructure:annotations:mk8s.mws.ru/load-balancer-external-ip-name: <имя зарезервированного внешнего IP-адреса>Создайте ресурс
HTTPRouteв пространстве именgateway-test, в котором развернуто тестовое приложение:bash cat <<EOF > HTTPRoute.yamlapiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata:name: httpbin-nginx-httpsnamespace: gateway-testspec:hostnames:- <доменное имя>parentRefs:- name: httpbin-gateway-nginx-httpssectionName: http- name: httpbin-gateway-nginx-httpssectionName: httpsrules:- matches:- path:type: PathPrefixvalue: /statusbackendRefs:- name: httpbinport: 8000weight: 1EOFkubectl apply -f HTTPRoute.yamlОжидаемый результат:
bash httproute.gateway.networking.k8s.io/httpbin-nginx-https createdПодробнее конфигурация ресурса
HTTPRouteописана в официальной документации.
8. Создайте правило файрвола
Заголовок раздела «8. Создайте правило файрвола»Let’s Encrypt валидирует сертификаты (проверка HTTP-01) через HTTP-запросы на порт 80 с разных IP-адресов своей инфраструктуры, и эти IP-адреса не раскрываются. Для прохождения проверки HTTP-01 нужно разрешить доступ к порту TCP:80 из всего интернета.
Узнайте, какой порт на узлах кластера соответствует порту
80балансировщика:bash kubectl get svc httpbin-gateway-nginx-https-nginxОжидаемый результат:
bash NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhttpbin-gateway-nginx-https-nginx LoadBalancer 10.22.119.230 2.59.82.255 80:30960/TCP,443:32179/TCP 21hЗдесь:
EXTERNAL-IP— внешний IP-адрес балансировщика;PORT(S)— порты, на которых балансировщик принимает трафик, и соответствующие им порты на рабочих узлах кластера (NodePort).
Создайте правило файрвола со следующими параметрами:
- Направление трафика —
Ingress. - Действие в рамках правила —
Allow. - Источник трафика —
0.0.0.0/0. - Назначение трафика — CIDR подсети, в которой расположен кластер Managed Kubernetes.
- Протокол — TCP.
- Порт — порт на узлах кластера (
NodePort), соответствующий порту80. В этом примере —30960. - Опция Активировать правило сразу после сохранения — включена.
9. Проверьте результат
Заголовок раздела «9. Проверьте результат»Убедитесь, что оператор cert-manager запросил выпуск сертификата от Let’s Encrypt:
bash kubectl get certificaterequests.cert-manager.io -n gateway-testОжидаемый результат:
bash NAME APPROVED DENIED READY ISSUER REQUESTER AGEhttpbin-tls-secret-1 True True letsencrypt system:serviceaccount:cert-manager:cert-manager 89mУбедитесь, что сертификат выпущен:
bash kubectl get certificate -n gateway-testОжидаемый результат:
bash NAME READY SECRET AGEhttpbin-tls-secret True httpbin-tls-secret 86mУбедитесь, что секрет создан и содержит сертификат:
bash kubectl get secrets httpbin-tls-secret -n gateway-testОжидаемый результат:
bash NAME TYPE DATA AGEhttpbin-tls-secret kubernetes.io/tls 2 86mУбедитесь, что тестовое приложение доступно по HTTPS:
bash curl -I https://<доменное имя>/status/200Ожидаемый результат:
bash HTTP/2 200server: nginxЗапросите информацию о сертификате:
bash openssl s_client -connect <доменное имя>:443 -servername <доменное имя> </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltNameОжидаемый результат:
bash subject=CN = <доменное имя>issuer=C = US, O = Let's Encrypt, CN = R12notBefore=Mar 25 10:02:26 2026 GMTnotAfter=Jun 23 10:02:25 2026 GMTX509v3 Subject Alternative Name:DNS:<доменное имя>
Удалите платные ресурсы
Заголовок раздела «Удалите платные ресурсы»Ресурсы, созданные в руководстве, тарифицируются. Если вы больше не планируете использовать их:
- Удалите промежуточную ВМ, если вы ее создавали.