Setting up the Gateway API
Gateway API
In this tutorial, you will learn how to set up access to the applications deployed in two test environments, dev and prod, using Yandex Application Load Balancer via the Gateway API. For this, you will need to create a public domain zone and delegate the domain to Yandex Cloud DNS.
To integrate the Gateway API and Application Load Balancer:
- Create Managed Service for Kubernetes resources.
- Install the Gateway API and set up domain zones.
- Prepare test applications.
- Create test applications.
- Test the Gateway API.
If you no longer need the resources you created, delete them.
Required paid resources
The support cost for this solution includes:
- Fee for a DNS zone and DNS requests (see Cloud DNS pricing).
- Fee for using the master and outgoing traffic in a Managed Service for Kubernetes cluster (see Managed Service for Kubernetes pricing).
- Fee for using computing resources, OS, and storage in cluster nodes (VMs) (see Compute Cloud pricing).
- Fee for using L7 load balancer's computing resources (see Application Load Balancer pricing).
- Fee for public IP addresses (see Virtual Private Cloud pricing).
Getting started
-
If you do not have the Yandex Cloud CLI installed yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the
yc config set folder-id <folder_ID>command. You can also set a different folder for any specific command using the--folder-nameor--folder-idparameter.
Create Managed Service for Kubernetes resources
-
Create a Kubernetes cluster and node group.
ManuallyTerraform-
If you do not have a network yet, create one.
-
If you do not have any subnets yet, create them in the availability zones where the new Kubernetes cluster and node group will reside.
-
Create security groups for the Managed Service for Kubernetes cluster and its node groups.
Warning
The configuration of security groups determines the performance and availability of the cluster and the services and applications running in it.
-
Create a Kubernetes cluster and node group with any suitable configuration. When creating, specify the preconfigured security groups.
-
If you do not have Terraform yet, install it.
-
Get the authentication credentials. You can add them to environment variables or specify them later in the provider configuration file.
-
Configure and initialize a provider. There is no need to create a provider configuration file manually, you can download it
. -
Place the configuration file in a separate working directory and specify the parameter values. If you did not add the authentication credentials to environment variables, specify them in the configuration file.
-
Download the k8s-gateway-api.tf
cluster configuration file to the same working directory. This file describes:-
Network.
-
Subnet.
-
Kubernetes cluster.
-
Service account for the Kubernetes cluster and node group.
-
Security groups which contain rules required for the Managed Service for Kubernetes cluster and its node groups.
Warning
The configuration of security groups determines the performance and availability of the cluster and the services and applications running in it.
-
-
Specify the following in the configuration file:
- Folder ID.
- Kubernetes version for the Kubernetes cluster and node groups.
- Kubernetes cluster CIDR.
-
Make sure the Terraform configuration files are correct using this command:
terraform validateTerraform will show any errors found in your configuration files.
-
Create the required infrastructure:
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
All the required resources will be created in the specified folder. You can check resource availability and their settings in the management console
. -
-
-
Install kubect
and configure it to work with the new cluster. -
Create a service account for the Gateway API.
-
Assign it the following roles:
alb.editor: To create the required resources.certificate-manager.admin: To use certificates registered in Yandex Certificate Manager.compute.viewer: To use Managed Service for Kubernetes cluster nodes in the load balancer target groups.vpc.publicAdmin: To manage external connectivity.
-
Create a static key and save it to a file named
sa-key.json:yc iam key create \ --service-account-name <name_of_service_account_for_Gateway_API> \ --output sa-key.json
Install the Gateway API and set up domain zones
-
Install the Gateway API by following this guide. During the installation, use the service account key you created earlier.
-
Reserve public IP addresses for the
prodanddevtest environments:yc vpc address create \ --name=prod \ --labels reserved=true \ --external-ipv4 \ zone=<availability_zone> && \ yc vpc address create \ --name=dev \ --labels reserved=true \ --external-ipv4 \ zone=<availability_zone>Where
<availability_zone>is the availability zone hosting your Kubernetes cluster.Save the public IP addresses, as you will need them in the next configuration steps.
-
Add resource records for your public DNS zone:
yc dns zone add-records \ --name <DNS_zone_name> \ --record '*.prod 60 A <prod_environment_IP_address>' && \ yc dns zone add-records \ --name <DNS_zone_name> \ --record '*.dev 60 A <dev_environment_IP_address>'Example of a valid command:
yc dns zone add-records \ --name my-domain-name \ --record '*.dev 60 A 171.154.241.41' -
Create a namespace for TLS secrets:
kubectl create namespace gateway-api-tls-secrets -
Create OpenSSL certificates:
openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-prod.pem \ -out gateway-cert-prod.pem \ -nodes \ -days 365 \ -subj '/CN=*.prod.<domain_zone>' && \ openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-dev.pem \ -out gateway-cert-dev.pem \ -nodes \ -days 365 \ -subj '/CN=*.dev.<domain_zone>'Example of a valid command:
openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-prod.pem \ -out gateway-cert-prod.pem \ -nodes \ -days 365 \ -subj '/CN=*.prod.my-test-domain.com'These certificates will be used to create secrets for the
prodanddevtest environments in the Kubernetes cluster. -
Create the secrets:
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
Prepare test applications
To test the Gateway API, we will build two applications, tutum/hello-world and nginxdemos/hello. For each application, you will need to configure and run three YAML files:
dev-gw.yamlandprod-gw.yamlwith Gateway settings. In these manifests, specify:- Security groups associated with your Kubernetes cluster in the
metadata.annotations.gateway.alb.yc.io/security-groupsparameter. - Domain zone with the
*.devand*.prodprefixes in thehostnameparameters. - IP addresses for the
devandprodenvironments in thespec.addresses.valueparameter.
- Security groups associated with your Kubernetes cluster in the
dev-route.yamlandprod-route.yamlto configure routing for the applications. In these manifests, you need to specify the domain zone with theapp.devandapp.prodprefixes in thespec.hostnamesparameter.dev-app.yamlandprod-app.yamlwith the applications’ settings. These manifests will be used to create:- Namespace (unique for each application)
- Deployment
for the application - Service
Configure the app for the dev environment
-
Create
dev-gw.yaml:dev-gw.yaml
--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway-api-dev annotations: gateway.alb.yc.io/security-groups: <cluster_security_group_IDs> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-dev protocol: HTTP port: 80 hostname: "*.dev.<domain_zone>" 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.<domain_zone>" 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: "<dev_environment_IP_address>" -
Create
dev-route.yaml:dev-route.yaml
--- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: dev-app-http-route namespace: dev-app spec: hostnames: - "app.dev.<domain_zone>" parentRefs: - name: gateway-api-dev namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80 -
Create
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
Configure the app for the prod environment
-
Create
prod-gw.yaml:prod-gw.yaml
--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway-api-prod annotations: gateway.alb.yc.io/security-groups: <cluster_security_group_IDs> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-prod protocol: HTTP port: 80 hostname: "*.prod.<domain_zone>" 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.<domain_zone>" 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: "<prod_environment_IP_address>" -
Create
prod-route.yaml:prod-route.yaml
--- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: prod-app-http-route namespace: prod-app spec: hostnames: - "app.prod.<domain_zone>" parentRefs: - name: gateway-api-prod namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80 -
Create
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
Create test applications
-
To install the applications, run this command:
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 -
Make sure the app pods switched to
Running:kubectl get pods --namespace dev-app && \ kubectl get pods --namespace prod-app -
Make sure a load balancer has been created for the Gateway API:
yc application-load-balancer load-balancer listNote
It may take several minutes to create the load balancer.
Test the Gateway API
To test the Gateway API, open these links in your browser:
app.prod.<domain_zone>.app.dev.<domain_zone>.
Note
Delete the resources you created
Some resources are not free of charge. Delete the resources you no longer need to avoid paying for them:
-
In the terminal window, go to the directory containing the infrastructure plan.
Warning
Make sure the directory has no Terraform manifests with the resources you want to keep. Terraform deletes all resources that were created using the manifests in the current directory.
-
Delete resources:
-
Run this command:
terraform destroy -
Confirm deleting the resources and wait for the operation to complete.
All the resources described in the Terraform manifests will be deleted.
-