skip to Main Content

I have an app set up which can be contacted via the service-IP, but not using the Ingress Rule.

Consider the following Ingress Manifest:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: default
  annotations:
    kubernetes.io/ingress.class: public
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rewrite-target: /$0
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - secretName: letsencrypt-prod
    hosts:
    - my.host.net
  rules:
  - host: my.host.net
    http:
      paths:
      - path: /myapp(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 1234

The relevant service is up and running. Doing a curl 10.152.183.91/myapp/path/ with 10.152.183.91 being the service IP gives the desired result.

When I go through curl my.host.net/myapp/path/ however, I get a 308 Permanent Redirect. Other apps on the same cluster are running as expected, so the cluster itself as well as nginx-ingress and CoreDNS are doing their job.

Where did I go wrong? Is the nginx.ingress.kubernetes.io/rewrite-target: /$0 wrong?

2

Answers


  1. Chosen as BEST ANSWER

    The problem was that I didn't even need to do any redirection, since my app was listening to the endpoint /myapp/ anyways. So any request hitting my server at the /myapp/path already had the correct URL.

    I figured this out when curl -L showed a redirect loop (as pointed out by @dawik-kruk)


  2. First and foremost, you will need to change the:

    • from: nginx.ingress.kubernetes.io/rewrite-target: /$0
    • to: nginx.ingress.kubernetes.io/rewrite-target: /$2

    Explanation:

    Rewrite Target

    Note

    Captured groups are saved in numbered placeholders, chronologically, in the form $1, $2 … $n. These placeholders can be used as parameters in the rewrite-target annotation.

    Create an Ingress rule with a rewrite annotation:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/use-regex: "true"
         nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: rewrite
      namespace: default
    spec:
      ingressClassName: nginx
      rules:
      - host: rewrite.bar.com
        http:
          paths:
          - path: /something(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: http-svc
                port: 
                  number: 80
    

    In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.

    For example, the ingress definition above will result in the following rewrites:

    • rewrite.bar.com/something rewrites to rewrite.bar.com/
    • rewrite.bar.com/something/ rewrites to rewrite.bar.com/
    • rewrite.bar.com/something/new rewrites to rewrite.bar.com/new

    Kubernetes.github.io: Ingress-nginx: Examples: Rewrite


    As for the curl part. By running exactly the same as you did:

    • curl my.host.net/myapp/path/

    You will receive a 308 Permanent Redirect.

    curl by default is not following the redirection. Try with curl -L.

    Example with setup similar to yours:

    ❯ curl kruklabs.internal/myapp/      
    <html>
    <head><title>308 Permanent Redirect</title></head>
    <body>
    <center><h1>308 Permanent Redirect</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>
    
    ❯ curl kruklabs.internal/myapp/ -L -k  
    Here is the nginx container!
    

    A side note!

    You could also try to contact Ingress directly with HTTPS.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search