Background: I have a customer fronting web app that I'm deploying with Kubernetes on GKE. As is typical with such an app I want to redirect traffic from http to https.
In the olden days I would have done that in a haproxy or nginx, but now I wanted to do this in Kubernetes. Reading up on the topic it seemed hard for some reason. https://github.com/kubernetes/ingress-gce/tree/2d2c91a608987d07205c4a93537c2938bc67df38#ingress-cannot-redirect-http-to-https
So I decided I would just let http through to my webapp and let a first-in-line middleware in my app do the redirect. I read that GKE would set the x-forwarded-proto header just like nginx.
So I did something like in the app which is node+koa:
app.use((ctx, next) => {
if (ctx.request.header['x-forwarded-proto'] === 'https') {
return next()
} else {
const httpsHost = url.parse('http://' + ctx.request.header.host).hostname
let redirectTo = 'https://' + httpsHost
redirectTo += ctx.request.url
ctx.response.status = 307
ctx.response.redirect(redirectTo)
}
})
This seemed to work fine for a few minutes/seconds but then my Ingress was marked bad:
The state in GCloud console was very hard for me to interpret, but it seems to be a default health check service that is failing because I'm redirecting 307 on an internal http health check:
Note here the root path.
I've finally been able to fix this by manually specifying the probes myself in the deployment
readinessProbe:
httpGet:
path: /healthz
port: 5002
livenessProbe:
httpGet:
path: /healthz
port: 5002
and taking care of them in the app:
router.get('/healthz', ctx => {
console.log([ctx.request.headers]) //eslint-disable-line
ctx.response.status = 200
})
With that I get another definition of the health probe:
and with a new version of my app I can handle this and everything is happy go lucky.
The thing that is confusing me the most and that I'm still wondering about is the fact that this default probe that got created as part of the Ingress is persistent over changes in the Deployment. What I mean is that I need to tear down the Ingress and recreate it again before the health probe is updated in accordance with the backing deployment. Just changing the deployment where this is defined doesn't recreate the state of the health probe service and it was still going against /. This made debugging this thing a lot harder.
I have double checked that this is still the case going in any direction. I removed the probes settings and reapplied my Deployment but stuff was still working fine beacause the health check service was still going against /healthz. However, doing kubectl delete ingress; kubectl create -f ingress.yml
and it started going against / again and failing. So basically the ingress is defined in terms of the backing service. Isn't this somewhat bad?
What I'm still trying to understand is:
it's kubernetes managed by Google that why it Google kubernetes engine.
if you want to remove or add a health ckeck prob you can by running kubectl edit deployment <your deployment>
and the yaml from the currently running deployment should pop up in your default editor then Edit it (add/remove probe).
An better solution for you is to use reverse proxy in NGINX
here is and example and configuration to redirect the http to https.