Serve one path internally and a different one externally - kubernetes

I have an helm chart serving an Mediawiki using apache. Internally it does so from /wiki.
I'd like to run multiply instances and externally reach it from /something-wiki, /other-wiki and so on.
So in other words I'd like to have my ingress controller react to one path and internally go to another path.
I tried the below but it just sends a 301 (moved permanently) which doesn't work since the folder doesn't exists.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /wiki
name: wiki-environment-erst-env
namespace: wiki
spec:
rules:
- host: aks-dev.something.com
http:
paths:
- backend:
serviceName: erst-wiki-package
servicePort: 80
path: /erst-wiki
tls:
- hosts:
- aks-dev.something.com
secretName: erst-tls-secret
Any ideas?

If I understand correctly, regexp redirection might work. And the wiki configuration should be handled accordingly.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/use-regex: true
name: wiki-environment-erst-env
namespace: wiki
spec:
rules:
- host: aks-dev.something.com
http:
paths:
- backend:
serviceName: erst-wiki-package
servicePort: 80
path: /erst-wiki/.*
tls:
- hosts:
- aks-dev.something.com
secretName: erst-tls-secret

Related

Do I have to define an ingress per service with Linkerd?

Looking at the linkerd ingress documentation here it says that I need to create an ingress with an annotation of
ingress.kubernetes.io/custom-request-headers: l5d-dst-override:web-svc.emojivoto.svc.cluster.local:80
this annotation is specific to a single service, which makes it sound like there must be a new ingress with it's own annotation for every service. I couldn't have something like the following for example:
spec:
rules:
- host: example.com
http:
paths:
- path: /path-one
backend:
serviceName: service-1
servicePort: 80
- path: /path-two
backend:
serviceName: service-2
servicePort: 80
where I could define paths to different services in a single ingress class.
Is my reading of these docs accurate? or am I missing something? I am hoping to avoid creating an ingress for every service I run in linkerd.
Yes, unfortunately you understood correctly about creating separate ingress for each service if you want use ingress.kubernetes.io/custom-request-headers.
Yes, if you would have 1000 services - you should create 1000 ingresses to make it work properly.
Ingress1:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
namespace: marcus
annotations:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/custom-request-headers: l5d-dst-override:service1.marcus.svc.cluster.local:80
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
path: /
Ingress2:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
namespace: marcus
annotations:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/custom-request-headers: l5d-dst-override:service2.marcus.svc.cluster.local:80
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
path: /
Traefik is a great solution, and in this case it would be great if it had the option to dynamically set the service in a header.
There is an open issue on this in the traefik project that has been open for a while. The last update is to use an Ingress per service in these scenarios.
Here's similar question.

Ingress controller is not routing to root

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: portal-ingress-home
namespace: portal
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
#nginx.ingress.kubernetes.io/rewrite-target: /$2
ingress.kubernetes.io/whitelist-source-range: "213.#####9/20"
spec:
tls:
- hosts:
- portal
secretName: portal-tls
rules:
- host: portal
- http:
paths:
- path: /
backend:
serviceName: customer
servicePort: 80
- path: /cust(/|$)(.*)
backend:
serviceName: customer
servicePort: 80
/ path is not going to backend , where as /cust/ is going to back end. I tried every regex pattern also to make default / go to customre service, not working. I'm sure I'm missing something. Pls help....
You put the two bits under rules: in two different list items. Remove the second -.

Handling multiple sub paths via Nginx Ingress

I am struggling to have Ingress controller to properly handle sub paths. My architecture - two services sat on diff paths of one domain. Each service has its own ingress configuration:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress1
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-production-issuer"
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- hosts:
- api.mydomain.com
secretName: my-secret
rules:
- host: api.mydomain.com
http:
paths:
- path: /path1
backend:
serviceName: service1
servicePort: 80
And
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress2
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-production-issuer"
kubernetes.io/ingress.allow-http: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- api.mydomain.com
secretName: my-secret
rules:
- host: api.mydomain.com
http:
paths:
- path: /path2
backend:
serviceName: service2
servicePort: 80
With the above configuration, 1st ingress works and i am able to reach my endpoints at api.mydomain.com/path1, in the same time api.mydomain.com/path2 returns http 400. What am i doing wrong?
So the actual problem was a bit different to ingress not being able to find an endpoint. My backend services are secure gRPC services and therefore expect to be called via https or grpcs. So setting an ingress to be running against secure backends solved the problem:
nginx.ingress.kubernetes.io/secure-backends: "true"
For a newer versions of k8s you should use different attributes.

Is there a best practice to implement ingress rule with rewrite to root

For example, I have a rule (https://kubernetes.github.io/ingress-nginx/examples/rewrite/):
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
So anything that goes to rewrite.bar.com/something will go to http-svc/. And if http-svc will answer another location, e.g. /static there will be redirect to rewrite.bar.com/static and here we go - 404. I wonder is there any simple and clear solution to fix such situations without asking the developer to implement proxy_path variable or something like that?
Tried Make links in response relative to new path
Change the rewrite annotation to $1. Note I have also changed the path regex. That should do it.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something/(.*)

Default path on multiple nginx ingress rewrite

Here is my situation, I'm on kubernetes (ingress), with two docker images: one dedicated to the web and the second one to the api.
Under the next configuration (at the end of the message): /web will show the front-end that will make some calls to /api, all good there.
but / is a 404 since nothing is defined, I couldn't find a way to tell in the ingress config that / should redirect to /web
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dev-ingress
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- demo.com
secretName: tls-secret
rules:
- host: demo.com
http:
paths:
- path: /api
backend:
serviceName: api-app
servicePort: 8080
- path: /web
backend:
serviceName: web-app
servicePort: 80
This depends on what your frontend and backend apps expect in terms of paths. Normally the frontend will need to be able to find the backend on a certain external path and in your case it sounds like your backend needs to be made available on a different path externally (/api) from what it works on within the cluster (/). You can rewrite the target for requests to the api so that /api will go to / when the request is routed to the backend:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dev-ingress-backend
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- demo.com
secretName: tls-secret
rules:
- host: demo.com
http:
paths:
- path: /api
backend:
serviceName: api-app
servicePort: 8080
And you can also define a separate ingress (with a different name) for the frontend that does not rewrite the target, so that a request to /web will go to /web for it:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dev-ingress-frontend
annotations:
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- demo.com
secretName: tls-secret
rules:
- host: demo.com
http:
paths:
- path: /web
backend:
serviceName: web-app
servicePort: 80