How to rewrite URLs for some specific paths? - kubernetes

I have read in ingress-nginx documentation that the rewrite is being performed thanks to an annotation like this:
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(/|$)(.*)
I have a case where I have multiple hosts and I want URL rewriting for some particular paths only:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
name: ingress
spec:
rules:
- host: somehost.westeurope.cloudapp.azure.com
http:
paths:
- path: /rest-smtp-sink # I want to rewrite this path
pathType: Prefix
backend:
service:
name: rest-smtp-sink-svc
port:
number: 80
- path: /backend # This one too
pathType: Prefix
backend:
service:
name: server-svc
port:
number: 80
- path: / # But not this one
pathType: Prefix
backend:
service:
name: client-svc
port:
number: 80
However, the annotation seems to be global. How do I enable URL rewriting for some paths only?

I managed to get the desired result with this configuration:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: ingress
spec:
rules:
- host: somehost.westeurope.cloudapp.azure.com
http:
paths:
- path: /rest-smtp-sink(/|$)(.*)
pathType: Prefix
backend:
service:
name: rest-smtp-sink-svc
port:
number: 80
- path: /backend(/|$)(.*)
pathType: Prefix
backend:
service:
name: server-svc
port:
number: 80
- path: /()(.*)
pathType: Prefix
backend:
service:
name: client-svc
port:
number: 80
As the nginx.ingress.kubernetes.io/rewrite-target annotation is global, I've used /$2 as the rewrite target and /()(.*) as a noop for the root path.

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

how to divide the request using ingress?

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 --> it will go to abc-demo-frontend service
I added below code but it is not working
current output
when user hit test.abc.com or test.abc.com/main.js both request going to abc-demo-frontend ? why ?
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: /*
pathType: ImplementationSpecific
backend:
service:
name: abc-demo-frontend
port:
number: 80
- path: /
pathType: ImplementationSpecific
backend:
service:
name: abc-demo-frontend-external
port:
number: 80
any idea..?
You can try
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

Kubernetesingress can't find multiple path resources

My ingress file like this and I cannot get my resources when it comes up multiple paths
And my ingress file like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite: /
spec:
ingressClassName: nginx
rules:
- host: foo.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Is there anybody can help me find solutions?

Convert apiVersion: networking.k8s.io/v1beta1 ingress manifest to apiVersion: networking.k8s.io/v1

I had installed an ran a kubernetes cluster with an nginx ingress earlier this year. Though it had little issues, it worked fine. For the ingress, I used the tag
apiVersion: networking.k8s.io/v1beta1
However, I have recently installed the latest version of (kubernetes 1.22) which only allows for
apiVersion: networking.k8s.io/v1
The problem i'm having is using my old yaml configuration with the new format.
My yaml file looks like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: dev-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/websocket-services : "chatserver"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- http:
paths:
- path: /api/auth/
pathType: Prefix
backend:
serviceName: um-service
servicePort: 5001
- path: /api/system/*
pathType: Prefix
backend:
serviceName: system-service
servicePort: 5002
- path: /api/news/*
backend:
serviceName: news-service
servicePort: 5003
- path: /api/tasks/*
# pathType: Prefix
backend:
serviceName: tasks-service
servicePort: 5004
- path: /api/chats/
pathType: Prefix
backend:
serviceName: chatserver
servicePort: 5500
- path: /
backend:
serviceName: web-service
servicePort: 5000
my new manifest looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /api/auth/
pathType: Prefix
backend:
service:
name: um-service
port:
number: 5001
- path: /api/system/*
pathType: Prefix
backend:
service:
name: system-service
port:
number: 5002
- path: /api/chats/
pathType: Prefix
backend:
service:
name: chatserver
port:
number: 5050
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 5000
ingressClassName: nginx
How do I convert this to use the new apiVersion: networking.k8s.io/v1 tag?
Fortunately there isn't too much difference between the API versions in terms of the YAML. Here's an example of networking.k8s.io/v1 from the Kubernetes Docs.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
The main change for you would have to do with the how the backend blocks are done. For example:
backend:
serviceName: tasks-service
servicePort: 5004
would need to become:
backend:
service:
name: "tasks-service"
port:
number: 5004

Kubernetes how to run multiple services at the same address

I have several sites available at http://service1/api and http://service2/api
I want them to work on the same external address and routing occurs inside the kube
http:/exturi/service1/api
http:/exturi/service2/api
Ingress configuration
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: ingress-api
spec:
rules:
- host: api.sample.com
http:
paths:
- backend:
serviceName: edpcore-db-api
servicePort: 13001
path: /db-api/
pathType: Prefix
tls:
- hosts:
- api.sample.com
secretName: tls-api-secret
how to configure ingress
If you are using the Nginx ingress you can do routing using
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: service-1
servicePort: 80
path: /service-1(/|$)(.*)
- backend:
serviceName: service-2
servicePort: 80
path: /service-2(/|$)(.*)
For example, the ingress definition above will result in the following rewrites:
rewrite.bar.com/service1 rewrites to rewrite.bar.com/
rewrite.bar.com/service1/ rewrites to rewrite.bar.com/
rewrite.bar.com/service1/new rewrites to rewrite.bar.com/new
Refer : https://kubernetes.github.io/ingress-nginx/examples/rewrite/
Extra
If you don't want to remove service name or rewrite simple use this config
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: simple
namespace: default
spec:
rules:
- host: simple.bar.com
http:
paths:
- backend:
serviceName: service-1
servicePort: 80
path: /service-1
- backend:
serviceName: service-2
servicePort: 80
path: /service-2
Thats how you should do it (nginx ingress):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: my-ingress-namespace
spec:
rules:
- host: exturi
http:
paths:
- backend:
service:
name: service1
port:
number: 80
path: /service1/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: service2
port:
number: 80
path: /service2/(.*)
pathType: ImplementationSpecific
status:
loadBalancer:
ingress:
- ip: {}