How to access keycloak on subpath with nginx ingress? - keycloak

I have nginx ingress controller in my EKS cluster along with keycloak i tried to expose it on a subpath (myhost.com/keycloak) but it doesn't work so after few researchs i found that i should add this env variable to keycloak deployment : PROXY_ADDRESS_FORWARDING=true and now i can only access it through myhost.com/auth. So is there any way to customize that path
to something like myhost.com/keycloak
Here is my Ingress resource :
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: "keycloak-ingress"
annotations:
kubernetes.io/ingress.class: nginx
labels:
app: keycloak-ingress
spec:
rules:
- host: myhost.com
http:
paths:
- path: /auth
backend:
serviceName: keycloak
servicePort: 8080

Manage-subsystem configuration documentations says:
Low-level configuration of Keycloak is done by editing the standalone.xml, standalone-ha.xml, or domain.xml file in your distribution. The location of this file depends on your operating mode.
While there are endless settings you can configure here, this section will focus on configuration of the keycloak-server subsystem. No matter which configuration file you are using, configuration of the keycloak-server subsystem is the same.
The keycloak-server subsystem is typically declared toward the end of the file like this:
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>auth</web-context>
...
</subsystem>
Note that anything changed in this subsystem will not take effect until the server is rebooted.
That results in a fact that the default entrypoint is: http://localhost:8080/auth .
and now i can only access it through myhost.com/auth
You can adjust your configuration in standalone.xmland substitute auth with keycloak . Additionally it'll be needed to adjust path in the ingress.yaml .
Hope that helps.

Related

SSL Certificate added but shows "Kubernetes Ingress controller fake certificate"

I am having the following issue.
I am new to GCP/Cloud, I have created a cluster in GKE and deployed our application there, installed nginx as a POD in the cluster, our company has a authorized SSL certificate which i have uploaded in Certificates in GCP.
In the DNS Service, i have created an A record which matched the IP of Ingress.
When i call the URL in the browser, it still shows that the website is still unsecure with message "Kubernetes Ingress controller fake certificate".
I used the following guide https://cloud.google.com/load-balancing/docs/ssl-certificates/self-managed-certs#console_1
however i am not able to execute step 3 "Associate an SSL certificate with a target proxy", because it asks "URL Maps" and i am not able to find it in the GCP Console.
Has anybody gone through the same issue like me or if anybody helps me out, it would be great.
Thanks and regards,
I was able to fix this problem by adding an extra argument to the ingress-nginx-controller deployment.
For context: my TLS secret was at the default namespace and was named letsencrypt-secret-prod, so I wanted to add this as the default SSL certificate for the Nginx controller.
My first solution was to edit the deployment.yaml of the Nginx controller and add at the end of the containers[0].args list the following line:
- '--default-ssl-certificate=default/letsencrypt-secret-prod'
Which made that section of the yaml look like this:
containers:
- name: controller
image: >-
k8s.gcr.io/ingress-nginx/controller:v1.2.0-beta.0#sha256:92115f5062568ebbcd450cd2cf9bffdef8df9fc61e7d5868ba8a7c9d773e0961
args:
- /nginx-ingress-controller
- '--publish-service=$(POD_NAMESPACE)/ingress-nginx-controller'
- '--election-id=ingress-controller-leader'
- '--controller-class=k8s.io/ingress-nginx'
- '--ingress-class=nginx'
- '--configmap=$(POD_NAMESPACE)/ingress-nginx-controller'
- '--validating-webhook=:8443'
- '--validating-webhook-certificate=/usr/local/certificates/cert'
- '--validating-webhook-key=/usr/local/certificates/key'
- '--default-ssl-certificate=default/letsencrypt-secret-prod'
But I was using the helm chart: ingress-nginx/ingress-nginx, so I wanted this config to be in the values.yaml file of that chart so that I could upgrade it later if necessary.
So reading the values file I replaced the attribute: controller.extraArgs, which looked like this:
extraArgs: {}
For this:
extraArgs:
default-ssl-certificate: default/letsencrypt-secret-prod
This restarted the deployment with the argument in the correct place.
Now I can use ingresses without specifying the tls.secretName for each of them, which is awesome.
Here's an example ingress that is working for me with HTTPS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: some-ingress-name
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- http:
paths:
- path: /some-prefix
pathType: Prefix
backend:
service:
name: some-service-name
port:
number: 80
You can save your SSL/TLS certificate into the K8s secret and attach it to the ingress.
you need to config the TLS block in ingress, dont forget to add ingress.class details in ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
rules:
- host: mydomain.com
http:
paths:
-
backend:
serviceName: my-service
servicePort: 80
path: /
tls:
- hosts:
- mydomain.com
secretName: my-tls-secret
You can read more at : https://medium.com/avmconsulting-blog/how-to-secure-applications-on-kubernetes-ssl-tls-certificates-8f7f5751d788
You might be seeing something like this in browser :
that's from the ingress controller and wrong certificate attached to ingress or ingress controller default fake cert.
in my fault, I upgraded new tsl on cattle-system name space, but not in my name-space, therefore some how, ingress recognize with K8s fake cert.
Solution: upgrade all old cert to new cert (only ingress user cert, WARNING - system cert maybe damaged your system - cannot explain)
Also don't forget to check that Subject Alternative Name actually contains the same value the CN contains. If it does not, the certificate is not valid because the industry moves away from CN. Just learned this now

Zeppelin Notebooks and Interpreters Missing Behind Kubernetes Ingress

I am running into an issue where the interpreters are missing after enabling the Kubernetes ingress to reach my Zeppelin container.
I'm running Zeppelin 0.8.2 on Kubernetes, and everything works correctly when it is not behind an ingress.
I am able to choose a default interpreter in the notebook creation popup, and run paragraphs without issue.
When an ingress is setup in Kubernetes, previously created notebooks and interpreter selection during new notebook creation are missing.
I am still able to reach the interpreter settings page, and it appears they are all still there.
Required change made in zeppelin-site.xml to run without the ingress.
<property>
<name>zeppelin.server.addr</name>
<value>0.0.0.0</value>
<description>Server binding address</description>
</property>
By default, was 127.0.0.0
Changes made in shiro.ini based on this forum discussion:
https://community.cloudera.com/t5/Support-Questions/How-do-I-recover-missing-Zeppelin-Interpreter-tab-and-its/m-p/160680
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000
Ingress used below with variable names changed
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
name: zeppelin-name
namespace: namespace_here
spec:
rules:
- host: zeppelin.zeppelin-services.my-host.org
http:
paths:
- backend:
serviceName: zeppelin-name
servicePort: 8080
path: /
tls:
- hosts:
- zeppelin.zeppelin-services.my-host.org
secretName: secret-name
status:
loadBalancer: {}
What am I missing for Zeppelin to work correctly behind the Kubernetes Ingress, to allow me to see previously created notebooks, and interpreters present in the dropdown menu when creating new notebooks?
Coworker found the answer.
It turns out the information was not reaching the zeppelin page.
On inspection, there was a 405 error:
'wss://zeppelin.zeppelin-services.my-host.org/ws' failed: Error during WebSocket handshake: Unexpected response code: 405
He checked the logs on the nginx-ingress pod and found similar failure messages.
Issue was in the ingress yaml used and required an addition to the annotation
metadata:
annotations:
nginx.org/websocket-services: zeppelin-name

How to configure HAproxy Ingress controller in Kubernetes

So we have a SQL server deployment with replica=2 in K8s which I need to make load balanced. I'm using Haproxy ingress controller to achieve this goal but I'm stuck in configuring Haproxy. I'm trying to configure the Haproxy based on this link and I don't know how to present my two pods to the ingress!
There is this part of the link says:
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: web-ingress
namespace: default
spec:
rules:
- host: foo.bar
http:
paths:
- path: /
backend:
serviceName: app
servicePort: 80
The issue is that in "spec.rules.host" section, I don't have any domain rather I have two IPs belong to my SQL pods! How am I supposed to represent my pods to the ingress? Am I doing right?
I've looked it up alot, but no luck!
P.S: What is the best practice for Load Balancing SQL server?
A DNS system translates hostname to IPs.With a domain registered with DNS system you can add a mapping of hostname to IP in the /etc/hosts file of the system from where you want to access the hostname.

Trying to rewrite url for Grafana with Ingress

In my kubernetes cluster I would like to do monitoring so I installed grafana.
I would like to access the grafana dashboard as http://example.com/monitoring, so I tried to include this in my ingress configuration
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: example.com
http:
paths:
- path: /monitoring/(.*)
backend:
serviceName: grafana
servicePort: 80
The idea is to add other paths there as well, for example / for the website.
I noticed that Grafana redirects http://example.com/monitoring to http://example.com/login. Of course this should have been http://example.com/monitoring/login. What would be the preferred way to fix this. Can it be done with ingress or should I somehow tell Grafana that it is behind a /monitoring path (if possible)?
I've installed grafana using this using Helm.
UPDATE: I've modified as suggested below the grafana chart's file values.yaml as follows
grafana.ini:
server:
domain: example.com
root_url: http://example.com/monitoring/
Now I get:
And the heml command I use to install grafana:
$> helm install stable/grafana -f values.yaml --set persistence.enabled=true --set persistence.accessModes={ReadWriteOnce} --set persistence.size=8Gi -n grafana
This is a common problem with services that are behind an HTTP reverse-proxy. Luckily, Grafana offers a way to let it know the context path it is running behind.
In grafana.ini (which is most possibly supplied via a ConfigMap to its Kubernetes deployment), you need to specify the variables like the following:
[server]
domain = example.com
root_url = http://example.com/monitoring/
See the full documentation here: https://grafana.com/docs/installation/behind_proxy/

Can later ingress subpaths override earlier ingress parent paths?

I have a Kubernetes ingress that I want to be the default for all paths on a set of hosts, provided there is not a more specific match:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: default-ing
spec:
rules:
- host: host1.sub.example.com
http:
paths:
- backend:
serviceName: my-default-service
servicePort: http
# Note: here we specify the root path intended as a default
path: /
- backend:
serviceName: my-default-service
servicePort: http
path: /route/path/to/default
A second ingress defines a custom service for a specific path:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: special-ing
spec:
rules:
- host: host1.sub.example.com
http:
paths:
- backend:
serviceName: special-service
servicePort: http
path: /special
I would expect that the order of adding/deleting the ingresses would not matter, or at least I could have some way of indicating that the path: / in default-ing is always to be ordered last.
When I try the above, the routing is fine as long as I add special-ing before default-ing (or alternatively, add default-ing, then the special-ing, then delete default-ing and re-add it again). When I add them as default-ing, then special-ing, requests to /special are routed to my-default-service instead of special-service.
I want the order of adding/deleting to be independent of the routing that is generated by nginx-ingress-controller, so that my kubectl manipulations are more robust, and if one of the ingresses is recreated nothing will break.
I'm using nginx-ingress-controller:0.19.0
Thanks for any help you can offer!
The short answer is no. I believe your configs should be disallowed by the nginx ingress controller or documented somewhere. Basically what's happening when you have 2 hosts rules with the same value: host1.sub.example.com one is overwriting the other in the server {} block in the nginx.conf that your nginx ingress controller is managing.
So if your add default-ing before special-ing then special-ing will be the actual config. When you add special-ing before default-ing then default-ing will be your only config, special-ing is not supposed to work at all.
Add special-ing, and the configs look something like this:
server {
server_name host1.sub.example.com;
...
location /special {
...
}
location / { # default backend
...
}
...
}
Now add default-ing, and the configs will change to like this:
server {
server_name host1.sub.example.com;
...
location /route/path/to/default {
...
}
location / { # default backend
...
}
...
}
If you add them the other way around the config will look like 1. in the end.
You can find more by shelling into your nginx ingress controller pod and looking at the nginx.conf file.
$ kubectl -n <namespace> exec -it nginx-ingress-controller-pod sh
# cat /etc/nginx/nginx.conf
Update 03/31/2022:
It seems like on newer nginx ingress controller versions. All the rules with the same host get merged into a server block in the nginx.conf