ingress-nginx hide domain redirect & path based routing - nginx

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

Related

set rate-limits for specific apis in kubernetes nginx

I am currently using nginx-ingress-controller in my eks-cluster.
I want to set rate-limits for only specific apis like /healthz like mentioned here and not only all my APIs.
Is there a way i can do it?
Thanks in advance
For separate specific you can make another ingress resource
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/limit-rps: "15"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress
name: ingress
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /healthz
While you can make one ingress resource for other API, without rate limit setup
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress-2
name: ingress-2
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /data
- backend:
serviceName: hello
servicePort: 80
path: /api

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

How to configure multiple ingresses in different namespaces on the same host

I have a single host cluster with k8s and I would like to configure a Ingress for each namespace in order to create separated environment: one for production, one for development.
I also took 2 different domains.
When I deploy the production ingress there are no problems, but when I deploy the second ingress the dev environment is unreachable, using port-forward everything seems fine.
The 2 ingresses configuration:
Dev
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.bluemix.net/redirect-to-https: "True"
name: dev-ingress
namespace: dev
spec:
rules:
- host: '*.dev.cloud'
http:
paths:
- backend:
serviceName: web-service
servicePort: 80
path: /
tls:
- hosts:
- '*.dev.cloud'
secretName: dev-cert
Production
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.bluemix.net/redirect-to-https: "True"
name: prod-ingress
spec:
rules:
- host: '*.prod.cloud'
http:
paths:
- backend:
serviceName: web-service
servicePort: 80
path: /
- host: "k8s-host"
http:
paths:
- path: /path/to/api
backend:
serviceName: web-api
servicePort: 3000
tls:
- hosts:
- '*.prod.cloud'
secretName: prod-cert
- hosts:
- "k8s-host"
secretName: k8s-host-cert
I also edited the CNAME record of the 2 domains in order to redirect to the k8s host.
I was expecting that the request from a subdomain of one of the domain would be redirected to the ingress matching the domain.
For example:
https://abc.dev.cloud -> dev-ingress
https://abc.prod.cloud -> prod-ingress

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