Kubernetes Nginx Ingress - Rewrite Dynamic URL - nginx

Here i have kubernetes running on minikube and it has 2 services backend and frontend. And i have installed ingress addon for minikube.
I wanted to rewrite whenever the frontend request the path url is /users/{user-id} it goes to backend service with the same url dynamically.
Let say the request is /users it rewrite to backend service to /users, /users/1 it goes to /users/1.
I tried to read nginx manual found some special expression i don't understand.
This is my ingress configuration.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-be
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /users/$1
spec:
ingressClassName: nginx
rules:
- host: backend
http:
paths:
- path: /users/(.*)
pathType: Prefix
backend:
service:
name: backend
port:
number: 5000
My configuration seems fine when the request is /users/{users-id} but when the request is /users, my ingress won't redirect me to '/users' in backend service.
When i tested with curl, this is the output.
curl http://backend/users/3
{"id":3,"name":"Sofia","email":"sofia#gmail.com","gender":"Female","createdAt":"2022-04-05T15:46:46.000Z","updatedAt":"2022-04-05T15:46:46.000Z"}%
curl http://backend/users
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
What am i missing here?
Thank you in advance for your help!

Update!
Andreas in the comment suggest me to use /users/ and it works!
Then i decided to modified my ingress configuration.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-be
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /users/$2
spec:
ingressClassName: nginx
rules:
- host: backend
http:
paths:
- path: /users(/|$)(.*)
pathType: Prefix
backend:
service:
name: backend
port:
number: 5000

Related

nginx ingress: Cannot redirect to backend service

I have scoured the Net to try to resolve something that seems to be a common issue, but unfortunately all of the documentation and suggestions have not solve my problem. I hope that you can help me and others with it.
We are migrating from another ingress to nginx-ingress. To validate our installation, I am using httpbin as the backend service.
When I create the following ingress with a path of '/' and send the query, I receive a proper response.
curl -I -k http://abczzz.com/anything
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mikie-ingress
namespace: mikie
spec:
ingressClassName: nginx
rules:
- host: abczzz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin-service
port:
number: 8999
What we really need is to be able to redirect to different services off of this single host, so I changed the ingress to the following, but the query always fails with a 404. Basically, I want the /httpbin to disappear and pass the path onto the backend service, httpbin.
curl -I -k http://abczzz.com/httpbin/anything
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mikie-ingress
namespace: mikie
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^(/httpbin)$ $1/ redirect;
spec:
ingressClassName: nginx
rules:
- host: abczzz.com
http:
paths:
- path: /httpbin(/|$)(.*)
pathType: Prefix
backend:
service:
name: httpbin-service
port:
number: 8999
I'd really appreciate your help to resolve what must be a simple routing issue.
Thanks for your time and interest.
I finally figured things out... Hopefully, the following snippet will help others...
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mikie-ingress
namespace: mikie
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
ingressClassName: nginx
rules:
- host: abczzz.com
http:
paths:
- backend:
service:
name: httpbin-service
port:
number: 8999
path: /httpbin/(.*)
pathType: Prefix

nginx ingress redirect traffic

I deployed nginx ingress controller and randomApp to minikube cluster.
I have 2 requirements:
All traffic for "random/.*" should go to the random service
Other paths should go to the nginx.
This configuration is correct?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-rule-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
defaultBackend:
service:
name: ingress-nginx-controller
port:
number: 80
rules:
- host: random.localdev.me
http:
paths:
- path: /random/(.*)
backend:
service:
name: random
port:
number: 8000
pathType: Prefix
You also need to add metadata.annotations: kubernetes.io/ingress.class: "nginx" or spec.ingressClassName: nginx to allow nginx-ingress-controller to discover the ingress.
Also you shouldn't define default backend service as ingress-nginx-controller. Because you will get 503 Service Temporarily Unavailable since nginx-ingress-controller's nginx.conf didn't be configured for this. You can give another nginx server's service for it.

Kubernetes Nginx Ingress pod subpath

I have a pod that exposes an HTTP service.
This pod has some HTTP endpoints which are available under /accounts.
My goal is to access this sub-path via accounts.example.com.
For example if the url accounts.example.com/test is requested, the nginx ingress should route the request to /accounts/test on my pod.
In the nginx ingress documentation I cannot find a use-case with examples like this.
You should use rewrite to accomplish your request.
https://kubernetes.github.io/ingress-nginx/examples/rewrite/
Here is an example:
Focus on this line: path: /something(/|$)(.*)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
Look on the different annotations for the re-write:

GKE ingress pass cookie as header

I would like to use some kubernetes ingress (doesn't matter the ingress type) on google cloud GKE 1.19.7-gke.1302, and nginx ingress deployed by nginx-ingress-0.8.0 helm chart, and my need is to fetch a cookie and use it later to authenticate to our service. When I use nginx as deployment it works, but when I use nginx ingress it seems to ignore the annotation.
I tried using this configuration snippet for the nginx ingress, which works on the nginx deployment but not on the ingress:
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header "Authorization" "Basic $cookie_myToken";
And this is my entire ingress yaml:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
# enable backend redirections
kubernetes.io/tls-acme: "true"
# enable stickiness
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header "Authorization" "Basic $cookie_myToken";
spec:
tls:
- secretName: my-tls
hosts:
- "test.com"
defaultBackend:
service:
name: my-nodeport
port:
number: 80
rules:
- host: "test.com"
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: my-nodeport
port:
number: 80
Any ideas?
Posting this answer to make it more visible as issue was identified and solved in comment section.
Root cause of this issue was Nginx Ingress Controller misconfiguration.
In the OP's setup Nginx Ingress Controller, v.0.8.0 was used. After redeploying Nginx Ingress to latest version (v0.44.0) from Nginx Ingress Documentation it started working properly.
Yes, reinstalling nginx ingress to the latest version with helm solved the problem.

Kubernetes NGINX Ingress changes HTTP request from a POST to a GET

I'm using Kubernetes that is bundled with Docker-for-Mac. I'm trying to configure an Ingress that routes http requests starting with /v1/ to my backend service and /ui/ requests to my Angular app.
My issues seems to be that the HTTP method of the requests are changed by ingress (NGINX) from a POST to a GET.
I have tried various rewrite rules, but to no avail. I even switched from Docker-for-Mac to Minikube, but the result is the same.
If I use a simple ingress with no paths (just the default backend) then the service is getting the correct HTTP method.
The ingress below works:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
backend:
serviceName: backend
servicePort: 8080
But this ingress does not:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /v1
backend:
serviceName: backend
servicePort: 8080
- path: /ui
backend:
serviceName: webui
servicePort: 80
When I debug the "backend" service I see that the HTTP Request is a GET instead of a POST.
I read somewhere that NGINX rewrites issue a 308 (permanent) redirect and the HTTP method is changed from a GET to a POST, but if that is the case how can I configure my ingress to support different paths for different services that require POST calls?
I found the solution to my problem. When I add host: to the configuration then the http method is not changed. Here is my current ingress yaml (the rewrite and regex are used to omit sending the /v1 as part of the backend URL)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: localhost
http:
paths:
- path: /v1(/|$)(.*)
backend:
serviceName: gateway
servicePort: 8080

Resources