Keycloak deployment on Kubernetes Cluster

Overview

Keycloak is an open-source identity and access management tool which make it easy to secure application and services with little to no code.

Keycloak provides various features and services such as,

  1. Single-Sign On

Keycloak provides the feature of single-sign on to the user, which means your application don’t have to deal authenticating user, storing credentials for the user or managing session for the users. Once logged-in to keycloak, user don’t have to login again to access different applications. This same applies to logout as well, keycloak provides single sign out feature.

2. User Federation

Keycloak has built-in support to connect to existing LDAP or Active Directory server.

3. Identity Provider

Keycloak can authenticate user with existing openID connect or SAML2.0 identity provider. We can enable login to various social-networking site such as Google, Facebook, Github through the admin console. No code or application changes required for it.

4. Authorization Services

Keycloak provides authorization service which allow us to manage permissions for all services from Keycloak admin console.

5. Standard Protocol

Keycloak is based on standard protocol and provides support for OpenID Connect, OAuth 2.0 and SAML.

Keycloak Deployment

There are many ways through which we can deploy Keycloak.

  1. Deployment with Keycloak distribution file.
  2. Deployment with Docker.
  3. Deployment with Kubernetes.

In this article, I am going to explain how we can deploy Keycloak with Kubernetes.

Keycloak Kubernetes Deployment

We can deploy Keycloak on Kubernetes cluster by creating deployment, service, ingress yaml’s for it.

  1. Deployment.yaml

We need to create deployment yaml file for deploying keycloak on kubernetes. Image that I am using for the deployment is “quay.io/keycloak/keycloak:8.0.2

---
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "keycloak-development"
namespace: "development"
spec:
selector:
matchLabels:
app: "keycloak-development"
replicas: 1
strategy:
type: "RollingUpdate"
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds: 5
template:
metadata:
labels:
app: "keycloak-development"
spec:
containers:
-
name: "keycloak-development"
image: "quay.io/keycloak/keycloak:8.0.2"
imagePullPolicy: "Always"
env:
-
name: "KEYCLOAK_USER"
value: "admin"

-
name: "KEYCLOAK_PASSWORD"
value: "admin"

-
name: "PROXY_ADDRESS_FORWARDING"
value: "true"
-
name: "KEYCLOAK_FRONTEND_URL"
value: "https://Mykeycloak-development/auth/"

-
name: "KEYCLOAK_ADMIN_URL"
value: "https://Mkeycloak- development/auth/realms/master/admin/"

ports:

- name: "http"
containerPort: 8080

- name: "https"
containerPort: 8443
readinessProbe:
httpGet:
path: "/auth/realms/master"
port: 8080

Note:- Here the KEYCLOAK_FRONTEND_URL value would be like https://<your_hostname>/auth.

KEYCLOAK_ADMIN_URL value would be like https://<your_hostname>/auth/realms/master/admin.

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>

2. Service.yaml

We need to create service file to expose Keycloak application. By default Keycloak work on port 8080.

---
apiVersion: "v1"
kind: "Service"
metadata:
name: "keycloak-development-service"
namespace: "development"
labels:
app: "keycloak-development"
spec:
ports:
-
port: 53582
targetPort: 8080
selector:
app: "keycloak-development"

Since Keycloak by default work on port 8080, I have defined the target port as 8080.

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>

3. Ingress.yaml

I am accessing Keycloak application with hostname and ingress path based routing as a result I have created ingress file.

---
apiVersion: "networking.k8s.io/v1"
kind: "Ingress"
metadata:
name: "keycloak-development-ingress"
namespace: "development"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
-
host: "xxxx"
http:
paths:
-
backend:
service:
name: "keycloak-development"
port:
number: 53582
path: "/keycloak-development/(.*)"
pathType: "ImplementationSpecific"

Once the yaml for ingressis 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://Mykeycloak-development/auth/

Issues after Deployment of Keycloak

You could face certain issues after deployment of Keycloak.

  1. Once you login to Keycloak and feed some data maybe create realm or client or user, it is possible that once the pod is deleted or restart all your data would also get lost with it.

Solution:- You need to create a separate database and add the information for database in your deployment.yaml file in form of env variable. In my case I have deployed the pod for postgressql, I have created a nodePort service for postgressql pod. Below are the env variables you need to add in deployment.yaml of Keycloak to resolve data lost issue. Here “DB_ADDR” is hostname of postgress,

-
name: "DB_VENDOR"
value: "POSTGRES"

-
name: "DB_ADDR"
value: "xxxx"

-
name: "DB_PORT"
value: "xxxx"

-
name: "DB_DATABASE"
value: "keycloak"

-
name: "DB_USER"
value: "postgres"

-
name: "DB_PASSWORD"
value: "xxxx"

Don’t forget to create database (in my case keycloak) inside postgres. After that re-run deployment file.

2. After running Keycloak, you could face issue that on reloading the page it gives 502 bad gateway error. To overcome this issue, add below annotation in ingress.yaml file.

nginx.ingress.kubernetes.io/proxy-buffer-size: "12k"

After adding env variable and annotation in deployment and ingress file respectively you need to recreate deployment and ingress.

In this way you could able to access Keycloak without any data lost or 502 bad gateway issue.

Devops Engineer