Ingress-Nginx regex routing rule with named capture group in path - kubernetes-ingress

I'm creating Kubernetes Ingress resources for an nginx Ingress Controller. The paths that I'll be using have an ID that I need to extract into a variable that may be in a different location in the path. E.g.:
http://myservice/environment/<someenv>/room/<roomid>
http://myservice/join/<roomid>
If I use a non-named capture group in the regex then the first path roomid will be $2 and for the second it'll be $1. Ideally I would be able to use a named capture group to assign it to a specific variable that I can easily use but creating an Ingress with the following path with a named capture group results in an error
# ingresses.networking.k8s.io "nginx-consistent" was not valid:
# * spec.rules[0].http.paths[0].path: Invalid value: "/join/(?<roomid>.*)": must be a valid regex
Is there a supported way to use named capture groups?
The current configuration doesn't have much interesting in it. The following is a trimmed down config.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: {{.Release.Name}}-nginx-route-by-roomid
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/upstream-hash-by: "roomid-$roomid"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header ingress-handler nginx-route-by-roomid;
spec:
rules:
- http:
paths:
- backend:
serviceName: {{ .Values.service.serviceName }}
servicePort: {{ .Values.service.servicePort }}
path: /api/v1/rooms/(?<roomid>[^/]*)
- backend:
serviceName: {{ .Values.service.serviceName }}
servicePort: {{ .Values.service.servicePort }}
path: /api/v1/players/([^/]*)/rooms/(?<roomid>[^/]*)

Related

Rewrite host specific rules ingress

I assume more than two domains to be used for my multi-tenant code, domain1.com, mydomain2.com each will have a unique identifier and an ID would be maintained for each
I want my common app myApp hosted at myappdomain.com to serve both domains using CNAME and the service container should get a request prefix in the path based on the domain like:
domain1.com/home should translate the myApp request like myApp/111/home where 111 is the id
domain2.com/home should translate the myApp request like myApp/222/home where 222 is the id
This is working when the request is formed like domain1.com/myApp/111/home with the config below, but I want to use a generic rewrite rule to mask domain1.com/home to myApp/111/home & domain2.com/home to myApp/222/home
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: myapp-custom-ingress
namespace: myapp-dev
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /myapp/$1
spec:
rules:
- host: myappdomain.com
http:
paths:
- path: /myapp/(.*)
pathType: ImplementationSpecific
backend:
serviceName: ui-myapp-proxy-mgmt-webapp
servicePort: 80
- host: domain1.com
http:
paths:
- path: /myapp/(.*)
pathType: ImplementationSpecific
backend:
serviceName: ui-myapp-proxy-mgmt-webapp
servicePort: 80
Note: currently myApp is deployed in html\myApp directory of apache in the service image

ingress url returns a blank screen

I have deployed an ingress in Kubernetes for graylog and when I try to access it, it returns a blank page. but it is getting into that service. I will add my code below for your reference. and also it is the same result when i add path for another service.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: logging
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
ingressClassName: demoingress
rules:
- host: demo.graylog.com
http:
paths:
- path: /graylog(/|$)(.*)
pathType: Prefix
backend:
service:
name: graylog-web
port:
number: 9000

How to configure Ingress in eks using private alb?

Unable to getting Private ALB using below snippet Ingress code
Followed steps to configure Ingress controller by using below URL:
https://aws.amazon.com/premiumsupport/knowledge-center/eks-alb-ingress-controller-setup/
Much appreciated if any one can help how to configure Ingress with private ALB.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ipc-ingress-dev
# labels:
# app: usermgmt-restapp
annotations:
# Ingress Core Settings
kubernetes.io/ingress.class: alb
kubernetes.io/role/internal-elb: 1
# kubernetes.io/cluster/ipc-eks-Cluster-dev-us: owned
alb.ingress.kubernetes.io/subnets: subnet-qqq, subnet-rrr, subnet-ttt
alb.ingress.kubernetes.io/scheme: internal
# alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/security-groups: sg-xxx, sg-yyy, sg-zzz
# Health Check Settings
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
alb.ingress.kubernetes.io/target-type: instance
#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
# alb.ingress.kubernetes.io/healthcheck-path: /xyzapi/health-status
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
alb.ingress.kubernetes.io/success-codes: '200'
alb.ingress.kubernetes.io/healthy-threshold-count: '2'
alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
spec:
# ingressClassName: alb
# tls:
# - hosts:
# secretName: my-secret-dev
rules:
- http:
paths:
- path: /xyzapi/*
backend:
serviceName: bwei-svc
servicePort: 5044
[1]: https://aws.amazon.com/premiumsupport/knowledge-center/eks-alb-ingress-controller-setup/

Azure AKS | Application gateway | Ingress | Backend Prefix

I am bit confused the way path resolves the endpoint, does it show in any logs the final endpoint it creates. I am stuck with this now. Below is the endpoint which I wanted to call:-
https://hostname/api/orders/employees. And to call this endpoint through Ingress application gateway, this is how I configured but it always return 502 bad gateway error.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ordersapi
namespace: orders
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: orders.apps.com
http:
paths:
- path: /api/orders/employees
backend:
serviceName: orderservice
servicePort: 80
Finally, there are two solution to this problem:-
First
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ordersapi
namespace: orders
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: orders.apps.com
http:
paths:
- path: /api/orders/employees
backend:
serviceName: orderservice
servicePort: 80
- path: /api/product/products
backend:
serviceName: orderservice
servicePort: 80h
Second
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ordersapi
namespace: orders
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/api/"
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: orders.apps.com
http:
paths:
- path: /api/*
backend:
serviceName: orderservice
servicePort: 80
You seem to have enabled SSL redirect but your service is serving on a non ssl port.
this could explain the bad gateway.
Often, the Azure AppGW will return 502 Bad Gateway when there are bad Certs involved, the health check for the backend service is wrong, and other reason
You should look at this:
https://support.microsoft.com/en-ca/help/4504111/azure-application-gateway-with-bad-gateway-502-errors
and this
https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-troubleshooting-502
I got same issue. My ingress setup was like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-name
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
rules:
- host: <myhostname>
http:
paths:
- path: /api*
backend:
serviceName: backend-app
servicePort: 80
- path: /
backend:
serviceName: frontend-app
servicePort: 80
If I defined path like /api/todolist, the endpoint worked fine. On the other hand if I went with /api* my requests were redirected to frontend app.
The problem was that endpoint /api/todolist existed on my backend and returned status was 200, for the /api endpoint I did not setup anything so I got 404 status.
In my case I needed to add healthcheck under /api edpoint, that returned proper http status :) For me returning string "Healthy" was enough.
#djsly #Jean-Philippe Bond - Thanks for your response and pointing the URL that helped me to investigate further. Having the backend application deployed on port 80 had a reason as SSL terminates at application gateway and listener redirects the request to backend application running on port 80, which works fine.
After further investigation, I added backend path prefix in ingress file (appgw.ingress.kubernetes.io/backend-path-prefix: "/api/orders/employees") which resolved the problem for one endpoint but not for all.
To describe the problem in details, application contains some of the restful services mentioned below and their endpoints are such as -
http://hostname/api/orders/employees
http://hostname/api/Lookup/officeHierarchy
http://hostname/api/Department/codes
http://hostname/api/position/members
Now if you see, these different endpoints starts with prefix "/api/" and then the controller name and actions.
Here Expected Result is
If any of these endpoints are called (via HTTP Get), data should be returned but it fails.
Investigation done so far
I added the prefix and did some changes to it. Thus If I configure my ingress like below, it returns the result successfully for only one specific endpoint - >
curl -v http://orders.apps.com/api/orders/employees returns 200 but fails for others.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ordersapi
namespace: orders
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/api/orders/employees"
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: orders.apps.com
http:
paths:
- path: /api/orders/employees
backend:
serviceName: orderservice
servicePort: 80
Thus , to make all endpoints works, I did the below changes in the above mentioned ingress file but calling
curl -v http://orders.apps.com/api/orders/employees returns 404. And the same goes with other endpoints like
curl -v http://orders.apps.com/api/department/codes returns 404.
As per my understanding, by doing the below changes - "path - /api/*" should be overwritten to the path - /api/orders/employees being called but it does not.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ordersapi
namespace: orders
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/api/"
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "wildcard.apps.com"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: orders.apps.com
http:
paths:
- path: /api*
backend:
serviceName: orderservice
servicePort: 80
Your suggestions are appreciated.
Thanks
Defining multiple paths without backend-path-prefix worked, e.g.
http:
paths:
path: /api/order/employees
backend:
serviceName: orderservice
servicePort: 80
path: /api/position/members
backend:
serviceName: positionservice
servicePort: 80
This seems to be a complex way but so far I found this the only way which worked.
For me the solution was to just add "*" to paths, e.g.
rules:
- http:
paths:
- pathType: Prefix
path: /api/*
backend:
service:
name: api
port:"
number: 80
- pathType: Prefix
path: /graphql*
backend:
service:
name: api
port:
number: 80
without any extra annotations. For whatever reason it does not work without "*" at the end.

Redirect specific sub directory to new url in Ingress

I need to redirect a specific URL to a new one.
I can use this code to redirect root domain but it doesn't work for subdirectory likes testdomain.com/specific-url
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'testdomain.com/specific-url') {
return 308 https://testdomain.com/new-url;
}
Try to use below approach I suggested here.
And copy paste for future:
My advice is to use NGINX Plus Ingress Controller annotation functionality if you can afford it.
You can find official example here.
Example:
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 /coffee/).
/coffee/ -> /beans/
/coffee/abc -> /beans/abc