Настройка Gateway API
Gateway API — набор ресурсов API, моделирующих сетевое взаимодействие в кластере Kubernetes.
Из этой статьи вы узнаете, как организовать доступ к приложениям, находящимся в двух тестовых средах dev
и prod
, с помощью Yandex Application Load Balancer через Gateway API. Для этого потребуется создать публичную доменную зону и делегировать домен сервису Yandex Cloud DNS.
Чтобы интегрировать Gateway API и Application Load Balancer:
- Создайте ресурсы Managed Service for Kubernetes.
- Установите Gateway API и настройте доменные зоны.
- Подготовьте тестовые приложения.
- Создайте тестовые приложения.
- Проверьте работу Gateway API.
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
-
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра
--folder-name
или--folder-id
. -
Зарегистрируйте публичную доменную зону и делегируйте домен.
Создайте ресурсы Managed Service for Kubernetes
-
Создайте кластер и группу узлов Kubernetes.
ВручнуюС помощью Terraform- Если у вас еще нет сети, создайте ее.
- Если у вас еще нет подсетей, создайте их в зонах доступности, где будут созданы кластер Kubernetes и группа узлов.
- Создайте кластер Kubernetes и группу узлов любой подходящей конфигурации.
- Создайте правило для подключения к сервисам из интернета и примените его к группе узлов кластера.
-
Если у вас еще нет Terraform, установите его.
-
Скачайте файл с настройками провайдера. Поместите его в отдельную рабочую директорию и укажите значения параметров.
-
Скачайте в ту же рабочую директорию файл конфигурации кластера k8s-gateway-api.tf. В файле описаны:
- Сеть.
- Подсеть.
- Группа безопасности и правила, необходимые для работы кластера, группы узлов и инстанса Kubernetes:
- Правила для служебного трафика.
- Правила для доступа к API Kubernetes и управления кластером с помощью
kubectl
через порты 443 и 6443. - Правила для доступа к сервисам из интернета.
- Кластер Kubernetes.
- Сервисный аккаунт, необходимый для работы кластера и группы узлов Kubernetes.
-
Укажите в файле конфигурации:
- Идентификатор каталога.
- Версию Kubernetes для кластера и групп узлов Kubernetes.
- CIDR кластера Kubernetes.
-
Выполните команду
terraform init
в директории с конфигурационными файлами. Эта команда инициализирует провайдер, указанный в конфигурационных файлах, и позволяет работать с ресурсами и источниками данных провайдера. -
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Создайте необходимую инфраструктуру:
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления.
-
-
Установите kubectl и настройте его на работу с созданным кластером.
-
Создайте сервисный аккаунт, необходимый для работы Gateway API.
-
alb.editor
— для создания необходимых ресурсов.certificate-manager.admin
— для работы с сертификатами, зарегистрированными в сервисе Yandex Certificate Manager.compute.viewer
— для использования узлов кластера Managed Service for Kubernetes в целевых группах балансировщика нагрузки.vpc.publicAdmin
— для управления внешней связностью.
-
Создайте для него статический ключ и сохраните в файл
sa-key.json
:yc iam key create \ --service-account-name <имя сервисного аккаунта для Gateway API> \ --output sa-key.json
Установите Gateway API и настройте доменные зоны
-
Установите приложение Gateway API с помощью инструкции. При установке используйте ключ сервисного аккаунта, созданный ранее.
-
Зарезервируйте публичные IP-адреса для тестовых сред
prod
иdev
:yc vpc address create \ --name=prod \ --labels reserved=true \ --external-ipv4 \ zone=<зона доступности> && \ yc vpc address create \ --name=dev \ --labels reserved=true \ --external-ipv4 \ zone=<зона доступности>
Где
зона доступности
— зона доступности, в которой расположен ваш кластер Kubernetes.Сохраните публичные IP-адреса — они понадобятся для дальнейшей настройки.
-
Создайте ресурсные записи для вашей публичной DNS-зоны:
yc dns zone add-records \ --name <имя вашей DNS-зоны> \ --record '*.prod.<имя вашей DNS-зоны> 60 A <IP-адрес для среды prod>' && \ yc dns zone add-records \ --name <имя вашей DNS-зоны> \ --record '*.dev.<имя вашей DNS-зоны> 60 A <IP-адрес для среды dev>'
Пример корректной команды:
yc dns zone add-records \ --name my-test-domain.com \ --record '*.dev.my-test-domain.com 60 A 171.154.241.41'
-
Создайте пространство имен для TLS-секретов:
kubectl create namespace gateway-api-tls-secrets
-
Создайте сертификаты OpenSSL:
openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-prod.pem \ -out gateway-cert-prod.pem \ -nodes \ -days 365 \ -subj '/CN=*.prod.<имя вашей DNS-зоны>' && \ openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-dev.pem \ -out gateway-cert-dev.pem \ -nodes \ -days 365 \ -subj '/CN=*.dev.<имя вашей DNS-зоны>'
На основании этих сертификатов в кластере Kubernetes будут созданы секреты для тестовых сред
prod
иdev
. -
Создайте секреты:
kubectl create -n gateway-api-tls-secrets secret tls gateway-prod-tls \ --cert=gateway-cert-prod.pem \ --key=gateway-key-prod.pem && \ kubectl create -n gateway-api-tls-secrets secret tls gateway-dev-tls \ --cert=gateway-cert-dev.pem \ --key=gateway-key-dev.pem
Подготовьте тестовые приложения
Для проверки работы Gateway API будут созданы два приложения (tutum/hello-world
и nginxdemos/hello
). Для каждого приложения понадобится настройка и выполнение трех YAML-файлов:
dev-gw.yaml
иprod-gw.yaml
— настройки Gateway. В этих манифестах нужно указать:- Группу безопасности, в которой развернут ваш кластер Kubernetes, в параметре
metadata.annotations.gateway.alb.yc.io/security-groups
. - Имя вашей DNS-зоны с префиксами
*.dev
и*.prod
в параметрахhostname
. - IP-адреса для сред
dev
иprod
в параметреspec.addresses.value
.
- Группу безопасности, в которой развернут ваш кластер Kubernetes, в параметре
dev-route.yaml
иprod-route.yaml
— настройка маршрутизации для приложений. В этих манифестах нужно указать имя вашей DNS-зоны с префиксамиapp.dev
иapp.prod
в параметреspec.hostnames
.dev-app.yaml
иprod-app.yaml
— настройки приложений. С помощью этих манифестов будут созданы:- Пространство имен (уникальное для каждого приложения).
- Deployment приложения.
- Сервис.
Настройте приложение для среды dev
-
Создайте манифест
dev-gw.yaml
:dev-gw.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: Gateway metadata: name: gateway-api-dev annotations: gateway.alb.yc.io/security-groups: <группа безопасности кластера> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-dev protocol: HTTP port: 80 hostname: "*.dev.<имя вашей DNS-зоны>" allowedRoutes: namespaces: from: Selector selector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - dev-app - name: gateway-api-dev-tls protocol: HTTPS port: 443 hostname: "*.dev.<имя вашей DNS-зоны>" allowedRoutes: namespaces: from: Selector selector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - dev-app tls: certificateRefs: - group: "" kind: Secret name: gateway-dev-tls namespace: gateway-api-tls-secrets mode: Terminate addresses: - type: IPAddress value: <IP-адрес для среды dev>
-
Создайте файл
dev-route.yaml
:dev-route.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: dev-app-http-route namespace: dev-app spec: hostnames: - "app.dev.<имя вашей DNS-зоны>" parentRefs: - name: gateway-api-dev namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80
-
Создайте манифест
dev-app.yaml
:dev-app.yaml--- apiVersion: v1 kind: Namespace metadata: name: dev-app --- apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: dev-app spec: selector: matchLabels: app: app template: metadata: labels: app: app spec: containers: - name: app image: tutum/hello-world resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: app namespace: dev-app spec: type: NodePort selector: app: app ports: - port: 80 targetPort: 80
Настройте приложение для среды prod
-
Создайте манифест
prod-gw.yaml
:prod-gw.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: Gateway metadata: name: gateway-api-prod annotations: gateway.alb.yc.io/security-groups: <группа безопасности кластера> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-prod protocol: HTTP port: 80 hostname: "*.prod.<имя вашей DNS-зоны>" allowedRoutes: namespaces: from: Selector selector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - prod-app - name: gateway-api-prod-tls protocol: HTTPS port: 443 hostname: "*.prod.<имя вашей DNS-зоны>" allowedRoutes: namespaces: from: Selector selector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - prod-app tls: certificateRefs: - group: "" kind: Secret name: gateway-prod-tls namespace: gateway-api-tls-secrets mode: Terminate addresses: - type: IPAddress value: <IP-адрес для среды prod>
-
Создайте манифест
prod-route.yaml
:prod-route.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: prod-app-http-route namespace: prod-app spec: hostnames: - "app.prod.<имя вашей DNS-зоны>" parentRefs: - name: gateway-api-prod namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80
-
Создайте манифест
prod-app.yaml
:prod-app.yaml--- apiVersion: v1 kind: Namespace metadata: name: prod-app --- apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: prod-app spec: selector: matchLabels: app: app template: metadata: labels: app: app spec: containers: - name: app image: tutum/hello-world resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: app namespace: prod-app spec: type: NodePort selector: app: app ports: - port: 80 targetPort: 80
Создайте тестовые приложения
-
Для установки приложений выполните команду:
kubectl apply -f prod-gw.yaml && \ kubectl apply -f prod-app.yaml && \ kubectl apply -f prod-route.yaml && \ kubectl apply -f dev-gw.yaml && \ kubectl apply -f dev-app.yaml && \ kubectl apply -f dev-route.yaml
-
Убедитесь, что поды приложений перешли в состояние
Running
:kubectl get pods --namespace dev-app && \ kubectl get pods --namespace prod-app
-
Убедитесь, что для Gateway API создан балансировщик нагрузки:
yc application-load-balancer load-balancer list
Примечание
Создание балансировщика нагрузки может занять несколько минут.
Проверьте работу Gateway API
Для проверки работы Gateway API перейдите по ссылкам в браузере:
app.prod.<имя вашей DNS-зоны>
.dev.prod.<имя вашей DNS-зоны>
.
Удалите созданные ресурсы
Если созданные ресурсы вам больше не нужны, удалите их:
-
В командной строке перейдите в директорию, в которой расположен актуальный конфигурационный файл Terraform с планом инфраструктуры.
-
Удалите конфигурационный файл
k8s-gateway-api.tf
. -
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Подтвердите изменение ресурсов.
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
Все ресурсы, которые были описаны в конфигурационном файле
k8s-gateway-api.tf
, будут удалены. -