User authentication is crucial if you are building a web application and with my interest in Kubernetes and open source I gravitate towards Keycloak. Keycloak is an open source identity and access management platform, it can be used with an official container image. This is a short guide on how to deploy this image as a StatefulSet in your cluster.
Prerequisites
- Understanding of kubectl, Kubernetes' cli tool
- A Kubernetes cluster, you can spin one up here in DigitalOcean (Use this link for $200 to follow along)
- In this guide I use Postgres for the database, you can switch out for your preferred database as long as it is in this list on the documentation.
- An ingress controller for your cluster, I usually install the nginx ingress controller
- A valid domain name, if you want to buy one you can do that here on spaceship.com (my new favorite place to keep domains)
- It is best to have a valid SSL certificate for Keycloak, you can use cert-manager for that (if you're running a cluster locally, I wrote an article on setting up your own certificate authority for self-signed certs with cert-manager that can help with this)
The Manifest
I'll start by showing the full Kubernetes manifest file and then we'll step through each configuration for a bit more detail. Make sure to continue reading, because you will need to update a few things (like the database and networking settings). I've actually passed this around to different clusters for a few years now and it works really for my purposes. I've run this in DigitalOcean, K3s, and minikube.
You'll notice the StatefulSet in the configuration below is locked into the 26.4.0 image, which is the latest version at the time of this writing, you can choose your preferred image from the tag list here.
Copy the code below and paste it into a file called keycloak.yaml:
You will need to make sure these values are updated for your clusters environment: KC_DB_URL_DATABASE, KC_DB_URL_HOST, KC_DB_PASSWORD, KC_DB_USERNAME, KC_HOSTNAME, and the ingress host values should match your domain. I'll walk through each of those and explain in a bit more detail what each section of the manifest file does in your cluster.
The StatefulSet
The first section above is the StatefulSet, here is just that part of the deployment:
One might ask why we are using StatefulSet? There are a few underlying dependencies that make Keycloak's runtime stateful. The team had a public discussion a few years ago about the topic, if you'd like to understand the specifics you can read the discussion here.
To make this manifest work with your cluster you will need to change a few environment values: KC_DB_URL_DATABASE, KC_DB_URL_HOST, KC_HOSTNAME, KC_DB_PASSWORD, and KC_DB_USERNAME. You will see them in the env property of the container configuration.
For KC_DB_URL_DATABASE, replace with the name of your Postgres database.
For KC_DB_URL_HOST, replace with the host url of your Postgres database.
For KC_HOSTNAME, replace with the domain name where intend to host your Keycloak deployment.
For KC_DB_USERNAME and KC_DB_PASSWORD you will need to create a secret in the same namespace as this StatefulSet. You can do that using this command:
This creates a secret named keycloak-db-creds with the keys user and password, they get used during the runtime of the application. These are your Postgres database credentials.
A few other important environment values are KC_BOOTSTRAP_ADMIN_USERNAME and KC_BOOTSTRAP_ADMIN_PASSWORD. These are the credentials to the first temporary user created when the application bootstraps. I've set both of these to the value admin, feel free to change those but they will be necessary to access Keycloak.
The Services
The next section of the manifest are two important services in this configuration:
The first service in the list is named keycloak and is the one used in the ingress configuration, this is how Keycloak's UI and API is accessed externally.
The other service, keycloak-discovery, is related to the Keycloak's public discussion about StatefulSet mentioned above. It is important for pod-to-pod communcation and is referenced in the StatefulSet JAVA_OPTS_APPEND environment variable.
The Ingress
The last section of the full manifest above is the ingress definition:
You'll want to change the cluster-issuer annotation to match your issuer, I wrote an article on setting up your own certificate authority for self-signed certs with cert-manager that can help with this (but only if you're running locally). You also need to set the ingress host to mach the KC_HOSTNAME you are using in the StatefulSet manifest, this is the domain name you will be using for your Keycloak deployment.
Apply The Manifest
Once everything is changed, apply the full manifest originally copied into the keycloak.yaml using: kubectl apply -f keycloak.yaml. After several minutes you should be able to access the cluster using the KC_HOSTNAME, the first time you login you can use the KC_DB_USERNAME and KC_DB_PASSWORD, of course you should create a new admin user immediately.
Conclusion
And that's a simple deployment of Keycloak, this guide talked about creating a StatefulSet (and why we use it), created a secret to store the database credentials, the different services needed for Keycloak to operate, and put an ingress in place for easy external access. Enjoy your new Keycloak instance 🔑.