kubectl --namespace keycloak create configmap keycloak-aurora-rootcert \
--from-file aurora.pem=/path/to/bundle.pem
This guide describes advanced Keycloak configurations for Kubernetes which are load tested and will recover availability-zone failures.
These instructions are intended for use with the setup described in the Concepts for single-cluster deployments guide. Use it together with the other building blocks outlined in the Building blocks single-cluster deployments guide.
Kubernetes cluster deployed across multiple availability-zones with a worker-pool configured for each.
Understanding of a Basic Keycloak deployment of Keycloak with the Keycloak Operator.
A database deployed according to one of the following guides:
Depending on the database you deployed use the relevant procedure for deploying Keycloak.
Determine the sizing of the deployment using the Concepts for sizing CPU and memory resources guide.
Install the Keycloak Operator as described in the Keycloak Operator Installation guide.
Build a custom Keycloak image which is prepared for usage with the Amazon Aurora PostgreSQL database.
Secure the Amazon Aurora PostgreSQL database connection by downloading the certificate bundles.
Create a ConfigMap with the certificate bundle using:
kubectl --namespace keycloak create configmap keycloak-aurora-rootcert \
--from-file aurora.pem=/path/to/bundle.pem
Create a generic secret keycloak-db-secret containing username and password values defined when creating the Aurora database.
kubectl --namespace keycloak create secret generic keycloak-db-secret \
--from-literal="username=keycloak" --from-literal="password=secret99" (1)
| 1 | Note: These are sample values for demonstration purposes only. Please chose a unique password to secure your database. |
Deploy the Keycloak CR with the following values with the resource requests and limits calculated in the first step:
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
labels:
app: keycloak
name: keycloak
namespace: keycloak
spec:
hostname:
hostname: <KEYCLOAK_URL_HERE>
resources:
requests:
cpu: "2"
memory: "1250M"
limits:
cpu: "6"
memory: "2250M"
db:
vendor: postgres
url: jdbc:aws-wrapper:postgresql://<AWS_AURORA_URL_HERE>:5432/keycloak (1)
poolMinSize: 30 (2)
poolInitialSize: 30
poolMaxSize: 30
usernameSecret: (3)
name: keycloak-db-secret
key: username
passwordSecret: (3)
name: keycloak-db-secret
key: password
image: <KEYCLOAK_IMAGE_HERE> (4)
startOptimized: false (4)
additionalOptions:
- name: log-console-output
value: json
- name: metrics-enabled (5)
value: 'true'
- name: event-metrics-user-enabled
value: 'true'
- name: db-driver
value: software.amazon.jdbc.Driver
- name: db-tls-mode (6)
value: verify-server
http:
tlsSecret: keycloak-tls-secret
instances: 3
truststores:
aurora:
configMap:
name: keycloak-aurora-rootcert (7)
| 1 | Set the Amazon Aurora PostgreSQL URL. |
| 2 | The database connection pool initial, max and min size should be identical to allow statement caching for the database. Adjust this number to meet the needs of your system. As most requests will not touch the database due to the Keycloak embedded cache, this change can serve several hundreds of requests per second. See the Concepts for database connection pools guide for details. |
| 3 | Utilise the Secret keycloak-db-secret created in the previous step for connecting to the database. |
| 4 | Specify the URL to your custom Keycloak image. If your image is optimized, set the startOptimized flag to true. |
| 5 | Enable the metrics endpoint in order to effectively monitor the system under load. |
| 6 | Secure the database connection. |
| 7 | Specify the ConfigMap name that contains the Amazon Aurora PostgreSQL database certificate bundle.
The Operator will automatically mount the file in directory /opt/keycloak/conf/truststores/configmap-<config map name>/<file-name> |
Determine the sizing of the deployment using the Concepts for sizing CPU and memory resources guide.
Install the Keycloak Operator as described in the Keycloak Operator Installation guide.
Create a ConfigMap containing the generated CA certificate of the CloudNativePG cluster so that Keycloak can secure the connection to the database.
kubectl --namespace keycloak create configmap cnpg-keycloak-ca \
--from-literal=cert.pem="$(kubectl --namespace cnpg-keycloak get secrets cnpg-keycloak-ca -o jsonpath='{.data.ca\.crt}' | base64 -d)"
Create a generic secret keycloak-db-secret containing a username and password for accessing the database.
We use the values from the cnpg-keycloak-app Secret which is automatically generated during the installation of the CloudNativePG database cluster.
kubectl get secret cnpg-keycloak-app --namespace cnpg-keycloak -o go-template='
apiVersion: v1
kind: Secret
metadata:
name: keycloak-db-secret
namespace: keycloak
type: Opaque
data:
username: {{ .data.username }}
password: {{ .data.password }}
' | kubectl apply -f -
Deploy the Keycloak CR with the following values with the resource requests and limits calculated in the first step:
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
labels:
app: keycloak
name: keycloak
namespace: keycloak
spec:
hostname:
hostname: <KEYCLOAK_URL_HERE>
resources:
requests:
cpu: "2"
memory: "1250M"
limits:
cpu: "6"
memory: "2250M"
db:
vendor: postgres
host: cnpg-keycloak-rw.cnpg-keycloak.svc.cluster.local (1)
poolMinSize: 30 (2)
poolInitialSize: 30
poolMaxSize: 30
usernameSecret: (3)
name: keycloak-db-secret
key: username
passwordSecret: (3)
name: keycloak-db-secret
key: password
additionalOptions:
- name: log-console-output
value: json
- name: metrics-enabled (4)
value: 'true'
- name: event-metrics-user-enabled
value: 'true'
- name: db-tls-mode (5)
value: verify-server
http:
tlsSecret: keycloak-tls-secret
instances: 3
truststores:
cnpg:
configMap:
name: cnpg-keycloak-ca (6)
| 1 | Set CloudNativePG read-write service URL. |
| 2 | The database connection pool initial, max and min size should be identical to allow statement caching for the database. Adjust this number to meet the needs of your system. As most requests will not touch the database due to the Keycloak embedded cache, this change can serve several hundreds of requests per second. See the Concepts for database connection pools guide for details. |
| 3 | Utilise the Secret keycloak-db-secret created in the previous step for connecting to the database. |
| 4 | Enable the metrics endpoint in order to effectively monitor the system under load. |
| 5 | Secure the database connection. |
| 6 | Specify the ConfigMap name that contains the CloudNativePG CA certificate.
The Operator will automatically mount the file in directory /opt/keycloak/conf/truststores/configmap-<config map name>/<file-name> |
Confirm that the Keycloak deployment is ready.
kubectl wait --for=condition=Ready keycloaks.k8s.keycloak.org/keycloak
kubectl wait --for=condition=RollingUpdate=False keycloaks.k8s.keycloak.org/keycloak
To enable load shedding, limit the number of queued requests.
spec:
additionalOptions:
- name: http-max-queued-requests
value: "1000"
All exceeding requests are served with an HTTP 503.
You might consider limiting the value for http-pool-max-threads further because multiple concurrent threads will lead to throttling by Kubernetes once the requested CPU limit is reached.
See the Concepts for configuring thread pools guide about load shedding for details.
When running on OpenShift and the default passthrough Ingress setup as provided by the Keycloak Operator, the load balancing done by HAProxy is done by using sticky sessions based on the IP address of the source. When running load tests, or when having a reverse proxy in front of HAProxy, you might want to disable this setup to avoid receiving all requests on a single Keycloak Pod.
Add the following supplementary configuration under the spec in the Keycloak Custom Resource to disable sticky sessions.
spec:
ingress:
enabled: true
annotations:
# When running load tests, disable sticky sessions on the OpenShift HAProxy router
# to avoid receiving all requests on a single Keycloak Pod.
haproxy.router.openshift.io/balance: roundrobin
haproxy.router.openshift.io/disable_cookies: 'true'