Setting up Gateway API
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 Gateway API. For this you will need to create a public domain zone and delegate the domain to Yandex Cloud DNS.
To integrate Gateway API and Application Load Balancer:
- Create Managed Service for Kubernetes resources.
- Install Gateway API and set up the domain zones.
- Prepare test applications.
- Create test applications.
- Test 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 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 a node group in any suitable configuration. When creating them, specify the security groups prepared earlier.
-
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 Gateway API:
-
Assign the following roles to it:
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 according to the instructions. 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 <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'
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
Prepare 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
: Settings for the Gateway. In these manifest files, specify:- Security groups in which your Kubernetes cluster is deployed in the
metadata.annotations.gateway.alb.yc.io/security-groups
parameter. - Domain zone, with the
*.dev
and*.prod
prefixes in thehostname
parameters. - IP addresses for the
dev
andprod
environments in thespec.addresses.value
parameter.
- Security groups in which your Kubernetes cluster is deployed in the
dev-route.yaml
andprod-route.yaml
: Routing settings for the applications. In these manifests, you need to specify the domain 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:- Namespace (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: <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 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.<domain_zone>" 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: <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 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.<domain_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 application pods have entered the
Running
state: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 Gateway API
To test 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. 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. -