nginx-ingress: Redirect host URI based on request header for specific range of IPs - kubernetes

I am new to K8s and learning the concepts.
I need to achieve the following requirements using nginx-ingress in K8s
Whenever we receive request to abc.com/api it should get redirected to example.com/api, if the request is not from whitelisted IP range.
Kindly assist me with suggestions or feedback on this.
Thank you
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.class: nginx
meta.helm.sh/release-name: static-web
meta.helm.sh/release-namespace: default
nginx.ingress.kubernetes.io/rewrite-target: /404.html
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
app.kubernetes.io/managed-by: Helm
name: internal-ingress
namespace: default
spec:
rules:
- host: abc.com
http:
paths:
- backend:
service:
name: nginx-svc
port:
number: 8000
path: /api/user-service
pathType: Prefix
- backend:
service:
name: nginx-svc
port:
number: 8000
path: /api/notification-service
pathType: Prefix
tls:
- hosts:
- abc.com
secretName: ingress-secret-tls

Related

Restricting Keycloak admin url

I am trying to restrict keycloak admin context (https://myserver.domain.com/auth/admin/*) to specific IPs only, However, want to keep other context open for all (Eg. /).
The service is running in GKE cluster with LoadBalancer, Nginx Ingress and backend. Below are the two configs created to achieve the above requirement.
Ingress1 is working and accessible to all including /auth/admin/*
Nginx Ingress1:
`
annotations:
nginx.ingress.kubernetes.io/affinity: cookie
labels:
app.kubernetes.io/managed-by: Helm
name: kc-ingress
namespace: kc
spec:
ingressClassName: nginx
rules:
host: my.domain.com
http:
paths:
backend:
service:
name: kc-service
port:
number: 80
path: /
pathType: ImplementationSpecific
`
Ingress2 is created to restrict the /auth/admin/* which is not working as expected.
Nginx Ingress2:
`
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: x.x.x.x/32
labels:
app.kubernetes.io/managed-by: Helm
name: kc-ingress-restricted
namespace: kc
spec:
ingressClassName: nginx
rules:
host: my.domain.com
http:
paths:
backend:
service:
name: kc-service
port:
number: 80
path: /auth/admin/(.*)
pathType: Prefix
`
Not sure what else is missing here.

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.

Combining routes of frontend and backend

I have a React front-end and Flask API as back-end.
I wish to have both front-end and back-end routes accessible at same address. E.g frontend at myapp.web.com and backend at myapp.web.com/api.
It will have different deployments for them. I want to know how to do this.
Yes, you can have the same domain that can point to multiple services based on the path.
Normally this can help you to resolve the CORS issue.
API
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
name: backend-ingress
namespace: backend-api
spec:
rules:
- host: myapp.web.com
http:
paths:
- backend:
service:
name: backend-service-name
port:
number: 80
path: /api
pathType: Prefix
tls:
- hosts:
- myapp.web.com
secretName: my-secret-tls
Frontend ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: frontend-service
namespace: frontend-service
spec:
rules:
- host: myapp.web.com
http:
paths:
- backend:
service:
name: frontend-service-name
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- myapp.web.com
secretName: my-secret-tls
so in this case, all the requests that start with /api will route to the backend app and rest of the requests will route to frontend.

How to disable tls for specific traefik ingress in kubernetes?

I am using traefik ingress controller in Kubernetes. It is configured to redirect all request to https and terminate tls connection before passing the request to backend service.
Is it possible to only enable http for one particular ingress config but https for other ingresses ? Any example would be helpful.
I only want to enable http(no https) for this ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: testdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 8080
You can create the one ingress with the config like
apiVersion: networking.k8s.io/v1
kind: Ingress
annotation:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/force-ssl-redirect: "false"
ingress.kubernetes.io/ssl-redirect: "false"
traefik.ingress.kubernetes.io/frontend-entry-points: http
metadata:
name: test-ingress
spec:
rules:
- host: testdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 8080
you can get more idea about the annotation from here : https://doc.traefik.io/traefik/v1.6/configuration/backends/kubernetes/

not able to create the rule for the ingress controller

What am I going wrong in the below query?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
serviceName: nginx
servicePort: 80
The error I am getting:
error validating "ingress.yaml": error validating data: [ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "serviceName" in io.k8s.api.networking.v1.IngressBackend, ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "servicePort" in io.k8s.api.networking.v1.IngressBackend]; if you choose to ignore these errors, turn validation off with
--validate=false
Ingress spec has changed since updated to v1. Try:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
According to this documentation you need to change ServiceName and ServicePort.
Each HTTP rule contains (...) a list of paths (for example, /testpath), each of which has an associated backend defined with a service.name and a service.port.name or service.port.number. Both the host and path must match the content of an incoming request before the load balancer directs traffic to the referenced Service.
Here is your yaml file with corrections:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
service:
name: nginx
port:
number: 8080
ServiceName and ServicePort no keywords are available like that in v1 .
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
service:
name: nginx
port:
number: 8080
service name and service port syntax is incorrect. Follow the below sample
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80