I have Nginx-based service which configured to accept HTTPS-only. However GKE ingress answers HTTP requests in HTTP. I know that GKE Ingress doesn't know to enforce HTTP -> HTTPS redirect, but is it possible to learn it at least return HTTPS from service?
rules:
- http:
paths:
- path: /*
backend:
serviceName: dashboard-ui
servicePort: 8443
UPDATE: I do have TSL configured on GKE ingress and my K8S service. When request comes in HTTPS everything works nice. But HTTP requests gets HTTP response. I implemented HTTP->HTTPS redirect in my service, but it didn't help. In fact, for now all communication between ingress and my service is HTTTPS because service exposes only HTTPS port
SOLUTION - thanks to Paul Annetts: Nginx should check original protocol inside HTTPS block and redirect, like this
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
Yes, you can configure the GKE Kubernetes Ingress to both terminate HTTPS for external traffic, and also to use HTTPS internally between Google HTTP(S) Load Balancer and your service inside the GKE cluster.
This is documented here, but it is fairly complex.
For HTTPS to work you will need a TLS certificate and key.
If you have your own TLS certificate and key in the cluster as a secret, you can provide it using the tls
section of Ingress
:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress-2
spec:
tls:
- secretName: my-secret
rules:
- http:
paths:
- path: /*
backend:
serviceName: my-metrics
servicePort: 60000
You can also upload your TLS certificate and key directly to Google Cloud and provide a ingress.gcp.kubernetes.io/pre-shared-cert
annotation that tells GKE Ingress to use it.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-psc-ingress
annotations:
ingress.gcp.kubernetes.io/pre-shared-cert: "my-domain-tls-cert"
...
To use HTTPS for traffic inside Google Cloud, from the Load Balancer to your GKE cluster, you need the cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
annotation on your NodePort
service. Note that your ports must be named for the HTTPS to work.
apiVersion: v1
kind: Service
metadata:
name: my-service-3
annotations:
cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
type: NodePort
selector:
app: metrics
department: sales
ports:
- name: my-https-port
port: 443
targetPort: 8443
- name: my-http-port
port: 80
targetPort: 50001
The load balancer itself doesn’t support redirection from HTTP->HTTPS, you need to find another way for that.
As you have NGINX as entry-point into your cluster, you can detect the protocol used to connect to the load-balancer with the X-forwarded-Proto
HTTP header and do a redirect, something like this.
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}