A simple HTTPS Redirect for your GKE app

Introduction

In this post, we will talk only about the redirection of HTTP traffic to HTTPS. In recent times, for this kind of redirection to work, you would have liked to use an ingress controller from the likes of ingress-nginx or HAProxy. You could install them by hand through manifests or with Helm. Using those adds complexity to your handling of the content delivery towards users. It might be necessary for the features they provide be used in really high-availability required environments.

But in the case of this blog for example, I'm just running it for the sake of it on GKE, for shits and giggles you may say. I therefore don't need a heavy solution for a simple problem and only used supported GKE features.

Here is what our work will look like:

Requirements

For this to work on your side, you will need:

  • Your own certificate, may it be downloaded for providers like GoDaddy, managed by GCP or self generated by Let's Encrypt.
  • Your own app deployed as a pod, deployment, daemonset or other kinds of controllers.
  • A service linked to your app (in my case a NodePort).

Configure your traffic redirection

Installing a frontendconfig

A frontendconfig is a Kubernetes CRD that will act as a configuration to your GCP load balancer. They need to be linked to an ingress in order to help you handle incoming traffic. You can learn more of those Kubernetes object by looking at this documentation page: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features

You can use the following manifest to add your frontendconfig:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: test-fec
  namespace: test-ns
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: MOVED_PERMANENTLY_DEFAULT

This configuration will explicitly order the GCP load balancer controller by the ingress to redirect the HTTP traffic to HTTPS by enabling the redirectToHTTPS feature. The MOVED_PERMANENTLY_DEFAULT value to the responseCodeName key is set by default if you do not specify it in the manifest, but it's good to know it.

In order to work, the ingress needs to be aware of this configuration. You can add the networking.gke.io/v1beta1.FrontendConfig: "test-fec" annotation to your ingress like this:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: test-ns
  annotations:
    ...
    networking.gke.io/v1beta1.FrontendConfig: "blog-fec"
  labels:
    app: test
spec:
  tls:
    ...

Once applied you will need to wait for a bit until the ingress syncs itself. You can check the result with a simple curl targeting your app using HTTP:

$ curl http://test.domain.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://test.domain.com/">here</A>.
</BODY></HTML>

And there you go, a nice little redirection!