Keycloak
Keycloak provides user federation, strong authentication, authorisation and is a great addition to our on-prem SSO solution.
Instantiate a postgres cluster using the PGO
When backed by postgresql, it's easy to run multiple instances of Keycloak to get high-availability and scalability, so let's create a cluster with our operator. There's a new trick in our postgresql config, creating the namespaced schema for the user keycloak.
apiVersion: v1
kind: ConfigMap
metadata:
name: db-init-schema
namespace: keycloak
data:
init.sql: |
\echo "EXECUTING DB INIT SCRIPT"
\c keycloak
CREATE SCHEMA keycloak AUTHORIZATION keycloak;
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: keycloak
namespace: keycloak
spec:
postgresVersion: 16
databaseInitSQL:
key: init.sql
name: db-init-schema
instances:
- name: instance1
replicas: 2
dataVolumeClaimSpec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: rook-cephfs
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: keycloak
postgres-operator.crunchydata.com/instance-set: instance1
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.47-2
manual:
options:
- --type=full
repoName: repo1
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 2Gi
storageClassName: rook-cephfs
A pre-emptive fly in the ointment, TLS
If you don't plan on using LDAP federation, feel free to skip this section.
If you plan to use the LDAP server we created in the previous step you will either need to use plain-text LDAP protocol, or configure your LDAP server with a TLS certificate. If you use a self-signed TLS certificate, or an internal root you will need to configure a Java keystore with this certificate otherwise Keycloak will fail to connect.
Create Java keystore
First, generate a Java-compatible keystore, any machine that has Java available should suit:
keytool -import -alias my-ldap-cert -keystore keycloak-spi.truststore.jks -file /path/to/my-ldap-cert.crt
Turn keystore into Kubernetes secret
Now turn that into a k8s secret that we can consume in our deployment:
Install the Helm chart
helm upgrade \
--install keycloak bitnami/keycloak \
--create-namespace \
-n keycloak \
--set production=true \
--set proxy=edge \
--set replicaCount=2 \
--set pdb.create=true \
--set postgresql.enabled=false \
--set externalDatabase.database=keycloak \
--set externalDatabase.existingSecret="keycloak-pguser-keycloak" \
--set externalDatabase.existingSecretHostKey=host \
--set externalDatabase.existingSecretPortKey=port \
--set externalDatabase.existingSecretUserKey=user \
--set externalDatabase.existingSecretPasswordKey=password \
--set extraEnvVars\[0\].name=KC_DB_SCHEMA \
--set extraEnvVars\[0\].value=keycloak
helm upgrade \
--install keycloak bitnami/keycloak \
--create-namespace \
-n keycloak \
--set production=true \
--set proxy=edge \
--set replicaCount=2 \
--set pdb.create=true \
--set postgresql.enabled=false \
--set externalDatabase.database=keycloak \
--set externalDatabase.existingSecret="keycloak-pguser-keycloak" \
--set externalDatabase.existingSecretHostKey=host \
--set externalDatabase.existingSecretPortKey=port \
--set externalDatabase.existingSecretUserKey=user \
--set externalDatabase.existingSecretPasswordKey=password \
--set extraEnvVars\[0\].name=KC_DB_SCHEMA \
--set extraEnvVars\[0\].value=keycloak \
--set spi.existingSecret=allcerts \
--set spi.truststorePassword=changeit \
--set spi.truststoreFilename=keycloak-spi.truststore.jks \
--set spi.truststoreFilename=keycloak-spi.truststore.jks
Find the default user
By default, the first user is named user
and the password is available as
a secret:
Copy that to your clipboard and we'll use it to login in the next step.
Port forward and configure
Find the service name we need to connect to:
You should see a list similar to the following:
keycloak ClusterIP 10.104.61.134 <none> 80/TCP 8m50s
keycloak-headless ClusterIP None <none> 80/TCP 8m50s
We want keycloak
. So:
Now you should be able to connect to http://localhost:8080 and use the credentials from the previous step to login and configure Keycloak.
Next steps
For production use you would now need to provision some DNS entries, and an ingress configuration to grant access outside of the cluster.