Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does nginx.ingress.kubernetes.io/rewrite-target: /$1 mean in minikube annotation?

While working with minikube ingress, I have to write nginx.ingress.kubernetes.io/rewrite-target: /$1. I have been trying hard to understand why we need this annotation and how to use it.

I know that the doc says the following:

In some scenarios the exposed URL in the backend service differs from the specified path in the Ingress rule. Without a rewrite any request will return 404. Set the annotation nginx.ingress.kubernetes.io/rewrite-target to the path expected by the service.

But I am not able to get the exact point of what exactly the exposed URL in the backend service differs from the specified path in the Ingress rule means. I am not able to get the idea clearly.

Further, upon trying to execute ingress file with services:

code 1:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80

code 2:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80

code 3:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /index
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80

what exactly is the difference between each pair of the above 3 code snippets with respect to rewrite-target and path mentioned above?

PS: I'm new to minikube and trying to figure out the exact way things work. Please help.

like image 673
vagdevi k Avatar asked Apr 10 '21 05:04

vagdevi k


People also ask

What does nginx ingress Kubernetes IO rewrite target mean?

nginx.ingress.kubernetes.io/rewrite-target. Target URI where the traffic must be redirected. string. nginx.ingress.kubernetes.io/ssl-redirect. Indicates if the location section is only accessible via SSL (defaults to True when Ingress contains a Certificate)

What is nginx ingress Kubernetes IO configuration snippet?

The configuration-snippet is to add configs to locations. If you want to add a custom location to the server context, you should use the server-snippet instead: Using the annotation nginx.ingress.kubernetes.io/server-snippet it is possible to add custom configuration in the server configuration block.

What is ingress in Minikube?

An Ingress is an API object that defines rules which allow external access to services in a cluster. An Ingress controller fulfills the rules set in the Ingress. This page shows you how to set up a simple Ingress which routes requests to Service web or web2 depending on the HTTP URI.

What is annotations in ingress?

The annotation is an extension of the nginx.ingress.kubernetes.io/canary-by-header to allow customizing the header value instead of using hardcoded values. It doesn't have any effect if the nginx.ingress.kubernetes.io/canary-by-header annotation is not defined.

How do I enable Nginx ingress in Kubernetes?

Enable the Ingress controller. To enable the NGINX Ingress controller, run the following command: minikube addons enable ingress. Verify that the NGINX Ingress controller is running. kubectl get pods -n kube-system. Note: This can take up to a minute.

What is Nginx limit-rate-after in Kubernetes?

nginx.ingress.kubernetes.io/limit-rate-after: initial number of kilobytes after which the further transmission of a response to a given connection will be rate limited. This feature must be used with proxy-buffering enabled. nginx.ingress.kubernetes.io/limit-rate: number of kilobytes per second allowed to send to a given connection.

How to set affinity type for Nginx ingress?

The annotation nginx.ingress.kubernetes.io/affinity enables and sets the affinity type in all Upstreams of an Ingress. This way, a request will always be directed to the same upstream server. The only affinity type available for NGINX is cookie.

Does SSL passthrough work with nginx ingress controller?

Because SSL Passthrough works on layer 4 of the OSI model (TCP) and not on the layer 7 (HTTP), using SSL Passthrough invalidates all the other annotations set on an Ingress object. By default the NGINX ingress controller uses a list of all endpoints (Pod IP/port) in the NGINX upstream configuration.


1 Answers

I don't know if things changes with new versions of the Ingress resource or with new versions of the Nginx Ingress Controller, but this is how I think it works.

Suppose I want to serve 2 different web applications under the same domain, with a Ingress.

  • App A is expecting requests under /
  • App B is expecting requests under /

So, both Apps are expecting their requests directly under root, which (at first glance) seems to make them impossible to be served at the same domain.

Except, with rewrite targets, I can. I could just serve them under a different path, but rewrite the target to /

  • Serve App A under myexample.com/aaa/
  • Serve App B under myexample.com/bbb/

And add a rewrite target to remove the first part of the path. This is just an example of what a rewrite target can be used for, it simply makes you able to serve an application under a different path of the one expected by the app itself.

Example of the ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /aaa(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-a
                port:
                  number: 80
          - path: /bbb(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-b
                port:
                  number: 80

Notice that, while this works pretty well on Rest API and similar things, it may work less well on web pages, because a web page could try to load resources at a different path (for example if it does not use relative paths). This is why (usually) frontend applications needs to know on which path they are being served under a domain.


Regarding the syntax of rewrite targets, I'll take as example the Ingress I wrote above. There are a couple things to take into consideration:

  • path
  • pathType
  • rewrite-target

Let's start with path and pathType interactions. With the path I can define where to serve my services. Depending on the pathType, it may be just a Prefix of the whole path, the Exact path, or it can depends on the Ingress Controller (aka ImplementationSpecific). Everything is nicely explain in the documentation with a long table of examples ( https://kubernetes.io/docs/concepts/services-networking/ingress/#examples )

I can do almost everything just with path and pathType, except if the applications I want to serve are expecting to be served at different paths from the ones specified in the Ingress; this is when rewrite-target comes into play.

Like in the example above, I can use rewrite-target to serve an application under a different path from the one expected, composing the url as I want. I can also use regex and capture groups (this is what $1, $2 and so on are)

For example, if I write path: /bbb(/|$)(.*) I mean that this path will match everything under /bbb, with or without a / after bbb. And if I then write rewrite-target: /$2 I'm meaning that requests will be rewritten to substitute /bbb with / and then take the second capture group (which means the second regex expression, (.*) )

The documentation explains it pretty well, even if it makes still use of the old Ingress resource ( https://kubernetes.github.io/ingress-nginx/examples/rewrite/ )

like image 118
AndD Avatar answered Nov 15 '22 08:11

AndD