Ingress rule for multiple paths not working as expected - kubernetes

here is the situation: I have 2 deployments running for sonarqube (for different use cases) linked to 2 different services and I am redirecting traffic through Ingress path based routing.
metadata:
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
name: sonarqube
namespace: sonar-namespace
spec:
rules:
- host: sonar.example.com
http:
paths:
- backend:
serviceName: sonar-service-1
servicePort: 80
path: /sonarqube/
- backend:
serviceName: sonar-service-2
servicePort: 80
path: /sonarqube-two/
I am able to access UI page under /sonarqube and under /sonarqube-two/ as well but whenever I am trying to take any action (say installing new plugins, creating new user etc) it's redirecting me to login page every single time. Could someone please help me this? Let me know if any information is required from my side.

You need to tell Sonarqube the path in which it is running, if you're not using the default path /.
You can set that by setting
sonar.web.context=/sonarqube
in $SONARQUBE-HOME/conf/sonar.properties
Taken from the official documentation: https://docs.sonarqube.org/latest/setup/install-server/ (Starting the Web Server)
An alternative approach would be to use subdomains instead of paths to host it (e.g. sonar1.example.com and sonar2.example.com). Then you wouldn't need to modify your configuration.

Never thought that issue would be with cache and cookies! Opened a new browser(firefox) and cleared all the history, cache, and cookies and after that, all started working. Now being able to open and take POST actions on both the URLs. Thanks Harsh and Pampy for taking out time and helping me out.

Related

How to use ingress so that services can talk to each other?

On AWS EKS, I have three pods in a cluster each of which have been exposed by services. The problem is the services can not communicate with each other as discussed here Error while doing inter pod communication on EKS. It has not been answered yet but further search said that it can be done through Ingress. I am having confusion as to how to do it? Can anybody help ?
Code:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: ingress-test
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: server-service
port:
number: 8000
My server-service has APIs like /api/v1/getAll, /api/v1/updateAll, etc.
So, what should I write in path and for a database service what should I do??
And say in future I make another microservice and open another service which has APIs like /api/v1/showImage, /api/v1/deleteImage will I have to write all paths in ingress or is their another way for it to work?
A Ingress is a really good solution to expose both a frontend and a backend at the same domain with different paths (but reading your other question, it will be of no help in exposing the database)
With this said, you don't have to write all the paths in the Ingress (unless you want to) as you can instead use pathType: Prefix as it is already in your example.
Let me link you to the documentation Examples which explain how it works really well. Basically, you can add a rule with:
path: /api
pathType: Prefix
In order to expose your backend under /api and all the child paths.
The case where you put a second backend, which wants to be exposed under /api as the first one, is way more complex instead. If two Pods wants to be exposed at the same paths, you will probably need to list all the subpaths in a way that differentiate them.
For example:
Backed A
/api/v1/foo/listAll
/api/v1/foo/save
/api/v1/foo/delete
Backend B
/api/v1/bar/listAll
/api/v1/bar/save
/api/v1/bar/delete
Then you could expose one under subPath /api/v1/foo (Prefix) and the other under /api/v1/bar (Prefix).
As another alternative, you may want to expose the backends at different paths from what they actually expect using a rewrite target rule.

NGINX Ingress to Microk8s Bare metal cluster not working as expected

First a little background:
We currently have several websites and services hosted on a Plesk server and I am setting up a bare-metal development server to provide an area where we can test updates, etc. before going to production. I am using a 3 node kubernetes cluster running microk8s on Ubunutu 20.04.01. The services we host are pretty diverse: we have a couple Moodle sites, a few Wordpress sites, a site running limesurvery, an instance of Mantis bugtracker, and a few more. I have successfully gotten most of the sites containerized and running on k8s. I can also access each individual site either through a NodePort or a MetalLB load balancer.
However, I'd really like to use the NGINX Ingress Controller on top of the load balancer so that I can have a consistent way to access the sites without using a bunch of IP addresses (or in the NodePort case, ports that change). No matter what I've done, I cannot seem to get the Ingress to do what I want. I simply want to do the following:
http://<LB IP Address>/bugtracker to access the Mantis Bug Tracker site
http://<LB IP Address>/moodle1 to access one of the Moodle sites
http://<LB IP Address>/limesurvey to access the limesurvey,
etc. I seem to be able to get to the main page of the site (e.g. index.html, index.php, etc.), but any references from there on do not work - i.e. they give path not found errors or 404 errors.
Here's a sample of my Ingress file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /limesurvey(/|$)(.*)
pathType: Prefix
backend:
service:
name: limesurvey-svc
port:
number: 80
- path: /moodle(/|$)(.*)
pathType: Prefix
backend:
service:
name: moodle-svc
port:
number: 8080
This ingress does not work (I get the 404s). However, if I only have one path in the file and just use '/' it works (but I can only use it for one service):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: limesurvey-svc
port:
number: 80
I think what I need is for the path (limesurvey) to continue to be pre-pended onto each URL request, but I cannot seem to make this happen. The reason I think this is because when I navigate to http://<LB IP Address>/limesurvey and click on a survey, I get a 404 error at http://<LB IP Address>/index.php/<survey number>. However, if I manually change the URL in my browser to http://<LB IP Address>/limesurvey/index.php/<survey number> it will access the survey (but still have 404s with supporting assets).
Am I trying to do something outside of what the Ingress controller was designed for? I feel like I should be able to use the rewrite-target to accomplish this but I'm missing something critical.
I appreciate any help.
Some applications relay on static content served from different URL webserver locations and moreover do internal path routing (e.g. you hit "/" path but get served "/admin" section immediately).
In such cases creation of right Ingress rules gets more tricky, and requires you to better understand behavior and constructs of your web application, to predict all possible URL path locations that user may visit (these forced by app internal redirects too), and these sourced by html code as well.
Seems like your case with limesurvey app falls into that category:
Why do I think that?
Just try to open limesurvey public demo (https://demo.limesurvey.org/) and inspect site content.
You will learn that main page is using a lot of static files (e.g. css, javascrpt files), referenced from absolute path starting with: /tmp/assets/...
<link rel="stylesheet" type="text/css" href="/tmp/assets/2d523ae6/survey.css" />
of course variants of different path locations can be matched with single smart reg-ex pattern, to avoid creation of dozen of individual ingress rules (what you tried).
What's the issue?
rules:
- http:
paths:
- path: /limesurvey(/|$)(.*) <---- it won't match "/tmp/assets/..." location
pathType: Prefix
backend:
service:
name: limesurvey-svc
port:
number: 80
Please try to create additional Ingress rule to support static file location (watch out, I'm using old syntax of Ingress resource, adjust it to your needs):
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
name: ingress-limesurvey-static
spec:
rules:
- http:
paths:
- backend:
serviceName: limesurvey-svc
servicePort: 80
path: /?(.*)
Best Solution (in my opinion)
You should define custom public URL within your application directly. Detailed information can be found in Advanced path settings, see publicurl option.
This way you wouldn't need to define internal reference for static files, however it should be done during installation.

How do I block paths in my (k8s) ingress?

I have a subset of paths that I expose with an ingress.
I'd like to block them for anyone coming through the ingress.
I'm trying this with a GCE Ingress
Adding a rule like:
- host: my.example.com
http:
paths:
- backend:
serviceName: dead-end-backend
servicePort: 80
path: /private
This backend is designated dead-end using Nginx default backend deployment/service but it's not working well.
I'm not asking how to use the default-backend (but it solve it).
I'm asking for a proper way to do this.
I'm not sure it's the best thing to do but what I did was use a "default-backend" service which returns error for anything.
Then I added each route I wanted to block to get to that default backend.
Like the saying - if it's silly, but it's working, then it's not silly.

Dynamically configuring routing to two set of pods

I have a web solution (angular application connecting to rest services) deployed in Kubernetes. I don't use any http sessions in my solution.
On upgrade of my rest services, I need to have both my pods with rest service version 1 and with rest service with version 2 available. Is there any way to setup a gateway/router where I can configure my endpoints dynamically?
I want /myendpoint?version=1 to route the traffic to the group of PODs with version 1, and /myendpoint?version=2 to route the traffic to the other group of PODs.
I must be able to dynamically add new endpoints without stopping the service.
Separate components by deployment cycle
I would recommend to separate frontend app and REST backend. (I don't know if you have this already)
By separation, you can roll out new versions independently, with a deployment cycle for each app.
Two Deployment or N-1 compatibility
In addition, if you want to have multiple versions of the same app available for a longer period, you can deploy them in two different Deployments
e.g. Two Deployment, each with its own Service and Ingress that setup both.
kind: Ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /v1/*
backend:
serviceName: service-v1
servicePort: 8080
- path: /v2/*
backend:
serviceName: service-v2
servicePort: 8080
Or you can have N-1 compatibility, so version 2 implements both /v1/ and /v2/ API.
Consider using CDN for static assets
It is usually recommended to deploy frontend on a CDN since it is static content. Sometimes your Javascript refers to other Javascript files using cache busting, then it is much easier to handle such setup if all your static content is available from a CDN.

Ingress for Kubernetes Wordpress

I've recently setup a Kubernetes cluster and I am brand new to all of this so it's quite a bit to take in. Currently I am trying to setup and Ingress for wordpress deployments. I am able to access through nodeport but I know nodeport is not recommended so I am trying to setup the ingress. I am not exactly sure how to do it and I can't find many guides. I followed this to setup the NGINX LB https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/complete-example and I used this to setup the WP Deployment https://docs.docker.com/ee/ucp/admin/configure/use-nfs-volumes/#inspect-the-deployment
I would like to be able to have multiple WP deployments and have an Ingress that resolves to the correct one, but I really can't find much information on it. Any help is greatly appreciated!
You can configure your ingress to forward traffic to a different service depending on path.
An example of such a confugration is this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: s1
servicePort: 80
- path: /bar
backend:
serviceName: s2
servicePort: 80
Read the kubernetes documentation on ingress for more info.
PS: In order for this to work you need an ingress controller like the one in the links in your question.
If you are on AWS, I highly recommend ALB ingress controller in conjunction with external-dns. These in combination with Wordpress Multisite give you some powerful options when it comes to providing dynamic ingress to new sites.
If you start running into any wonky issues (e.g. unable to login to the admin, redirect loops, disappearing media) after getting that all set up, I wrote a guide on some of the more common issues people run into when running Wordpress on Kubernetes, might be worth having a look!