Monday, May 6, 2024
No menu items!
HomeCloud ComputingModular GKE Ingress with the Gateway API

Modular GKE Ingress with the Gateway API

Objective   

Gateway API for Kubernetes Ingress can handle a wider set of functionalities than that of original Kubernetes Ingress. In this blog we will have a look at the implementation of  Gateway on Google Kubernetes Engine(GKE). We will see how to initially set it up, and monitor it in GKE. We will also look at setting up some security in the form of a GCP Gateway Policy.

Introduction

NodePort and LoadBalancer service objects initially provided exposure of Kubernetes services to the outside world. Later, Ingress was developed, which routes traffic to services controlled by rules defined on the Ingress resource. The Kubernetes Gateway API is an evolution of Ingress, delivering the same function but as a superset of the Ingress capabilities. 

The GKE Gateway controller is Google’s implementation of the Gateway API for Load Balancing. The Gateway controller watches for Gateway API resources and reconciles Cloud Load Balancing resources to implement the networking behavior specified by the Gateway resources. The GKE Gateway controller supports multi-tenant usage of a load balancer, shared across Namespaces, clusters, and regions. 

With Gateway API, ingress implementation is broken into discrete resources including. This allows federation of components aligned with roles/teams. So, GatewayClasses are provided by the platform (see GatewayClasses on GKE). Cluster Operators provision a Gateway. Application teams can expose their applications by deploying HTTPRoutes independently and attaching them securely to the Gateway. See diagram below.

What do we want to do?

We want to set up external ingress to our sample web application running in GKE called twsttech.io using GKE Gateway. We need to:

create a global Gateway, based on the external L7 Gateway Class – referencing a certificate mapping

create a HTTPRoute, based on the root path to our application. 

create an SSL based GatewayPolicy to restrict tls to v1.2, referencing a previously generated SSL policy. 

We also want to understand a bit more about the specifications of the above resources and how they can be configured for use in different GKE ingress use cases. 

The following prerequisites are focused on ingress security rather than actual Gateway implementation and so are outside the scope of this blog:

Set the external domain name with static IP, 

Create a domain certificate

a certificate mapping created using Google Certificate manager 

An SSL policy to enforce tls version

Getting started

Let’s enable the Gateway API in our cluster. Ours is an existing GKE standard cluster, so we need to run the following command:

code_block[StructValue([(u’code’, u’gcloud container clusters create gke-std-001 \rn –gateway-api=standard \rn –cluster-version=1.24 \rn –location=europe-west1′), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f1d1e390>)])]

To enable the Gateway API on other GKE clusters types, follow the documentation Enable the Gateway API in your cluster.

Confirm that the Gateway classes are installed in your cluster:

code_block[StructValue([(u’code’, u’kubectl get gatewayclass’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e9419a2bbd0>)])]

Output should look like this (truncated for brevity):

code_block[StructValue([(u’code’, u’NAME CONTROLLER ACCEPTED AGErngke-l7-global-external-managed networking.gke.io/gateway True 3m’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e9419a2b090>)])]
code_block[StructValue([(u’code’, u’Note: To use GKE Gateway controller, the following requirements are needed:rnGKE cluster type: Standard: 1.24 or later; Autopilot: 1.26 or laterrnrnPlease check out the other Gateway requirements, and limitations.’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f09e5090>)])]

Create external Gateway

Save the following manifest as gateway.yaml:

code_block[StructValue([(u’code’, u’kind: GatewayrnapiVersion: gateway.networking.k8s.io/v1beta1rnmetadata:rn name: op-gatewayrn namespace: ns-gatewayrn annotations:rn networking.gke.io/certmap: wildcard-op-twsttech-io-cert-maprnspec:rn gatewayClassName: gke-l7-global-external-managedrn listeners:rn – name: httpsrn protocol: HTTPSrn port: 443rn allowedRoutes:rn namespaces:rn from: “All”rn – name: httprn protocol: HTTPrn port: 80rn allowedRoutes:rn namespaces:rn from: “All”rn addresses:rn – type: NamedAddressrn value: twst-public-ip-op’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f09e5450>)])]

This file defines our Gateway with the following specifications:

Gateway is called op-gateway, created in the namespace ns-gateway

Gateway class is gke-l7-global-external-managed

Gateway is configured with the certificate mapping Certificate Manager wildcard-op-twsttech-io-cert-map which is applied via the annotation. This is a pre-configured certificate for the public domain *.twsttech.io. An advantage of Certificate Manager is the ability to use Google-managed certificates with DNS authorization for wildcard domain names

The gateway has listeners for both 80 and 443 , allowing bindings from all namespaces.

It also uses a pre-configured managed public ip, named twst-public-ip-op

Create a HTTPRoute

This will define the routes that we want to attach to the gateway.

Save the following manifest as httproute.yaml:

code_block[StructValue([(u’code’, u’apiVersion: gateway.networking.k8s.io/v1beta1rnkind: HTTPRouternmetadata:rn name: training-route1-apirnspec:rn parentRefs:rn – kind: Gatewayrn name: op-gatewayrn namespace: ns-gatewayrn hostnames:rn – training.twsttech.io.comrn rules:rn – matches:rn – path:rn value: /rn backendRefs:rn – name: trainingrn port: 80′), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f1b78e90>)])]

This file defines our HTTPRoute with the following specifications:

HTTPRoute name is training-route1-api

It references the Gateway – op-gateway ; and is created in the same namespace – ns-gateway. HTTPRoutes can be in different namespaces, using Shared Gateways 

Hostname is defined as training.twsttech.io.com with rules are set as the root path (/)

The BeckendRefs are defined as the GKE service being exposed, i.e. training

Create a GCPGatewayPolicy

This will allow us to customize our client to load balancer traffic with the minimum tls version. This references an SSL-based policy created previously.

Save the following manifest as gw-policy-tls.yaml:

code_block[StructValue([(u’code’, u’kind: GCPGatewayPolicyrnapiVersion: networking.gke.io/v1rnmetadata:rn name: gp-tls-12rn namespace: ns-gatewayrnspec:rn default:rn sslPolicy: sslp-tls-12rn targetRef:rn group: “gateway.networking.k8s.io”rn kind: Gatewayrn name: op-gatewayrn namespace: ns-gateway’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f1b78050>)])]

This file defines our GCPGatewayPolicy with the following specifications:

The GCPGatewayPolicy is named gp-tls-12, in the same namespace ns-gateway as the Gateway.

The policy references a pre-configured SSL policy named sslp-tls-12

Deploy the files

Deploy all three yaml files using kubectl apply. Verify the all three have deployed:

code_block[StructValue([(u’code’, u’kubectl get gatewayrnkubectl get httprouternkubectl get gcpgatewaypolicy’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e93f0945e10>)])]

Check that the gateway has an attached route:

code_block[StructValue([(u’code’, u’kubectl describe gateway op-gateway -n ns-gateway’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e9428e1ef50>)])]
code_block[StructValue([(u’code’, u’Listeners:rn Attached Routes: 1rn Conditions:rn Last Transition Time: 2023-06-01T11:43:18Zrn Message:rn Reason: Readyrn Status: Truern Type: Readyrn Name: httpsrn Supported Kinds:rn Group: gateway.networking.k8s.iorn Kind: HTTPRoute’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e9428e1e050>)])]

And that’s it. Our sample web application in GKE is now exposed using Gateway API. We have specified the extra security of tls version also through the use of a Gateway policy.

Gateway API can be used for discrete or shared ingress routes. This gives the option of configuring a single load balancer with many routes which can save costs, as well as aligning with roles and teams within your organization. 

What’s next 

You can find the files used above in my opowbow github repo, feel free to have a look! Also, check out this video on Kubernetes Gateway to see it in action. For detailed information on deploying Gateway on GKE, go to the documentation page Deploying Gateways.

Cloud BlogRead More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments