Wildcard to match `path` and `serviceName` in Kubernetes ingress - kubernetes

I have a Kubernetes cluster with an undefined series of services, and what I want to do is serve each service on an endpoint, with the ability to add new services at any time, with them still being available at an endpoint.
I'm looking for a way to set, in my ingress, a wildcard on serviceName, so that /xx will be routed to service xx, /yy to service yy, etc.
Another solution that I could also use would be matching http://xx.myurl.com to service xx.
Is this something doable with Kubernetes?
I imagine something of the like
- path: /(.*)
backend:
serviceName: $1
servicePort: 80
Thanks,
Colin

This is not something the Ingress system supports. Some other tools may, you can do this pretty easily with a static Nginx config for example.

Yes, you can do it with ingress, here are both solutions:
for my-domain.com/xxx
in ingress service you do something like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
labels:
name: ingress-service
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: my-domain.com
http:
paths:
- path: /xx/(.*)
pathType: Prefix
backend:
service:
name: xx
port:
number: 80
- path: /yy/(.*)
pathType: Prefix
backend:
service:
name: yy
port:
number: 80
so everything that is pointed to my-domain.com/xx will be pointed out to xx service and it will remove /xx/ from the path, ex:
If you make a request to my-domain.com/xx/values, the request will be forwarded as my-domain.com/values to the xx service.
Learn more about it at https://kubernetes.io/docs/concepts/services-networking/ingress/#simple-fanout
As well as you can see here how the paths work: https://kubernetes.io/docs/concepts/services-networking/ingress/#examples
The other solution for xx.my-domain.com you can do it like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
labels:
name: ingress-service
namespace: my-namespace
spec:
rules:
- host: xx.my-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: xx
port:
number: 80
- host: yy.my-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: yy
port:
number: 80
You can learn more about it at https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards

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

Kubernetes Ingress path route to different services in different namespaces

currently I'm trying the following setup:
I have:
one cluster
one Ingress Controller
one url (myapp.onazure.com)
two namespaces for two applications default and default-test
two deployments, ingress objects, services for the namespaces
I can easily reach my app from the default namespace with path based routing '/' as a prefix rule
Now i have tried to configure the second namespace and following rule: /testing to hit another service
Unfortunately i get an HTTP404 when i try to hit the following URL myapp.onazure.com/testing/openapi.json
What did I miss?
Working Ingress 1
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object
namespace: default
annotations:
kubernetes.io/ingress.class: public-nginx
spec:
tls:
- hosts:
- myapp-region1.onazure.com
- myapp-region2.onazure.com
secretName: ingress-tls-csi
rules:
- host: - myapp-region1.onazure.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: liveapi-svc
port:
number: 8080
- host: myapp-region2.onazure.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: liveapi-svc
port:
number: 8080
Not working Ingress 2
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object-testing
namespace: default-testing
annotations:
kubernetes.io/ingress.class: public-nginx
#nginx.ingress.kubernetes.io/rewrite-target: /testing
spec:
tls:
- hosts:
- myapp-region1.onazure.com
- myapp-region2.onazure.com
secretName: ingress-tls-csi-testing
rules:
- host: myapp-region1.onazure.com
http:
paths:
- path: /testing
#pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8080
- host: myapp-region2.onazure.com
http:
paths:
- path: /testing
#pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8080
Maybe I am missing a rewrite target to simply '/' in the testing namespace ingress?
Finally I figured out the missing part. I had to add the following statement to the not working ingress object:
annotations:
kubernetes.io/ingress.class: public-nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
Please see the complete ingress object:
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object
namespace: default-testing
annotations:
kubernetes.io/ingress.class: public-nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- myapp.onazure.com
secretName: ingress-tls-csi-testing
rules:
- host: myapp.onazure.com
http:
paths:
- path: /testing/(.*)
pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8000
Use full DNS name of a service,
$SERVICE.$NAMESPACE.svc.cluster.local
But you need to make sure your ignress controller has acccess to the desired namespace.

Routing of application doesn't work with Kubernetes ingress

I have a Kubernetes Ingress with the following configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
This works just fine. I can open up the page in the browser and my application works perfectly fine but whenever I add another service like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /prometheus
pathType: Prefix
backend:
service:
name: prometheus
port:
number: 9090
- path: /grafana
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
things just don't work anymore. My grafana application is now accessible under /grafana but all the routes and links inside the app don't work anymore. What do I have to change that everything will work?
I've already tried adding these two annotations but it didn't change anything.
ingress.kubernetes.io/add-base-url: "true"
ingress.kubernetes.io/rewrite-target: "/$1"

Is it possible to use same hostname with multiple Ingress resources running in different namespaces?

I want to use the same hostname let's say example.com with multiple Ingress resources running in different namespaces i.e monitoring and myapp. I'm using Kubernetes nginx-ingress controller.
haproxy-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: haproxy-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
# fill in host here
- example.com
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: haproxy
port:
number: 80
grafana-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
tls:
- hosts:
- example.com
rules:
- host: example.com
http:
paths:
# only match /grafana and paths under /grafana/
- path: /grafana(/|$)(.*)
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
When I'm doing curl example.com then it is redirecting me to the deployment running in namespace one(as expected) but when I'm doing curl example.com/grafana then still it is redirecting me to namespace one deployment.
Please help.
Yes it is possible.
There can be two issues in your case.
One is you don't need the regex path for grafana ingress. Simple /grafana path will be fine with path type Prefix as with path type Prefix any /grafana/... will be redirected associated service. So the manifest file will be:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
spec:
tls:
- hosts:
- example.com
rules:
- host: example.com
http:
paths:
- path: /grafana
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
And the second issue can be the related service or deployment might not be the under same namespace monitoring. Please make sure the deployment/service/secret or other resources needed for grafana remains under the same namespace monitoring.

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.