Ingress manifest with same host but different paths - kubernetes

I've encountered an odd problem, I think. I'm not sure if my rewrite-target is correct.
I got two URLs that I want to reach, both URLs are going to different backend and frontends. The /login endpoint will be added automatically when you hit the login-page, which we will do.
first one: dev.app.com/login
second one: dev.app.com/path2/login
The first URL is always working, even if I put /login after the host directly or just let it redirect from dev.app.com to dev.app.com/login.
But the second URL is working only if I let it redirect from dev.app.com/path2 to dev.app.com/path2/login. If I put dev.app.com/path2/login directly in the browser I will get an 404 not found nginx error. The same goes if I first put dev.app.com/path2/ and gets redirected to dev.app.com/path2/login (which works), then I reload the page. Then I get an 404 not found error.
I have setup an Ingress file with the following code:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-fe
annotations:
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- dev.app.com
secretName: tls-secret-con
rules:
- host: dev.app.com
http:
paths:
- path: /(.*)
pathType: ImplementationSpecific
backend:
service:
name: path1svc
port:
number: 80
- path: /path2(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: path2svc
port:
number: 80
What could cause this?

In the Yaml Can you change the PathType to Prefix and have a check?. Can you refer to this link1 and Link2 and Let me know if this resolves your issue. Find sample examples for ingress Path matching.
Here's the example from the Kubernetes docs:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress-1
spec:
ingressClassName: nginx
rules:
- host: test.com
http:
paths:
- path: /foo/bar
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /foo/bar/
pathType: Prefix
backend:
service:
name: service2
port:
number: 80

Related

How to run kubernetes ingress for bultiple api

I want to organize my web apis iwth kubernetes ingress tool.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-api-ingress
annotations:
kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/use-regex: "true"
# nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: api.myapp.com
http:
paths:
- pathType: Prefix
path: /catalog
backend:
service:
name: myapp-catalog-service
port:
number: 80
- pathType: Prefix
path: /identity
backend:
service:
name: myapp-identity-service
port:
number: 80
With this configuration, I can access the "api.myapp.com/catalog".
But "api.myapp.com/catalog" is 404 not found. How can fix this configuration?
Seems to be an issue with rewrite annotation that might cause the 404 error. Can you give the below annotation in the yaml and give a try :
nginx.ingress.kubernetes.io/rewrite-target: /$2
As per this rewrite target example , These $2 placeholders can be used as parameters in the rewrite-target annotation. This Target URI where the traffic must be redirected.
As per Kubernetes ingress update your yaml as below example which can be accessed from foo.bar.com/foo from port 4200 and foo.bar.com/bar from port 8080.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
Refer to this ingress path matching doc and SO

getting 503 service not available after doing configuration

I have application "test.abc.com". I want to transfer request between different service.
Example or Expected output
when user hit test.abc.com --> it will go to abc-demo-frontend-external service
when user hit test.abc.com/main.js or test.abc.com/main.css or any .css/ .js files --> it will go to abc-demo-frontend service
I have added below configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-demo-frontend-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: 'false'
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: "test.abc.com"
http:
paths:
- path: /[^\/#?]+\.(?:css|js)(?![^\/?#])
pathType: ImplementationSpecific
backend:
service:
name: abc-demo-frontend
port:
number: 80
- path: /
pathType: ImplementationSpecific
backend:
service:
name: abc-demo-frontend-external
port:
number: 80
after adding [^\/#?]+\.(?:css|js)(?![^\/?#]) path I am getting 503 why ?
when I add below path I am getting 503 why ?
- path: /[^\/#?]+\.(?:css|js)(?![^\/?#])
pathType: ImplementationSpecific
backend:
service:
name: abc-demo-frontend
port:
number: 80
The Regex used in the spec.rules.http.paths.path for K8s ingress-nginx should be comply with RE2 engine syntax; see here. Seems the Regex that you are using does not comply with the RE2 engine syntax. Check it with the supported syntax in https://github.com/google/re2/wiki/Syntax.
Because of this, your ingress-nginx pods should not be ready. Pods are not being ready should be the reason to get 503 - service unavailable issue. Try updating the Regex according to the RE2 syntax and then check it again.

Remove path with ingress nginx kubernetes 404

I have 2 services running behind Kubernetes Ingress Nginx that I'm not able to get it to work together. And the issue is I get is a 404.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
cert-manager.io/cluster-issuer: "letsencrypt-staging"
name: rewrite
namespace: default
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /bar/static(/|$)(.*)
pathType: Prefix
backend:
service:
name: service-1
port:
number: 80
- path: /foo/bar
pathType: Prefix
backend:
service:
name: service-1
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: service-2
port:
number: 80
tls:
- hosts:
- www.example.com
secretName: www.example.com-tls
For the first path I'm trying to remove bar from the path so that it becomes it becomes www.example.com/static without changing the URL if that makes sense. This works fine and all static files get a 200 however with this configuration I will get a 404 on the second path rule /foo/bar.
If I disable the nginx.ingress.kubernetes.io/rewrite-target: /$2 line, the second path rule /foo/bar gets a 200 and routes to the service correctly but now as expected since I have removed the capture group, the first rule /bar/static(/|$)(.*) doesn't work anymore and I get a 404 on all static content.
How can I make these work together?

Kubernetes Nginx Ingress Controller missing path

I have two deffinitions for Nginx Ingress Controller. Each of them routes to services for web app(React app hosted on nginx) and web api(.Net Core).
First is workig fine, but it is cumbresome since I need to add entry in etc file for each specified host to make it work:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-controller
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: testapp-web-dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: testapp-portal-web-service
port:
number: 80
- host: testapp-api-dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: testapp-portal-api-service
port:
number: 80
I decided to modify it to have single host with multiple paths, so I will have only one entry in etc file. But it does not work. First request is routed correctly to http://testapp//testapp-web-dev but every other next
request fails i.e. request for manifest goes to http://testapp/manifest.json but it should go to http://testapp/testapp-web-dev/manifest.json.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-controller
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: testapp
http:
paths:
- path: /testapp-web-dev(/|$)(.*)
pathType: Prefix
backend:
service:
name: testapp-portal-web-service
port:
number: 80
- path: /testapp-api-dev(/|$)(.*)
pathType: Prefix
backend:
service:
name: testapp-portal-api-service
port:
number: 80
Tried couple different url rewrite but without luck.
If you want to preserve the requested path, you need to remove the nginx.ingress.kubernetes.io/rewrite-target: /$2 annotation.
As per Nginx Ingress Rewrite:
In this ingress definition, any characters captured by (.*) will be
assigned to the placeholder $2, which is then used as a parameter in
the rewrite-target annotation.
i.e., the annotation is redirecting http://testapp/testapp-web-dev/manifest.json to http://testapp/manifest.json.

kubernetes ingress with multiple target-rewrite

Usually ingress rewrite target works as follows:
nginx.ingress.kubernetes.io/rewrite-target: /
This will rewrite the target of your service names as they are in the root directory. So if I have this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
rules:
http:
paths:
- path: /
backend:
serviceName: front-main
servicePort: 80
- path: /api
backend:
serviceName: back-main
servicePort: 80
My services are going to receive data as they are in /. However, I would like for my service front-main to send root / and for the server back-main to send /someotherpath/. How can I do this?
Is there something like the following line?
nginx.ingress.kubernetes.io/rewrite-target: "front-main: / ; back-main: /someotherpath"
I don't seem to find the answer in the documentation.
Unfortunately, Ingress based on free version of Nginx do not have that feature.
But, if you can use Nginx Plus based Ingress, you can do it by annotation.
Here is an example from official repo:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/rewrites: "serviceName=tea-svc rewrite=/;serviceName=coffee-svc rewrite=/beans/"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea/
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee/
backend:
serviceName: coffee-svc
servicePort: 80
Below are the examples of how the URI of requests to the tea-svc are rewritten (Note that the /tea requests are redirected to /tea/).
/tea/ -> /
/tea/abc -> /abc
Below are the examples of how the URI of requests to the coffee-svc are rewritten (Note that the /coffee requests are redirected to /beans/).
/coffee/ -> /beans/
/coffee/abc -> /beans/abc
Another solution is create two ingress yaml files
Each one using different annotations. It works!
The new syntax for the rewrite annotation allows you to use capture groups to define the rewrite-target, which can be used in some situations to achieve what you're looking for.
For instance, if you want one of your services to keep the matching url in its rewrite but not the other, you could use matching groups as follow:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1$2 # Here we concatenate the two matched groups
spec:
rules:
- http:
paths:
- path: /front()(.*) # Here the first matching group is always empty
pathType: Prefix
backend:
service:
name: front-main
port:
number: 80
- path: /(back)(.*) # Here the first matching group matches 'back'
pathType: Prefix
backend:
service:
name: back-main
port:
number: 80
So /back/foo would redirect to the back-service on /back/foo, but /front/foo would redirect to the front-service simply to /foo.
As far as I know, this can't be used for the more general case you asked for, like rewriting /back/foo to /some-completely-different-path.