I have the following ingress resource for one of my apps
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name:""
annotations:
ingress.kubernetes.io..
spec:
rules:
- host: my-app
http:
paths:
- path: /path/to/service
backend:
serviceName: my-service
servicePort: 80
This works as expected and I can access my service at http://my-app/path/to/service. However the service in my app takes query parameters that dont seem to correctly get redirected for eg:
http://my-app/path/to/service/more/paths
This brings me back to http://my-app/path/to/service
How can I maintain this path structure ?
I believe you need to use wildcards on your path:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name:""
annotations:
ingress.kubernetes.io..
spec:
rules:
- host: my-app
http:
paths:
- path: /path/to/service/*
backend:
serviceName: my-service
servicePort: 80
More information here. Seems like it's hard to find any docs with wildcard examples. Not that this is specific to nginx, it may not work with other ingress controllers.
Related
I am trying to learn .NET Microservice. I have been following a great tutorial on Youtube (Time: 4:44:55, Adding An API Gateway). Everything worked well until NGINX Ingress came into the picture. I pasted the same YAML file from the GitHub account of the trainer I doubled checked all the things but couldn't find anything:
I can see all the pods and services are working fine:
I updated my host file.
What did I miss?
URL, I am using: http://acme.com/api/platforms/
Error: HTTP Error 404. The requested resource is not found.
The output of the Ingress YAML:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/use-regex":"true"},"name":"ingress-srv","namespace":"default"},"spec":{"rules":[{"host":"acme.com","http":{"paths":[{"backend":{"service":{"name":"platforms-clusterip-srv","port":{"number":80}}},"path":"/api/platforms","pathType":"Prefix"},{"backend":{"service":{"name":"commands-clusterip-srv","port":{"number":80}}},"path":"/api/c/platforms","pathType":"Prefix"}]}}]}}
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
creationTimestamp: "2021-09-18T00:12:41Z"
generation: 1
name: ingress-srv
namespace: default
resourceVersion: "2274742"
uid: a7376202-8b1b-4f1a-a42f-08de5f602192
spec:
rules:
- host: acme.com
http:
paths:
- backend:
service:
name: platforms-clusterip-srv
port:
number: 80
path: /api/platforms
pathType: Prefix
- backend:
service:
name: commands-clusterip-srv
port:
number: 80
path: /api/c/platforms
pathType: Prefix
status:
loadBalancer:
ingress:
- hostname: localhost
Services:
UPDATE: Tried below commands and got some new information:
UPDATE: Result of
Kubectl get pods --namespace=ingress-nginx
Try removing the regex annotation from th ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: ingress-srv
namespace: default
spec:
rules:
- host: acme.com
http:
paths:
- backend:
service:
name: platforms-clusterip-srv
port:
number: 80
path: /api/platforms
pathType: Prefix
- backend:
service:
name: commands-clusterip-srv
port:
number: 80
path: /api/c/platforms
pathType: Prefix
or just try this nginx.ingress.kubernetes.io/rewrite-target: /
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: acme.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: commands-clusterip-srv
port:
number: 80
in above ingress, all requests will go to service commands-clusterip-srv so from browser side you pass anything either /api or /api/c ingress will route the traffic to that service if your host is acme.com
Error 404 clearly means there is some issue with your Nginx configuration path is not matching or host issue, Nginx not able to find upstream or target so it throws 404.
Update
Try adding IP and entry into the host file for
192.168.1.28 acme.com
i am not sure you have used the IP POD to curl ideally you should me using the acme.com as you can to access the data.
also hope you service, deployment and ingress are in same namespace.
First of all, Thank you Harsh for your precious time. I tried all the things but no error was found.
It was really a miracle that I am able to resolve it issue on HTTPS. I am able to access "https://acme.com/api/platforms". But still, HTTP is giving me the same error. However, I am fine with HTTPS
We are using Azure App G/w Ingress Controller to expose services hosted within AKS.
E.g.
Service named abc is hosted in AKS as below
apiVersion: v1
kind: Service
metadata:
labels:
project: abc
app: abc
env: dev
name: abc
namespace: abc
spec:
ports:
- name: http
# This is the external port of the cluster
port: 8443
protocol: TCP
targetPort: http
selector:
project: abc
app: abc
env: dev
type: ClusterIP
Ingress Configuration
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-abc
namespace: abc
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
rules:
- http:
paths:
- backend:
serviceName: abc
servicePort: 9000
path: /abc*
Problem Statement
Front-end will send request to the backend like: https://app-gw-ip/abc/operation.
App G/w applies appropriate routing rule and converts the request_uri to "//operation". "abc" in the URL path is overwritten by "/" because of the backend-path-prefix annotation. Whereas we want the request_uri as "/operation"
Is there a way to set backend-path-prefix to empty string ?
I want to replace "abc/" in the URL path with "/". Currently it replaces "abc" with "/".
If I do not use the backend-path-prefix, then backend uri path will be "abc/operation". This will return 404 because abc service will not have any endpoint named abc/operation.
Just use path as path: /abc/*
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-abc
namespace: abc
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
rules:
- http:
paths:
- backend:
serviceName: abc
servicePort: 9000
path: /abc/*
i am not able to understand one point in the rate-limiting of Nginx ingress
i was referring to one article regarding rate limiting with nginx ingress : https://medium.com/titansoft-engineering/rate-limiting-for-your-kubernetes-applications-with-nginx-ingress-2e32721f7f57#:~:text=When%20we%20use%20NGINX%20ingress,configure%20rate%20limits%20with%20annotations.&text=As%20an%20example%20above%2C%20the,qps)%20on%20the%20Hello%20service.
in limitation section at last
It applies to the whole ingress and is not able to configure
exceptions, eg. when you want to exclude a health check path /healthz
from your service.
if i am creating two ingresses with different names, one has path /hello1 and another /hello2 both pointing to the same service backend.
Now if i am adding rate limiting to only one ingress or path /hello1 will it affect another? if the same host or domain is there ???
ingress 1 : example.com/hello1 - rate-limit set
ingress 2 : example.com/hello2 no rate limiting
Thanks in advance
Rate limit will be applied only to that ingress where you specified it. What is basically nginx-ingress doing in the background - it merges rules into 1 huge config, however they applies to different objects.
e.g 2 different ingresses for same host and diff path.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test1
annotations:
kubernetes.io/ingress.class: 'nginx'
nginx.ingress.kubernetes.io/limit-rps: '5'
spec:
rules:
- host: example.com
http:
paths:
- path: /path1
backend:
serviceName: service1
servicePort: 8080
and
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test2
annotations:
kubernetes.io/ingress.class: 'nginx'
nginx.ingress.kubernetes.io/limit-rps: '10'
spec:
rules:
- host: example.com
http:
paths:
- path: /path2
backend:
serviceName: service1
servicePort: 8080
I am trying to deploy Jenkins on Kubernetes. I have deployed it with ClusterIP along with Nginx Ingress Controller on AKS.
When I access the IP of the Ingress-Controller, the Jenkins login URL (http://ExternalIP/login?from=%2F) comes up. However the UI of the Jenkins page isn't coming up and there is a some sort of redirection happening and keeps growing (http://ExternalIP/login?from=%2F%3Ffrom%3D%252F%253Ffrom%253D%25252F%25253F). I am very new to Ingress controller and annotations. I am not able to figure on what's causing this redirection.
Below are my configuration files. Can anyone please help on what's going wrong ?
ClusterIP-Service.yml
kind: Service
apiVersion: v1
metadata:
name: jenkins-nodeport-svc
namespace: jenkins
labels:
env: poc
app: myapp_jenkins
spec:
ports:
- name: "http"
port: 80
targetPort: 8080
type: ClusterIP
selector:
app: myapp_jenkins
Ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
rules:
- http:
paths:
- backend:
serviceName: jenkins-nodeport-svc
servicePort: 80
path: /(.*)
There's something in your ingress:
path: /(.*)
is a regular expression with a single capturing group that match everything. For example with following url: http://ExternalIP/login?from=myurl your capturing group $1 (the first and only one) would match login?from/myurl.
Now the problem is that nginx.ingress.kubernetes.io/rewrite-target: /$2 annotation is rewriting your url with a non existing capturing group.
You don't need rewriting, you just need to plain forward every request to the service.
Here you can find Rewrite Examples if you interested on it.
But in your case you can set:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
rules:
- http:
paths:
- backend:
serviceName: jenkins-nodeport-svc
servicePort: 80
path: /
and you're good to go.
I have a k8s 1.9.0 cluster and following is my ingress rule.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
labels:
app: report
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "gayan.test.com"
http:
paths:
- path: /report
backend:
serviceName: qc-report-svc
servicePort: 80
- path: /report/*
backend:
serviceName: qc-report-svc
servicePort: 80
So I have two requests.
Request one - https://gayan.test.com/report/ping This request hit the pod and return the response.
(GET /ping 200 302.079 ms - 63)
Request two - wss://gayan.test.com/report/socket.io/?EIO=3&transport=websocket.
This request doesn't even hit the server. I think this is related to ingress rule.
My question is how can I send all the /report traffic to qc-report-svc service?
Assuming you are using the Nginx Ingress Controller you need to add the nginx.org/websocket-services annotation to enable WebSocket support.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
labels:
app: report
annotations:
ingress.kubernetes.io/rewrite-target: /
nginx.org/websocket-services: "qc-report-svc"
spec:
rules:
- host: "gayan.test.com"
http:
paths:
- path: /report
backend:
serviceName: qc-report-svc
servicePort: 80