Setting up the Gateway API
The Gateway API
In this tutorial, you will learn how to enable access to the applications deployed in two test environments, dev
and prod
, by running Yandex Application Load Balancer with 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 the domain zones
- Provision the test applications
- Create test applications
- Test the Gateway API
If you no longer need the resources you created, delete them.
Getting started
-
If you do not have the Yandex Cloud command line interface yet, install and initialize it.
The folder specified in the CLI profile is used by default. You can specify a different folder using the
--folder-name
or--folder-id
parameter.
Create Managed Service for Kubernetes resources
-
Create a Kubernetes cluster and a group of nodes.
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 your Kubernetes cluster and node group will be created.
-
Create a Kubernetes cluster and a node group in any suitable configuration.
-
Configure 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.
-
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. The file describes:-
Network.
-
Subnet.
-
Kubernetes cluster.
-
Service account required for the Kubernetes cluster and node group to operate.
-
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 validate
If there are any errors in the configuration files, Terraform will point them out.
-
Create the required infrastructure:
-
Run the command to view planned changes:
terraform plan
If the resource configuration descriptions are correct, the terminal will display a list of the resources to modify and their parameters. This is a test step. No resources are updated.
-
If you are happy with the planned changes, apply them:
-
Run the command:
terraform apply
-
Confirm the update of 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 kubectl
and configure it to work with the created cluster. -
Create a service account required 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 the domain zones
-
Install the Gateway API application by following the guide. During the installation, use the service account key issued previously.
-
Reserve the public IP addresses for the
prod
anddev
test 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: you will need them to continue the setup.
-
Add resource records for your public DNS zone:
yc dns zone add-records \ --name <name_of_your_DNS_zone> \ --record '*.prod.<name_of_your_DNS_zone> 60 A <prod_environment_IP_address>' && \ yc dns zone add-records \ --name <name_of_your_DNS_zone> \ --record '*.dev.<name_of_your_DNS_zone> 60 A <dev_environment_IP_address>'
Example of a valid command:
yc dns zone add-records \ --name my-test-domain.com \ --record '*.dev.my-test-domain.com 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.<name_of_your_DNS_zone>' && \ openssl req -x509 \ -newkey rsa:4096 \ -keyout gateway-key-dev.pem \ -out gateway-cert-dev.pem \ -nodes \ -days 365 \ -subj '/CN=*.dev.<name_of_your_DNS_zone>'
Based on these certificates, secrets will be created for the
prod
anddev
test 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
Provision the test applications
Two applications will be created to test the Gateway API (tutum/hello-world
and nginxdemos/hello
). For each application, you will need to configure and run three YAML files.
dev-gw.yaml
andprod-gw.yaml
are the settings for the Gateway. In these manifest files, specify:- The security group in which your Kubernetes cluster is deployed, in the
metadata.annotations.gateway.alb.yc.io/security-groups
parameter. - The name of your DNS zone, with the prefixes
*.dev
and*.prod
, in thehostname
parameters. - IP addresses for the
dev
andprod
environmentsspec.addresses.value
.
- The security group in which your Kubernetes cluster is deployed, in the
dev-route.yaml
andprod-route.yaml
: Routing setup for the applications. In these manifests, you need to specify the name of your DNS zone with theapp.dev
andapp.prod
prefixes in thespec.hostnames
parameter.dev-app.yaml
andprod-app.yaml
: Settings for the applications. These manifests will be used to create:- A namespace (it's unique for each application).
- Deployment
for the application. - Service.
Configure the application for the dev environment
-
Create the
dev-gw.yaml
manifest file:dev-gw.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: Gateway metadata: name: gateway-api-dev annotations: gateway.alb.yc.io/security-groups: <security_group_in_the_cluster> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-dev protocol: HTTP port: 80 hostname: "*.dev.<name_of_your_DNS_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.<name_of_your_DNS_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: <IP_address_for_the_dev_environment>
-
Create the
dev-route.yaml
file:dev-route.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: dev-app-http-route namespace: dev-app spec: hostnames: - "app.dev.<your_DNS_zone_name>" parentRefs: - name: gateway-api-dev namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80
-
Create the
dev-app.yaml
manifest file: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 application for the prod environment
-
Create the
dev-prod.yaml
manifest file:prod-gw.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: Gateway metadata: name: gateway-api-prod annotations: gateway.alb.yc.io/security-groups: <security_group_in_the_cluster> spec: gatewayClassName: yc-df-class listeners: - name: gateway-api-prod protocol: HTTP port: 80 hostname: "*.prod.<name_of_your_DNS_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.<name_of_your_DNS_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: <IP_address_for_the_dev_environment>
-
Create the
prod-route.yaml
manifest file:prod-route.yaml--- apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: prod-app-http-route namespace: prod-app spec: hostnames: - "app.prod.<name_of_your_DNS_zone>" parentRefs: - name: gateway-api-prod namespace: default rules: - matches: - path: value: / backendRefs: - name: app port: 80
-
Create the
prod-app.yaml
manifest file: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 that the pods of your applications have changed their status to
Running
:kubectl get pods --namespace dev-app && \ kubectl get pods --namespace prod-app
-
Make sure that a load balancer has been created for the Gateway API:
yc application-load-balancer load-balancer list
Note
It may take several minutes to create the load balancer.
Test the Gateway API
To test your Gateway API operation, follow these links in your browser:
app.prod.<name_of_your_DNS_zone>
dev.prod.<name_of_your_DNS_zone>
Note
Delete the resources you created
Some resources are not free of charge. To avoid paying for them, delete the resources you no longer need:
-
In the command line, go to the directory with the current Terraform configuration file with an infrastructure plan.
-
Delete the
k8s-gateway-api.tf
configuration file. -
Make sure the Terraform configuration files are correct using this command:
terraform validate
If there are any errors in the configuration files, Terraform will point them out.
-
Confirm updating the resources.
-
Run the command to view planned changes:
terraform plan
If the resource configuration descriptions are correct, the terminal will display a list of the resources to modify and their parameters. This is a test step. No resources are updated.
-
If you are happy with the planned changes, apply them:
-
Run the command:
terraform apply
-
Confirm the update of resources.
-
Wait for the operation to complete.
-
All the resources described in the
k8s-gateway-api.tf
configuration file will be deleted. -