k8s, Ingress, Minio, and a Static Site - kubernetes

We have a k8s cluster with an nginx Ingress and Minio installed. In Minio I have a bucket called tester with a hello world index.html file. I used the Minio MC client to set the tester bucket to public. Now I am able to see the hello world file when I visit my (altered) minio url like so: https://minio.example.com/tester/index.html.
My goal is to set up an Ingress resource to access the public bucket. Here is my manifest to try and do so, however I only ever get a 404 error . . .
ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend-site
namespace: "default"
labels:
type: "frontend"
awesomeness: "super-mega"
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /tester/
backend:
serviceName: minio-svc
servicePort: 9000
- path: /tester/*
backend:
serviceName: minio-svc
servicePort: 9000
tls:
- hosts:
- app.example.com
secretName: ssl-certs
I have also tried to set the paths with the index fileto no avail like so:
path: /tester/index.html
path: /tester/index.html/*
I do have another Ingress which points to Minio in general and it works perfect at the url like minio.example.com. The minio has a service called minio-svc on port 9000.
Unfortunately I have only ever received a 404 from my Ingress thus far. Anyone else deploying static sites with Ingress to public Minio bucket? What am I doing wrong???
Updates
So I kind of got somewhere. I added an annotation and set the paths to simply / and /*.
Here is my new config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend-site
namespace: "default"
labels:
type: "frontend"
awesomeness: "super-mega"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /tester/index.html
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
backend:
serviceName: minio-svc
servicePort: 9000
- path: /*
backend:
serviceName: minio-svc
servicePort: 9000
tls:
- hosts:
- app.example.com
secretName: ssl-certs
Now I just get access denied from Minio even though the bucket is public and I can still access from https://minio.example.com/tester/index.html!?

Found out you can't do what I'm asking very easily. I got around it all by simply mounting the directory from the bucket directly to Nginx. Voila!

Related

Dynamic Routing by Hostname only - Kubernetes Ingress Rules

I have a K8s cluster with multiple different services deployed and would like to use a single Ingress to route each incoming request to the appropriate service via a unique hostname DNS.
Currently, I've only been able to resolve a request when using the root path i.e. service-123.app.com.
As soon as I try to make a request with a path it doesn't resolve. The paths are valid paths to each service. For example, service-123.app.com/page/12345 would be expected by the application.
I might not fully understand how K8s Ingress rules are expected to work, but I hoped that it would match based on hostname only and simply forward on the path to the appropriate service.
Am I missing something very simple here? Any help is much appreciated. Thanks!
Here are my config files.
Ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
......
name: app-name
namespace: default
spec:
rules:
- host: service-123.app.com
http:
- path: "/*"
backend:
serviceName: service-123
servicePort: 80
- host: service-456.app.com
http:
paths:
- path: "/*"
backend:
serviceName: service-456
servicePort: 80
service.yaml
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app: service-123
name: service-123
namespace: default
spec:
ports:
- name: port8080
port: 80
targetPort: 8080
selector:
app: service-123
type: NodePort
Not sure which K8s and ingress controller you are using, but in the later K8s you can specify the pathType which takes care of path wildcards more nicely.
You would have something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
......
name: app-name
namespace: default
spec:
rules:
- host: service-123.app.com
http:
- path: /
pathType: Prefix
backend:
serviceName: service-123
servicePort: 80
- host: service-456.app.com
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: service-456
servicePort: 80
If you are using an nginx ingress controller a good way to see the right nginx configuration is by looking at the actual nginx.conf generated by the ingress controller.
$ kubectl cp <nginx-ingress-controller-pod>:nginx.conf nginx.conf
$ cat nginx.conf

Kubernetes ingress - access to web service container subpaths

I have a web service (dashboard-service) running in a container. The service provides the required webpages at:
http://192.168.1.100:3000/page2/
http://192.168.1.100:3000/page3/
etc
I have the dashboard-service running in a kubernetes cluster, and want to use ingress to control access like this:
so that I can access at: http://192.168.1.100:3000/dashboard/1
http://192.168.1.100:3000/dashboard/2
etc
I've tried the following ingress setup, but am getting "404 Not Found"
Is there some way of adding routes to subpaths?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-service
namespace: db
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /dashboard/
pathType: Prefix
backend:
service:
name: dashboard-service
port:
number: 3000
First of all, there is no below configuration in ingress
backend:
service:
name: dashboard-service
port:
number: 3000
You should use next instead..
- backend:
serviceName: dashboard-service
servicePort: 3000
Next, I would propose you install, configure and use nginx ingress controller instead of regular kubernetes-ingress. Please note also, if you use nginx controller, your annotation should be nginx.ingress.kubernetes.io/rewrite-target: , not ingress.kubernetes.io/rewrite-target:
As per NGINX Ingress Controller rewrite documentation, your ingress should look like
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /page$2
name: dashboard-service
namespace: db
spec:
rules:
http:
paths:
- backend:
serviceName: dashboard-service
servicePort: 3000
path: /dashboard(/|$)(.*)
I tested regex and capture groups for you here: https://regex101.com/r/3zmz6J/1

ERR_TOO_MANY_REDIRECTS for Minio via NGINX Ingress Controller

I have a Minio ClusterIP service running in a Kubernetes cluster. And on top of it, I have a NGINX Ingress Controller. NGINX Ingress needs to forward Minio traffic to the Minio service, and other traffic to their corresponding services.
My Ingress configuration looks like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /app/?(.*)
backend:
serviceName: app-service
servicePort: 3000
- path: /minio/?(.*)
backend:
serviceName: minio-service
servicePort: 9000
Once deployed, the app works fine. However, the Minio page has problem, complaining:
This page isn’t working
example.mysite.com redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS
And indeed, the requests are kept redirecting. Here is the screenshot from Chrome DevTools' Network console.
Any ideas?
As Minio always redirects to /minio/, you need to keep /minio in the path and pass it on to the Minio service.
When I change its path rule to - path: /(minio/.*), it works. Now the Ingress configuration looks like below:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /app/?(.*)
backend:
serviceName: app-service
servicePort: 3000
- path: /(minio/.*)
backend:
serviceName: minio-service
servicePort: 9000
And I've got the Minio service working in the browser:
Hope it is helpful.

Serve one path internally and a different one externally

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

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