3
votes

I currently have a working Frontend and Backend nodeports with an Ingress service setup with GKE's Google-managed certificates.

However, my issue is that by default when a user goes to samplesite.com, it uses http as default. This means that the user needs to specifically type in the browser https://samplesite.com in order to get the https version of my website.

How do I properly disable http on GKE ingress, or how do I redirect all my traffic to https? I understand that this can be forcefully done in my backend code as well but I want to separate concerns and handle this in my Kubernetes setup.

Here is my ingress.yaml file:

kind: Service
apiVersion: v1
metadata:
  name: frontend-node-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
  - port: 5000
    targetPort: 80
    protocol: TCP
    name: http
---
kind: Service
apiVersion: v1
metadata:
  name: backend-node-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: backend
  ports:
  - port: 8081
    targetPort: 9229
    protocol: TCP
    name: http
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: samplesite-ingress-frontend
  namespace: default
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "samplesite-static-ip"
    kubernetes.io/ingress.allow-http: "false"
    networking.gke.io/managed-certificates: samplesite-ssl
spec:
  backend:
    serviceName: frontend-node-service
    servicePort: 5000
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: samplesite-ingress-backend
  namespace: default
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "samplesite-backend-ip"
    kubernetes.io/ingress.allow-http: "false"
    networking.gke.io/managed-certificates: samplesite-api-ssl
spec:
  backend:
    serviceName: backend-node-service
    servicePort: 8081
1

1 Answers

5
votes

Currently GKE Ingress does not support out of the box HTTP->HTTPS redirect.

There is an ongoing Feature Request for it here:

There are some workarounds for it:

  • Use different Ingress controller like nginx-ingress.
  • Create a HTTP->HTTPS redirection in GCP Cloud Console.

How do I properly disable http on GKE ingress, or how do I redirect all my traffic to https?

To disable HTTP on GKE you can use following annotation:

  • kubernetes.io/ingress.allow-http: "false"

This annotation will:

  • Allow traffic only on port: 443 (HTTPS).
  • Deny traffic on port: 80 (HTTP) resulting in error code: 404.

Focusing on previously mentioned workarounds:

Use different Ingress controller like nginx-ingress

One of the ways to have the HTTP->HTTPS redirection is to use nginx-ingress. You can deploy it with official documentation:

This Ingress controller will create a service of type LoadBalancer which will be the entry point for your traffic. Ingress objects will respond on LoadBalancer IP. You can download the manifest from installation part and modify it to support the static IP you have requested in GCP. More reference can be found here:

You will need to provide your own certificates or use tools like cert-manager to have HTTPS traffic as the annotation: networking.gke.io/managed-certificates will not work with nginx-ingress.

I used this YAML definition and without any other annotations I was always redirected to the HTTPS:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx" # IMPORTANT
spec:
  tls: # HTTPS PART
  - secretName: ssl-certificate # SELF PROVIDED CERT NAME
  rules:
  - host:
    http:
      paths:
      - path: /
        backend:
          serviceName: hello-service
          servicePort: hello-port

Create a HTTP->HTTPS redirection in GCP Cloud Console.

There is also an option to manually create a redirection rule for your Ingress resource. You will need to follow official documentation:

Using the part of above documentation, you will need to create a HTTP LoadBalancer responding on the same IP as your Ingress resource (reserved static IP) redirecting traffic to HTTPS.

Disclaimer!

Your Ingress resource will need to have following annotation:

  • kubernetes.io/ingress.allow-http: "false"

Lack there of will result in forbidding you to create a redirection mentioned above.