Kubernetes nginx ingress configuration for wildcard rule - nginx

I am struggling with the following issues. I have 2 services running. I am using a wildcard for handling subdomains. See the example conf below:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: web-static-ip
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/server-alias: www.foo.bar
nginx.ingress.kubernetes.io/use-regex: "true"
name: foo-bar-ingress
namespace: test
spec:
rules:
- host: '*.foo.bar'
http:
paths:
- backend:
serviceName: legacy-service
servicePort: 80
path: /(.*)
pathType: ImplementationSpecific
- host: foo.bar
http:
paths:
- backend:
serviceName: new-service
servicePort: 8080
path: /(.*)
pathType: ImplementationSpecific
Using the app in the way that abc.foo.bar -> legacy-service and foo.bar -> new-service work perfectly fine. However, when I access the app with www prefix, it gets under the wildcard subdomain path, meaning www.foo.bar goes into legacy-service, which is what I want to avoid. AFAIU this "www" is caught by this asterisk regexp and goes in the wrong way. I would like it go to new-service.
Is there any way I can achieve this with the nginx ingress configuration?

Also redirecting requests from www.foo.bar can be achieved by also specifying the hostname. Please note that the order of the hosts does matter as they are translated into the Envoy filter chain. Therefore, the wildcard host should be the last host.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: web-static-ip
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/server-alias: www.foo.bar
nginx.ingress.kubernetes.io/use-regex: "true"
name: foo-bar-ingress
namespace: test
spec:
rules:
- host: 'foo.bar'
http:
paths:
- backend:
serviceName: new-service
servicePort: 8080
path: /(.*)
pathType: ImplementationSpecific
- host: 'www.foo.bar'
http:
paths:
- backend:
serviceName: new-service
servicePort: 8080
path: /(.*)
pathType: ImplementationSpecific
- host: '*.foo.bar'
http:
paths:
- backend:
serviceName: legacy-service
servicePort: 80
path: /(.*)
pathType: ImplementationSpecific

Related

ingress-nginx hide domain redirect & path based routing

I'm using ingress-nginx on kubernetes. I need to redirect incoming connections to / to a blog hosted on webflow and perform path-based routing.
Webflow provides a domain like website123.webflow.com. I would like to serve the blog without performing a redirect. I would like to mask the webflow domain and use the default instead.
Here's what I came with so far:
---
apiVersion: v1
kind: Service
metadata:
name: homepage
spec:
externalName: website123.webflow.io
type: ExternalName
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
external-dns.alpha.kubernetes.io/hostname: my.custom.domain.com
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/load-balance: ewma
nginx.ingress.kubernetes.io/proxy-body-size: 4G
nginx.ingress.kubernetes.io/upstream-vhost: website123.webflow.io
service.beta.kubernetes.io/do-loadbalancer-hostname: my.custom.domain.com
labels:
source: github
name: http
namespace: panattt1
spec:
rules:
- host: my.custom.domain.com
http:
paths:
- path: /api
backend:
serviceName: http
servicePort: 80
- path: /images
backend:
serviceName: http
servicePort: 80
- path: /app
backend:
serviceName: http
servicePort: 80
- path: /game
backend:
serviceName: http
servicePort: 80
- path: /mapmaker
backend:
serviceName: http
servicePort: 80
- path: /dashboard
backend:
serviceName: http
servicePort: 80
- path: /
backend:
serviceName: homepage
servicePort: 80
tls:
- hosts:
- my.custom.domain.com
The above solution doesn't work as I'd like to. The URL in the browser changes from my.custom.domain.com to website123.webflow.io, which is not what I want.
I believe the host header reaches paths other than / which is not ideal. Not tested yet.
If remove nginx.ingress.kubernetes.io/upstream-vhost I get an error from webflow's CDN because the $host header uses a domain that is not available. Adding the custom domain produces the same error.
Any ideas if I can handle this situation gracefully using ingress-nginx?
This works for me without annotations like upstream-vhost etc.
kind: Service
metadata:
name: blog-service
namespace: panattt1
spec:
externalName: website123.webflow.io
ports:
- port: 8001
protocol: TCP
targetPort: 443
type: ExternalName
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
name: blog-ingress
namespace: panattt1
spec:
rules:
- host: my.custom.domain.com
http:
paths:
- backend:
serviceName: blog-service
servicePort: 8001
path: /
tls:
- hosts:
- my.custom.domain.com

Kubernetes + ingress-nginx - two apps, one of which in / path

I have two apps on a Kubernetes cluster which need to be exposed. One is a OAuth2 based authenticator, the other is the client app using it.
I would like to have the client app on test.mydomain.com and the authenticator on test.mydomain.com/auth
I tried building the following ingress in Kubernetes:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "20m"
spec:
rules:
- http:
paths:
- path: /auth
backend:
serviceName: authenticator-service
servicePort: 8080
- path: /
backend:
serviceName: app-service
servicePort: 8080
For some reason, I can't get it to work, and whenever I try and hit test.mydomain.com/auth I end up hitting the main app-service. Am I doing something completely wrong? Is what I want to do even possible?
Try this -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: nginx
name: my-ingress
spec:
rules:
- host: test.mydomain.com
http:
paths:
- path: /(.*)
backend:
serviceName: app-service
servicePort: 8080
- path: /auth/(.*)
backend:
serviceName: authenticator-service
servicePort: 8080

kubernetes nginx-ingress always redirecting to 404 default backen ignoring path rules

After setting TLS succesfully, i'm not able to reach my web application through the ingress, since it is always redirecting to 404 default backend
This is my ingress configuration:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: 'letsencrypt-prod'
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
tls:
- hosts:
- xxxx.com
- www.xxxx.com
secretName: xxxx-com
rules:
- host: xxxx.com
- http:
paths:
- path: /(.*)
backend:
serviceName: web-cluster-ip-service
servicePort: 3000
- host: www.xxxx.com
- http:
paths:
- path: /(.*)
backend:
serviceName: web-cluster-ip-service
servicePort: 3000
Removing TLS options make it work fine (thought is not using TLS anymore):
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /(.*)
backend:
serviceName: web-cluster-ip-service
servicePort: 3000
Nevermid, after many hours i found that my configuration has an error:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: 'letsencrypt-prod'
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
tls:
- hosts:
- xxxx.com
- www.xxxx.com
secretName: xxxx-com
rules:
- host: xxxx.com
http:
paths:
- path: /(.*)
backend:
serviceName: web-cluster-ip-service
servicePort: 3000
- host: www.xxxx.com
http:
paths:
- path: /(.*)
backend:
serviceName: web-cluster-ip-service
servicePort: 3000
Hypens should be removed before http in each host block
That was... hard to find, a warning message when applying a possible weird/wrong configuration would not have hurt anyone

K8S - Ingress - Route 2 different applications

In my minikube k8s cluster, I have 2 applications/services.
This is my ingress controller for the services I have.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tutorial
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
backend:
serviceName: default-http-backend
servicePort: 80
rules:
- host: mysite.com
http:
paths:
- path: /sva
backend:
serviceName: app-a
servicePort: 8080
- path: /svb
backend:
serviceName: app-b
servicePort: 8150
When i type mysite.com/sva or mysite.com/svb it routes to appropriate services. However, none of the static files (js, css, images etc) is loaded as they seem to request for the resources from mysite.com instead of mysite.com/sva/
How can I make it look for the resources under specific service?
Try to Add the following annotation in ingress
ingress.kubernetes.io/add-base-url: "true"
will solves this problem.
You can also review : https://github.com/kubernetes/ingress-nginx/issues/333
Based on Harsh Manvar answer, Looks like rewrite does not work on the static resources as of now.
This is a workaround I am planning to follow to route diff apps like sva.mysite.com or svb.mysite.com. It works fine. Just adding this as an answer if somebody faces similar problem.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tutorial
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
backend:
serviceName: default-http-backend
servicePort: 80
rules:
- host: sva.mysite.com
http:
paths:
- path: /
backend:
serviceName: app-a
servicePort: 8080
- host: svb.mysite.com
http:
paths:
- path: /
backend:
serviceName: app-b
servicePort: 8150

Rewrite path for nginx Ingress

I need to point Ingress to images so that my Pods gets the URL, in full. I have the below config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: solar-demo
annotations:
nginx.org/server-snippet: "proxy_ssl_verify off;"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: shmukler.example.com
http:
paths:
- path: /city/*
backend:
serviceName: solar-demo
servicePort: 3000
- path: /solar/*
backend:
serviceName: solar-demo
servicePort: 3001
If I keep the line: nginx.ingress.kubernetes.io/rewrite-target: /, my services inside the Pods get the rewritten paths, so /city/dublin becomes /dublin.
If I comment out the line nginx.ingress.kubernetes.io/rewrite-target: /, I just get 503 errors on the client side, and nothing in the logs. With rewrite, my services give me 404 because there is no route /dublin.
What am I doing wrong? How could I just pass the path on and have the Pods respond?
$ kubectl describe svc solar-demo
Name: solar-demo
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration=
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"solar-demo","namespace":"default"},"spec":{"ports":[{"name":"city","port":3000...
Selector: app=testapp
Type: ClusterIP
IP: 10.107.221.76
Port: city 3000/TCP
TargetPort: 3000/TCP
Endpoints: 172.17.0.3:3000,172.17.0.8:3000
Port: solar 3001/TCP
TargetPort: 3001/TCP
Endpoints: 172.17.0.3:3001,172.17.0.8:3001
Session Affinity: None
Events: <none>
Suggestions?
Here should be a working config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: solar-demo
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: shmukler.example.com
http:
paths:
- path: /city
backend:
serviceName: solar-demo
servicePort: 3000
- path: /solar
backend:
serviceName: solar-demo
servicePort: 3001
What changed:
Removed * from paths
Specified ingress in the annotation
Removed re-write annotation
The path on an ingress (when using an nginx ingress) is like specifying the nginx location block. nginx does not use the * character in location blocks.

Resources