Deploying Keycloak on Kubernetes with Minikube

Manish Sharma
8 min readMar 26, 2024

Kubernetes has become the de facto standard for container orchestration, offering powerful tools for managing containerized applications at scale. Keycloak, an open-source identity and access management solution, plays a crucial role in securing these applications. In this guide, we will explore how to deploy Keycloak on Kubernetes using Minikube, a tool that enables local Kubernetes cluster creation for development and testing purposes.

What is Key Cloak

Keycloak is an open-source Identity and Access Management (IAM) solution developed by Red Hat. It provides features for Single Sign-On (SSO), user federation, identity brokering, and social login, among others. Keycloak aims to simplify user authentication and authorization for web and mobile applications, microservices, and APIs.

Key Cloak Features

Here are some key features and components of Keycloak:

  • Single Sign-On (SSO): Keycloak allows users to authenticate once and access multiple applications without needing to log in again. This improves user experience and reduces the hassle of remembering multiple credentials.
  • Identity Federation: Keycloak supports integration with external identity providers such as LDAP, Active Directory, SAML, OAuth, and OpenID Connect. This enables organizations to leverage existing identity systems and centralize user management.
  • User Management: Keycloak provides a user management interface where administrators can create, update, and delete user accounts, as well as manage user roles and permissions. It also supports self-registration and password reset workflows.
  • Role-Based Access Control (RBAC): Administrators can define roles and permissions within Keycloak and assign them to users or groups. This granular access control ensures that users only have access to the resources they are authorized to use.
  • OAuth 2.0 and OpenID Connect: Keycloak is compliant with OAuth 2.0 and OpenID Connect standards, making it compatible with a wide range of applications and frameworks. It can act as both an OAuth 2.0 Authorization Server and an OpenID Connect Identity Provider.
  • Security: Keycloak provides robust security features such as encryption, token-based authentication, brute force protection, and session management. It also supports multi-factor authentication (MFA) for enhanced security.
  • Integration and Extensibility: Keycloak can be easily integrated with various platforms and technologies through its REST API, Java libraries, and adapters for popular frameworks like Spring Security. It also supports custom authentication flows and user federation providers.
  • Clustering and High Availability: Keycloak supports clustering and horizontal scaling to handle large numbers of users and ensure high availability. It can be deployed in standalone mode or as a cluster behind a load balancer.
  • Customizable Themes: Keycloak allows customization of the login, registration, and account management pages using themes and templates. This enables organizations to tailor the user interface to match their branding and design requirements.
  • Auditing and Logging: Keycloak provides comprehensive auditing and logging capabilities to track user authentication events, administrative actions, and system activities. This helps in compliance with security and regulatory requirements.

Prerequisites

Before we begin, ensure you have the following prerequisites installed:

  • Install VirtualBox on the machine
  • Install Docker or Docker Desktop
  • Install kubectl CLI on machine
  • Install Minikube
  • Helm (optional, but recommended for managing Kubernetes applications)

Setting Up the Environment

# To install the latest minikube stable release on x86-64 macOS using Homebrew:
brew install minikube
  • Start Minikube using the command: minikube start --cpus='8' --memory='8000' --driver='virtualbox'
  • Verify that Minikube is running by executing: minikube status
  • Set up the Kubernetes context to point to Minikube: kubectl config use-context minikube

Deploying Keycloak on Kubernetes

PostgreSQL Database Setup

  • Keycloak requires a database backend for storing configuration data. In this guide, we will use PostgreSQL, but you can choose from other supported databases.
  • Enable Add-ons (Optional): For PostgreSQL, you might need persistent storage, so enabling the storage-provisioner addon would be helpful.
minikube addons list | grep 'storage-provisioner'

as per the result storage-provisioner is already enabled on minikube if not then execute this command

minikube addons enable storage-provisioner
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install my-postgresql bitnami/postgresql --version 15.1.4

output

NAME: my-postgresql
LAST DEPLOYED: Tue Mar 26 17:44:43 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: postgresql
CHART VERSION: 15.1.4
APP VERSION: 16.2.0

** Please be patient while the chart is being deployed **

PostgreSQL can be accessed via port 5432 on the following DNS names from within your cluster:

my-postgresql.default.svc.cluster.local - Read/Write connection

To get the password for "postgres" run:

export POSTGRES_PASSWORD=$(kubectl get secret --namespace default my-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)

To connect to your database run the following command:

kubectl run my-postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:16.2.0-debian-12-r10 --env="PGPASSWORD=$POSTGRES_PASSWORD" \
--command -- psql --host my-postgresql -U postgres -d postgres -p 5432

> NOTE: If you access the container using bash, make sure that you execute "/opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash" in order to avoid the error "psql: local user with ID 1001} does not exist"

To connect to your database from outside the cluster execute the following commands:

kubectl port-forward --namespace default svc/my-postgresql 5432:5432 &
PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U postgres -d postgres -p 5432

WARNING: The configured password will be ignored on new installation in case when previous PostgreSQL release was deleted through the helm command. In that case, old PVC will have an old password, and setting it through helm won't take effect. Deleting persistent volumes (PVs) will solve the issue.

WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
- primary.resources
- readReplicas.resources
+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

That’s a basic setup. Depending on your requirements, you might need to adjust configurations in Helm Chart values.yaml file.

  • Check PGSQl Deployment
kubectl get all -n default

output

  • Retrieve PgSQL Password
export POSTGRES_PASSWORD=$(kubectl get secret --namespace default my-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)
echo $POSTGRES_PASSWORD
  • Connect to PgSQL to validate connection
$ export POSTGRES_PASSWORD=$(kubectl get secret --namespace default my-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)
$ kubectl run my-postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:16.2.0-debian-12-r10 --env="PGPASSWORD=$POSTGRES_PASSWORD" \
--command -- psql --host my-postgresql -U postgres -d postgres -p 5432

KeyCloak Setup

  • Enable Ingress Addon: To check if you have the Ingress addon enabled, enter the following command:
minikube addons list | grep 'ingress'

If the Ingress addon is not enabled, enter the following command to enable it:

minikube addons enable ingress
  • Deploy KeyClock Deployment & Services
$ kubectl create -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes/keycloak.yaml
$ kubectl get all -n default

output

I have postgres installed in same namespace so excluding its all deployment to display keycloak deployments.

  • (Option 1) Create Ingress: Create an Ingress for Keycloak by entering the following command

$ wget -q -O - https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes/keycloak-ingress.yaml | \
sed "s/KEYCLOAK_HOST/keycloak.$(minikube ip).nip.io/" | \
kubectl create -f -
$ kubectl get ingress

Execute below commands to get KeyCloak URls

KEYCLOAK_URL=https://keycloak.$(minikube ip).nip.io &&
echo "" &&
echo "Keycloak: $KEYCLOAK_URL" &&
echo "Keycloak Admin Console: $KEYCLOAK_URL/admin" &&
echo "Keycloak Account Console: $KEYCLOAK_URL/realms/myrealm/account" &&
echo ""

output

  • Option 2 (Without Ingress):

Enable ingress-dns addon to enable tunnel on minikube

minikube addons enable ingress-dns

After the addon is enabled, you need to run below command and your ingress resources would be available at 127.0.0.1

minikube tunnel

output

🏃  Starting tunnel for service keycloak.
🏃 Starting tunnel for service kubernetes.

|-----------|------------------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------------------|-------------|------------------------|
| default | keycloak | | http://127.0.0.1:49715 |
| default | kubernetes | | http://127.0.0.1:49717 |
| default | my-postgresql | | http://127.0.0.1:49719 |
| default | my-postgresql-hl | | http://127.0.0.1:49721 |
|-----------|------------------|-------------|------------------------|
🎉 Opening service default/keycloak in default browser...
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
  • Valid KeyCloak Database

Get the keycloak pod deployment name and execute below command to print env variables used in key cloak pod deployment.

$ kubectl exec -it pod/keycloak-77c488897b-677st -n default -- env

output must be similar,

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=keycloak-77c488897b-677st
TERM=xterm
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
KC_PROXY=edge
MY_POSTGRESQL_SERVICE_PORT_TCP_POSTGRESQL=5432
MY_POSTGRESQL_PORT=tcp://10.107.28.83:5432
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
MY_POSTGRESQL_SERVICE_HOST=10.107.28.83
MY_POSTGRESQL_SERVICE_PORT=5432
MY_POSTGRESQL_PORT_5432_TCP_PROTO=tcp
KEYCLOAK_PORT_8080_TCP_PROTO=tcp
MY_POSTGRESQL_PORT_5432_TCP=tcp://10.107.28.83:5432
KEYCLOAK_SERVICE_HOST=10.102.200.124
KEYCLOAK_SERVICE_PORT=8080
KEYCLOAK_SERVICE_PORT_HTTP=8080
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
MY_POSTGRESQL_PORT_5432_TCP_PORT=5432
KEYCLOAK_PORT_8080_TCP=tcp://10.102.200.124:8080
KUBERNETES_SERVICE_PORT=443
MY_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.28.83
KEYCLOAK_PORT=tcp://10.102.200.124:8080
KEYCLOAK_PORT_8080_TCP_PORT=8080
KEYCLOAK_PORT_8080_TCP_ADDR=10.102.200.124
LANG=en_US.UTF-8
KC_RUN_IN_CONTAINER=true
HOME=/opt/keycloak

In above output line MY_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.28.83 indicates that keycloak deployment is using the PgSQL we deployed in above steps.

  • Now, login to KeyCloak Admin console: Enter this url http://127.0.0.1:49715/admin in browser and enter default username and password which is admin and admin.

After the login it takes you to the main page

Thats all. Installation of KeyCloak and PgSQL is done.

I’m grateful for each and every reader who has taken the time to read this article. Thank you for your support and encouragement.

Your feedback is invaluable! Let me know what you think about this article in the comments and if you enjoy my content, consider clicking ‘Follow’ to receive updates.

--

--

Manish Sharma

I am technology geek & keep pushing myself to learn new skills. I am AWS Solution Architect — Associate, Professional & Terraform Associate Developer certified.