I have an ingress, defined as the following:
Name: online-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
jj.cloud.com
/online/(.*) online:80 (172.16.1.66:5001)
/userOnline online:80 (172.16.1.66:5001)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal AddedOrUpdated 29m (x4 over 74m) nginx-ingress-controller Configuration for default/online-ingress was added or updated
If I test it with no rewrite, it's ok.
curl -X POST jj.cloud.com:31235/userOnline -H 'Content-Type: application/json' -d '{"url":"baidu.com","users":["ua"]}'
OK
However, if I try to use rewrite, it will fail.
curl -X POST jj.cloud.com:31235/online/userOnline -H 'Content-Type: application/json' -d '{"url":"baidu.com","users":["ua"]}'
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.21.3</center>
</body>
</html>
And it will produce the following error logs:
2021/11/03 10:21:25 [error] 134#134: *63 open() "/etc/nginx/html/online/userOnline" failed (2: No such file or directory), client: 172.16.0.0, server: jj.cloud.com, request: "POST /online/userOnline HTTP/1.1", host: "jj.cloud.com:31235"
172.16.0.0 - - [03/Nov/2021:10:21:25 +0000] "POST /online/userOnline HTTP/1.1" 404 153 "-" "curl/7.29.0" "-"
Why the path /online/userOnline
doesn't match /online/(.*)
and rewrite it to /userOnline
? Or are there some other errors?
Here is the yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: online-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: jj.cloud.com
http:
paths:
- path: /online(/|$)/(.*)
pathType: Prefix
backend:
service:
name: online
port:
number: 80
- path: /userOnline
pathType: Prefix
backend:
service:
name: online
port:
number: 80
ingressClassName: nginx
When I checked the generated nginx config, I found (default-online-ingress.conf):
location /online(/|$)/(.*) {
It seems lost of the modifier for regex match, like this:
location ~* "^/online(/|$)/(.*)" {
If it's true, how to make rewrite take effect and generate correct nginx config?
If I understood your issue correctly, you have a problem with captured groups.
According to Nginx Rewrite targets it seems to me,
path: /online(/|$)(.*)
rewrite-target:
should be rewrite-target: /$2
kubernetes.io/ingress.class: nginx
yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: online-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: jj.cloud.com
http:
paths:
- path: /online(/|$)(.*)
pathType: Prefix
backend:
service:
name: online
port:
number: 80
- path: /userOnline
pathType: Prefix
backend:
service:
name: online
port:
number: 80
ingressClassName: inner-nginx