Shubham Dhote
4 min readJun 12, 2023

Keycloak Latest version deployment on Kubernetes

This is the updated version of keycloak deployment on kubernetes, you can check my previous blog to know more abut keycloak and if you are looking for the older version.

Link:- https://medium.com/@shubhamdhote9717/keycloak-deployment-on-kubernetes-cluster-834bee73a567

In this blog I will explain about the latest keycloak version deployment.

Below are the steps that we need to follow while deploying keycloak on kubernetes.

  1. Service.yaml

We need to create service file to expose Keycloak application. By default Keycloak work on port 8080, with the previous version we were able to directly use ClusterIP and can have replicas of pods. But with the latest keycloak version we would need to create headless service, that would help us to have replicas i.e to have HA keycloak on kubernetes.

apiVersion: v1
kind: Service
metadata:
name: keycloak
labels:
app: keycloak
spec:
ports:
- name: http
port: 8080
targetPort: 8080
- name: https
port: 8443
targetPort: 8443
- name: jgroup
port: 7600
targetPort: 7600

selector:
app: keycloak
type: ClusterIP
clusterIP: None

Once the yaml for service is created, we need to apply the deployment using below command.

kubectl apply -f service.yaml -n <namespace>

To check if the service is created or not, run below command.

kubectl get svc -n <namespace>

2. Deployment.yaml

Next we would create the deployment.yaml, there are some of the env variables/parameters I would explain below.

apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
labels:
app: keycloak
spec:
replicas: 2
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:21.1.1
args: ["start", "--cache-stack=kubernetes", "--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true"]
env:
- name: KEYCLOAK_ADMIN
value: "admin"
- name: KEYCLOAK_ADMIN_PASSWORD
value: "admin"
- name: KC_PROXY
value: "edge"
- name: jgroups.dns.query
value: "keycloak"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_METRICS_ENABLED
value: "true"
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_HTTP_RELATIVE_PATH
value: "/auth"
- name: KC_HOSTNAME_URL
value: "https://domain-name.com/keycloak/auth/"
- name: KC_HOSTNAME_ADMIN_URL
value: "https://domain-name.com/keycloak/auth/"
- name: KC_DB
value: "mysql"
- name: KC_DB_URL
value: "jdbc:mysql://mysql/keycloak"
- name: KC_DB_URL_HOST
value: "mysql"
- name: KC_DB_URL_PORT
value: "3306"
- name: KC_DB_URL_DATABASE
value: "keycloak"
- name: KC_DB_USERNAME
value: "root"
- name: KC_DB_PASSWORD
value: "password"

ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
- name: jgroups
containerPort: 7600
1. jgroups.dns.query: keycloak
(This is the headless service name that we created in service.yaml.

2. KC_HTTP_RELATIVE_PATH: /auth
(on this path we will open our keycloak home page)

3. KC_HOSTNAME_URL: https://domain-name.com/keycloak/auth/
(I am using ingress path based routing which I will explain below as a result of which I have given /keycloak after my domain name)

4. KC_DB: mysql
(You will need to deploy any database so that data would be secure even if it is deleted)

5. KC_DB_URL: jdbc:mysql://mysql/keycloak
(The value is inthe format jdbc:mysql://<your-mysql-service-name>/<database>,
Note:- I have already created keycloak database in mysql)

All other env variabes are self-explainatory

If you are having issue with logout, i.e after clicking on logout in your application not in the keycloak admin, you can add the below arg in your deployment yaml
("--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true")

6. IF you are encountaring the below error (mostly with latest versions)
ERROR: Unexpected error when starting the server in (production) mode ERROR: Failed to start quarkus ERROR: hostname is not configured; either configure hostname, or set hostname-strict to false

update the args in the deployment.yaml file as below

args: ["start", "--cache-stack=kubernetes", "hostname="https://domain-name.com/keycloak/auth/", "--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true"]

Extra Env variable

If you want to run keycloak on IPV6 stack, i.e your cluster is having IPV6 address add the below env variable

- name: JAVA_OPTS
value: -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true

If you are having multiple replicas i.e more than 1 pods for keycloak and if you face issue while accessing the application, add below env variables. update the value according to number of pods, i.e if you have two pods value will be 2, if you have four pods value will be 4.

- name: CACHE_OWNERS_COUNT
value: "2"
- name: CACHE_OWNERS_AUTH_SESSIONS_COUNT
value: "2"

Once the yaml for deployment is created, we need to apply the deployment using below command.

kubectl apply -f deployment.yaml -n <namespace>

Above command will work only if you have kubectl tool installed. Also if you have created a separate namespace for deploying keycloak you can defined like above. Otherwise if you want to use default namespace simply use below command.

kubectl apply -f deployment.yaml

To check if the deployment is created or not, run below command.

kubectl get deployments -n <namespace>

3. Ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 2500m
nginx.ingress.kubernetes.io/proxy-buffer-size: 12k
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
ingressClassName: nginx
rules:
- host: domain.com
http:
paths:
- backend:
service:
name: keycloak
port:
number: 8080
path: /keycloak/(.*)
pathType: Prefix

Once the yaml for ingress is created, we need to apply the deployment using below command.

kubectl apply -f ingress.yaml <namespace>

To check if the ingress is created or not, run below command.

kubectl get ingress -n <namespace>

Once deployment, service, ingress is created you can check the status for the pod if they are running or not. Run the below command to check status for the pod.

kubectl get pods -n <namespace>

If the pod is up and running, you can access keycloak with frontend url through any web browser.

https://domain.com/keycloak/auth/

Hope this latest blog on keycloak(latest version) would be helpful for you.