To really see what goes on takes an understanding of some rather complex nginx configuration. Whenever an Ingress
is deployed or edited, the configuration in the nginx controller is updated.
The ingress controller is nothing more than nginx server running in reverse proxy mode, which means it can examine incoming requests and make a routing decision (which backend to use) based on a set of rules for matching URL paths (and a lot of other stuff as well using other annotations).
To see the differences in the Killercoda lab
- Deploy the solution as given - don’t end the lab
- Get the nginx configuration and save as
rewrite.conf
controller_pod=$(kubectl get pod -n ingress-nginx --selector app.kubernetes.io/component=controller)
kubectl exec -t -n ingress-nginx $controller_pod -- cat nginx.conf > rewrite.conf
- Edit the ingress and remove the annotation. Wait 30 seconds to ensure controller has updated
- Get the configuration again and save as
no-rewrite.conf
kubectl exec -t -n ingress-nginx $controller_pod -- cat nginx.conf > no-rewrite.conf
- Use the VSCode editor by pressing
Editor
tab at the top left of the terminal
- Right click on
rewrite.conf
as shown and hit Select for Compare
- Right click on
no-rewrite.conf
as shown and hit Compare with Selected
The editor will show the two configurations side by side with differences highlighted. Lines in red on the left were removed from the config when you updated the ingress to remove the annotation, and stuff on the right in green was added to the config
You will see one of the things removed for each of europe and asia is the rewrite rule created by the annotation, e.g.
rewrite "(?i)/europe" / break;
-
rewrite
directive: This is used to rewrite URLs based on specified patterns and conditions.
-
(?i)
: This is a flag within the regular expression that makes the pattern case-insensitive. Thus, it will match /europe
, /Europe
, /EUROPE
, etc. (although technically it will only match the lowercase version due to the location directive explained below)
-
/europe
: This is the pattern that nginx will look for in the requested URL.
-
/
: This is the replacement string. When the pattern is matched, the URL is rewritten to just /
.
-
break
: This indicates that nginx should stop processing the rewrite directives at this point and immediately process the rewritten URL.
Putting it all together, this rewrite rule means that any URL containing /europe
(case-insensitive) will be rewritten to /
, and nginx will stop any further rewrite processing for this request. So the backend service will be requested as europe.world.service/
That was part of a single location processing block:
location ~* "^/europe" {
which matches any URL path starting with /europe
(exact case) and anything after it e.g. /europe/london
, /europe/London
but not /Europe
, /EUROPE
In the replacement without the rewrite, two distinct exact matching location
rules have been added, one for /europe
and another for /europe/
. Here, ultimately the former will generate a “301 Moved Permanently” response pointing to the latter, and the latter will explicitly call the backend on /
All the above is also done for asia