Is Kubernetes/GKE default health probe defined in terms of the backing service at create time?

10/15/2018

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:

enter image description here

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:

enter image description here

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:

enter image description here

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:

  1. Is this Kubernetes or just GKE?
  2. Is it possible to disable a default health check without defining my own?
  3. Is there a better/cleaner way to achieve this pretty basic thing I'm aiming for?
-- Viktor Hedefalk
gcloud
google-kubernetes-engine
kubernetes

1 Answer

10/16/2018

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.

-- Alioua
Source: StackOverflow