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.
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)
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.
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.
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.
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.
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.
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.
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.
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.
/
/
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 /
myexample.com/aaa/
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:
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/ )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With