How can I redirect traffic to my web service via ingress annotations?

8/15/2019

I have deployed a Jenkins instance to Kubernetes that is accessible from jenkins.company.com. I would like to setup a second route jenkins.company.com/admin that will attach a header and then forward the request to the same service.

My problem is that all the subsequent requests that the Jenkins home page relies on are returning 404 http responses.

Request URL: https://jenkins.company.com/admin
Request Method: GET Status Code: 200 
Request URL: https://jenkins.company.com/static/1d6021a8/css/layout-common.css
Method: GET Status Code: 404 
Request URL: https://jenkins.company.com/static/1d6021a8/css/style.cssRequest 
Method: GET Status Code: 404 
Request URL: https://jenkins.company.com/static/1d6021a8/scripts/prototype.js
Method: GET Status Code: 404 
...

I've experimented with various ingress annotations with no success.

nginx.ingress.kubernetes.io/use-regex: "true"

with spec.rules.paths[].path using regular expressions in an attempt to get the rewrite-target value.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/auth-realm: Authentication Required - ok
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/configuration-snippet: |-
      proxy_set_header User $remote_user;
    nginx.ingress.kubernetes.io/rewrite-target: $1
  name: jenkins-master-ingress
  namespace: default
spec:
  rules:
  - host: jenkins.company.com
    http:
      paths:
      - backend:
          serviceName: my-jenkins
          servicePort: 8080
        path: /a
  tls:
  - secretName: my-secret
status:
  loadBalancer:
    ingress:
    - {}
~                  

Interestingly, I also found that adding the another path fixed everything, although I can't explain how. Adding "stati" as a path unblocks it, but using "static" or "static/(.+)" breaks it back to returning 404s.

spec:
  rules:
  - host: jenkins.company.com
    http:
      paths:
      - backend:
          serviceName: my-jenkins
          servicePort: 8080
        path: /a
      - backend:
          serviceName: my-jenkins
          servicePort: 8080
        path: /stati

How can I get the /static files to pass through? What is my ingress missing?

-- James
kubernetes
kubernetes-ingress
nginx
nginx-ingress

1 Answer

8/21/2019

Consider that the annotations regarding the header change will affect all the rules in the ingress and that your ingress rules are only allowing incoming requests for /a, not for /static. Hence, it will never be served.

Now, the rewrite-target directive will transform any incoming URI for each path (for instance: /a) before sending it into the specified backend. For that, it uses captured groups.

In your second snippet case, capturing static/(.+) is leaving $1 with whatever comes after static/ and is removing it completely from the original URI, to send it to the backend, always resulting in 404 as such URIs doesn't exist there.

It doesn't seem to be possible at the moment to add specific headers to selected paths through the ingress annotations, as custom headers are part of the global configuration of the ingress controller.

-- yyyyahir
Source: StackOverflow