<p>I am working on an application that is hosted on Kubernetes on google cloud, it uses Ingress to manage the routing to each service, then inside each service there's some extra routing using golang.</p>

<p><strong>My problem is:</strong> when I try sending an API request to <code>/api/auth/healthz</code> I am expecting to reach the <code>statusHandler()</code> function, instead I always hit the <code>requestHandler()</code> function, even though I have an http.HandleFunc in there: <code>http.HandleFunc("/healthz", statusHandler)</code></p>

<p>Here's my code in go</p>

<pre><code>func main() {
    flag.Parse()

    // initialize the "database"
    err := store.Initialise()
    if err != nil {
        glog.Error(err)
        glog.Error("Store failed to initialise")
    }

    defer store.Uninitialise()

    // Initialize the default TTL for JWT access tokens to 1 day
    tokenTTL = 24 * time.Hour
    glog.Infof("JWT access tokens time-to-live set to: %s", tokenTTL.String())

    http.HandleFunc("/healthz", statusHandler)
    http.HandleFunc("/", requestHandler)

    glog.Infof("Authentication service started on port 8080...\n")
    http.ListenAndServe(":8080", nil)
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
    glog.Infof("Reached the status handler")
    statusObj := serviceStatus{
        GitSHA:         os.Getenv("GIT_SHA"),
        BuildTimestamp: os.Getenv("BUILD_TIMESTAMP"),
        DeployEnv:      os.Getenv("DEPLOY_ENV"),
    }
    statusJSON, _ := json.Marshal(statusObj)

    w.Header().Set("Content-Type", "application/json")
    fmt.Fprintf(w, "%s", statusJSON)
}

func requestHandler(w http.ResponseWriter, r *http.Request) {
    glog.Infof("Reached the request handler")
    ...
}
</code></pre>

<p>And here's my Ingress code:</p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  # https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/annotations.md
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
    nginx.ingress.kubernetes.io/enable-cors: "false"
    nginx.ingress.kubernetes.io/cors-enable-origin: "*"
    nginx.ingress.kubernetes.io/auth-type: "basic"
    nginx.ingress.kubernetes.io/auth-secret: "ci-ingress-auth"
    nginx.ingress.kubernetes.io/proxy-body-size: "4g"
  name: ci-api-ingress
  namespace: ci
spec:
  rules:
  - host: ci.omitted.io
    http:
      paths:
      - backend:
          serviceName: auth-service &lt;&lt; This is the service I am working on
          servicePort: 8080
        path: /api/auth
      - backend:
          serviceName: data-import-service
          servicePort: 8080
        path: /api/data-import
      - backend:
          serviceName: log-service
          servicePort: 8080
        path: /api/log
      - backend:
          serviceName: project-service
          servicePort: 8080
        path: /api/project
      - backend:
          serviceName: orchestration-service
          servicePort: 8080
        path: /api/orchestration
      - backend:
          serviceName: public
          servicePort: 80
        path: /
</code></pre>

<hr>

<p>Based on <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/" rel="nofollow noreferrer">Kubernetes' documentation</a> that should work as what they have in there is something similar to my implementation:</p>

<pre><code>http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() &gt; 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})
</code></pre>

<p><strike>based on your ingress rules the path for requests should be:
<code>/api/auth/healthz</code>
  not  <code>/api/auth-service/healthz</code></strike></p>

<p>The ingress path <code>/api/auth/</code> is kept in the request uri passed to the application server.  </p>

<p>Adding <code>rewrite-target</code> to the ingress annotations will ensure the path is passed to your underlying server as you'd expect e.g. as <code>/&lt;path&gt;</code> rather than <code>/api/auth/&lt;path&gt;</code>. Inspecting the application server logs should show this is the case.</p>

<p><code>ingress.kubernetes.io/rewrite-target: /</code> </p>
