How to ByPass Traffic directly to Backend from K8S NGINX Ingress Controller - kubernetes

OAUTH2 is used for authentication and the OAUTH2 proxy is deployed in Kubernetes. When a request is received by the NGINX Ingress controller, it always routes the traffic to OAUTH proxy. The requirement is when the request contains a specific header (For example: abc) then those requests should be routed directly to the backend. Those shouldn't be routed to OAUTH proxy. Can this be done using some sort of an annotation in NGINX Ingress controller? Can we by pass those traffic going to OAUTH2?

You may want to have a look at https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary
Let's say you have a normal Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-backend
spec:
ingressClassName: nginx
rules:
- host: XXX
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 80
Set the header name and value for your desired backend on a second Ingress, with canary enabled.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-backend-header
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: sample-header
nginx.ingress.kubernetes.io/canary-by-header-value: abc
spec:
ingressClassName: nginx
rules:
- host: XXX
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-with-header
port:
number: 80
Now, every request with sample-header: abc routes to the second ingress/service. Any other value, e. g. sample-header: test, will route to the first ingress/service.

Related

K8S traffic to one service via two separate ingress (http + https)

So I have a bunch of services running in a cluster, all exposed via HTTP only ingress object, example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: some-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- backend:
service:
name: some-svc
port:
number: 80
path: /some-svc(/|$)(.*)
pathType: Prefix
They are accessed by http://<CLUSTER_EXTERNAL_IP>/some-svc, and it works ofc.
Now I want to create an additional ingress object for every service which will force SSL connections and allow the use of a domain instead of an IP address.
The problem is that the newer SSL ingresses always return 404 while testing the connection.
The manifests are as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "some-ingress-ssl"
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/app-root: "/some-svc"
spec:
tls:
- hosts:
- foobar.com
secretName: foobar-tls
rules:
- host: foobar.com
http:
paths:
- path: /some-svc(/|$)(.*)
pathType: Prefix
backend:
service:
name: some-svc
port:
number: 80
tests (foobar.com point to CLUSTER_EXTERNAL_IP):
> curl -I http://<CLUSTER_EXTERNAL_IP>/some-svc
HTTP/1.1 200 OK
> curl -I https://foobar.com/some-svc
HTTP/2 404
Is it possible to have both ingresses simultaneously? (one enforcing SSL, the other not)
If so what am I doing wrong here?
Figured out I was missing this annotation:
nginx.ingress.kubernetes.io/rewrite-target: /$2
in SSL ingress...
works like a charm now, maybe someone will find this usefull

Only allow requests to certain paths using k8s ingress

I've set up an ingress to route traffic to my http server, however I would like to leave some routes inaccessible from outside of the cluster.
Example routes:
/status -> end point to determine service status
/users/names -> returns users
/users/ages -> returns ages
current ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: my-namespace
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: my-service
port:
number: 8080
this works currently but leaves all routes accessible. What I want to do is only have routes that fall under the /users path open, so that would be both /users/names and /users/ages. That would leave /status inaccessible from outside of the cluster. Is this achievable from changing the ingress configuration? Any help would be appreciated.
Just specify the path that you want to expose via the ingress like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: my-namespace
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: /users # <- add the path here
backend:
service:
name: my-service
port:
number: 8080

Multi-path application with path based routing in Kubernetes ingress

I want to run a spring boot application over ingress having multiple path Like
http://localhost:8888/login
http://localhost:8888/client/dev
On localhost when i run this application it automatically redirect to /login
I am using traefik ingress controller. The pod and service is running. Ingress configured as below.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/redirect-entry-point: https
traefik.ingress.kubernetes.io/rewrite-target: /
name: config
namespace: default
spec:
rules:
- host: config.example.com
http:
paths:
- backend:
service:
name: config
port:
number: 8888
path: /config
pathType: ImplementationSpecific
status:
loadBalancer: {}
when i open https://config.example.com/config it redirects to https://config.example.com/login and i get 404 error.
What annotations can be used so that it allow me to do further sub path routing.

Can I have both http and https in Ingress configuration?

I have ingress yaml like below which makes ingress to proxy HTTPS to HTTP connection. I'm confused how can I make this same ingress to process also HTTP to HTTP connection. Meaning I want it to use the same rule for both incoming HTTP or HTTPS. Removing tls portion makes it work with HTTP but adding it stops HTTP and makes it HTTPS only. Is it limitation of Kubernetes which prevents both HTTP and HTTPS routing in the same ingress controller?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
tls:
- hosts:
- "*.mydomain.com"
secretName: aks-ingress-tls
rules:
- host: "*.mydomain.net"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: frontend-service
port:
number: 80
You should redirect the HTTP request to your HTTPS listener. The requests hitting your Azure LB 80/443 listeners will be handled in the same way.
Due to Azure App gateway limitation, you cannot use a wildcard host in your ingress rules and you have to use workarounds.
See: https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#ssl-redirect
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- "*.mydomain.com"
secretName: aks-ingress-tls
rules:
- host: "www.mydomain.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: frontend-service
port:
number: 80

Minikube | Ingress Service - Bad Request

I'm working on a single-node cluster which works fine with docker-compose but the reconfiguration of the same setup using Minikube Ingress Controller gives me a Bad Request response.
Bad Request
Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
My Ingress looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /?(.*)
pathType: Prefix
backend:
service:
name: emr-cluster-ip-service
port:
number: 443
- path: /?(.*)
pathType: Prefix
backend:
service:
name: erp-cluster-ip-service
port:
number: 8069
How to fix this?
You are exposing HTTPS service on HTTP ingress, which is not the right thing to do. You might want to do one of the following:
Configure TLS-enabled ingress.
Configure TLS passthough on ingress object.
In both cases you also need to set nginx.ingress.kubernetes.io/ssl-redirect: "true"