Kubernetes Gateway and HTTPRoute

In this post we’re going to use a Gateway and HTTPRoutes to create a global load balancer and configure routes as an alternative to using the traditional ingress approach.

Cheat Sheet:

kubectl get gateways

kubectl describe gateways <name>

kubectl get httproutes

kubectl describe httproutes <route name>

References:

https://gateway-api.sigs.k8s.io/guides/multiple-ns/

https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-gateways#external-gateway

https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api

What you’ll need:

Kubernetes cluster (we’re using Autopilot)

Working installs of gcloud and helm

Install Sample Applications:

For this example we’re going to install pgadmin and phpmyadmin via helm charts.

This example assumes that pgadmin, phpmyadmin, and the following yamls are in the same namespace, ie, default. Review the multiple-ns link the references if needed.

Configure gateway.yaml:

Create a gateway.yaml file and add the following contents:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: external-http
  # annotations:
  #   networking.gke.io/certmap: store-example-com-map
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
  - name: http
    protocol: HTTP
    port: 80

Configure routes.yaml:

Next, create a routes.yaml file and put the following contents inside of it.

Pro Tip: Note the RequestHeaderModifier below — this tells pgAdmin to update its internal base paths. Hat tip to Joey for finding that nugget here!

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: pgadmin-external
spec:
  parentRefs:
  - kind: Gateway
    name: external-http
  rules:
  - backendRefs:
    - name: phpmyadmin
      port: 80
  - matches:
    - path:
        value: /pga
    filters:
      - type: RequestHeaderModifier
        requestHeaderModifier:
          add:
            - name: X-Script-Name
              value: /pga
    backendRefs:
    - name: pgadmin-pgadmin4
      port: 80  

Create a Health Check Policy for pgAdmin:

During our testing we needed to create a healthcheck policy for pgAdmin because the default one created by using the gateway and route was generating an http healthcheck that was marking the pods as bad. The following will create a TCP healthcheck that will work. Note — we did not try the http healthcheck AFTER we modified the headers in the route.yaml for pgAdmin.

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: pgadmin-healthcheck
  # namespace: default
spec:
  default:
    checkIntervalSec: 5
    timeoutSec: 5
    healthyThreshold: 5
    unhealthyThreshold: 2
    logConfig:
      enabled: true
    config:
      type: TCP
      httpHealthCheck:
        portSpecification: USE_SERVING_PORT
        proxyHeader: NONE
  targetRef:
    group: ""
    kind: Service
    name: pgadmin-pgadmin4

Deploy:

Now we need to deploy each of the yamls as follows:

kubectl apply -f gateway.yaml

kubectl apply -f routes.yaml

kubectl apply -f pgadmin-healthcheck.yaml

Check the Status:

You can check the status of the gateway, etc by doing the following:

kubectl:

kubectl get gateways

kubectl describe gateways <name>

kubectl get httproutes

kubectl describe httproutes <route name>

Via Portal:

You can visit the load balancer section in portal to see the newly created loadbalancer, backends, and routes.

Acknowledgements:

Many thanks to Joey for working tirelessly with me as we figured this out!

Scroll to Top