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 network traffic of your Managed Service for Kubernetes cluster.
- Create a rule for connecting to the services from the internet, then apply it to the cluster's node group.
-
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.
- Security group and rules required for cluster and node group operation:
- Rules for service traffic.
- Rules for accessing the Kubernetes API and managing a cluster with
kubectl
through ports443
and6443
. - Rules for accessing services from the Internet.
- Kubernetes cluster.
- Service account required to use the Kubernetes cluster and node group.
-
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>
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. -