Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions charts/keycloakx/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: keycloakx
version: 7.1.11
appVersion: 26.5.6
version: 7.1.12
appVersion: 26.6.1
description: Keycloak.X - Open Source Identity and Access Management for Modern Applications and Services
keywords:
- sso
Expand Down
28 changes: 27 additions & 1 deletion charts/keycloakx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,14 @@ The following table lists the configurable parameters of the Keycloak-X chart an
| `test.image.pullPolicy` | The image pull policy for the test Pod image | `IfNotPresent` |
| `test.podSecurityContext` | SecurityContext for the entire test Pod | `{"fsGroup":1000}` |
| `test.securityContext` | SecurityContext for the test container | `{"runAsNonRoot":true,"runAsUser":1000}` |
| `test.deletionPolicy` | `helm.sh/hook-delete-policy` for the test Pod | `before-hook-creation` | | `before-hook-creation` |
| `test.deletionPolicy` | `helm.sh/hook-delete-policy` for the test Pod | `before-hook-creation` |
| `updateHook.enabled` | If `true`, enables the update hook that runs before statefulset updates | `false` |
| `updateHook.image` | The image used for the update hook | `docker.io/curlimages/curl` |
| `updateHook.podSecurityContext` | SecurityContext for the update hook Pod | `{"fsGroup":1000,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}} |
| `updateHook.securityContext` | SecurityContext for the update hook container | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsUser":1000} |
| `updateHook.resources` | Resource requests and limits for the update hook container | `{"limits":{"cpu":"20m","memory":"32Mi"},"requests":{"cpu":"20m","memory":"32Mi"}}` |
| `updateHook.kubernetesApi.port` | Kubernetes API port for the update hook (Required if updateHook is enabled) | `""` |
| `updateHook.kubernetesApi.ip` | Kubernetes API IP for the update hook (Required if updateHook and networkpolicy are enabled) | `""` |

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:

Expand Down Expand Up @@ -372,6 +379,25 @@ extraEnv: |
For high availability, Keycloak must be run with multiple replicas (`replicas > 1`).
The chart has a helper template (`keycloak.serviceDnsName`) that creates the DNS name based on the headless service.

#### Updating Minor and Major Versions in Cluster Mode

Keycloak does **not** support minor or major version upgrades while running in cluster mode. Only patch updates are supported.
(Refer to the official Keycloak documentation for more details.)

If you attempt such an upgrade in cluster mode, you may encounter errors due to JGroups version mismatches, for example:

> WARN [org.jgroups.protocols.TCP] (TcpServer.Acceptor[7800]-1,keycloakx-1-2180(v=16.0.8)) JGRP000006: 10.151.254.47:7800: failed accepting connection from peer SSLSocket[hostname=127.0.0.6, port=51749, Session(1776862509121|TLS_AES_256_GCM_SHA384)]: java.io.IOException: 10.151.254.47:7800: readPeerAddress(): packet from /127.0.0.6:51749 has different version (5.3.16) from ours (5.5.1); discarding it

Because of this limitation, **downtime is required** to perform minor or major version upgrades.

**Recommended upgrade procedure:**

1. Scale down the StatefulSet to a single replica to disable cluster mode.
2. Perform the version upgrade.
3. Once the upgrade is complete, scale the StatefulSet back to its original number of replicas.

To simplify this process, the chart includes an `updateHook` parameter that automates these steps.

### Default Cache Stack

The default cache stack is now using `jdbc-ping` which leverages a table called `jgroups_ping` in the keycloak database to store the cache and significantly reduces network complexity. Keycloak has set this [transport stack](https://www.keycloak.org/server/caching#_transport_stacks) as the default starting in 26.1.0 and it is backwards compatible with all 26.X releases.
Expand Down
2 changes: 1 addition & 1 deletion charts/keycloakx/examples/postgresql-kubeping/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM quay.io/keycloak/keycloak:26.5.6
FROM quay.io/keycloak/keycloak:26.6.1

ENV JGROUPS_KUBERNETES_VERSION 1.0.16.Final

Expand Down
24 changes: 24 additions & 0 deletions charts/keycloakx/templates/hooks/networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{- if and .Values.updateHook.enabled (gt (int .Values.replicas) 1) .Values.networkPolicy.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: "{{ include "keycloak.fullname" . }}-scale-down"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": "-15"
spec:
podSelector:
matchLabels:
job-name: "{{ include "keycloak.fullname" . }}-scale-down"
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: {{ printf "%s/32" .Values.updateHook.kubernetesApi.ip | quote }}
ports:
- protocol: TCP
port: {{ .Values.updateHook.kubernetesApi.port }}
{{- end }}
40 changes: 40 additions & 0 deletions charts/keycloakx/templates/hooks/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{- if and .Values.updateHook.enabled (gt (int .Values.replicas) 1) }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: "{{ include "keycloak.fullname" . }}-scale-down"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": "-15"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: "{{ include "keycloak.fullname" . }}-scale-down"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": "-15"
rules:
- apiGroups: ["apps"]
resources: ["statefulsets", "statefulsets/scale"]
verbs: ["get", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: "{{ include "keycloak.fullname" . }}-scale-down"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": "-15"
subjects:
- kind: ServiceAccount
name: "{{ include "keycloak.fullname" . }}-scale-down"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: "{{ include "keycloak.fullname" . }}-scale-down"
{{- end }}
42 changes: 42 additions & 0 deletions charts/keycloakx/templates/hooks/scale-down.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{- if and .Values.updateHook.enabled (gt (int .Values.replicas) 1) }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ include "keycloak.fullname" . }}-scale-down"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": "-10"
spec:
template:
spec:
serviceAccountName: "{{ include "keycloak.fullname" . }}-scale-down"
restartPolicy: Never
securityContext:
{{- toYaml .Values.updateHook.podSecurityContext | nindent 8 }}
containers:
- name: kubectl
image: "{{ .Values.updateHook.image }}"
securityContext:
{{- toYaml .Values.updateHook.securityContext | nindent 12 }}
command:
- /bin/sh
- -ec
- |
TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)"
CACERT="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
KUBERNETES_API="https://{{ .Values.updateHook.kubernetesApi.ip }}:{{ .Values.updateHook.kubernetesApi.port }}"

curl --fail --silent --show-error \
--cacert "${CACERT}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/merge-patch+json" \
-X PATCH \
"${KUBERNETES_API}/apis/apps/v1/namespaces/${NAMESPACE}/statefulsets/{{ include "keycloak.fullname" . }}/scale" \
--data '{"spec":{"replicas":1}}'
resources:
{{- toYaml .Values.updateHook.resources | nindent 12 }}
backoffLimit: 0
{{- end }}
29 changes: 28 additions & 1 deletion charts/keycloakx/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ image:
# The Keycloak image repository
repository: quay.io/keycloak/keycloak
# Overrides the Keycloak image tag whose default is the chart appVersion
tag: "26.5.6"
tag: ""
# Overrides the Keycloak image tag with a specific digest
digest: ""
# The Keycloak image pull policy
Expand Down Expand Up @@ -646,3 +646,30 @@ extraManifests: []
# name: "{{ include \"keycloak.fullname\" . }}-tpl"
# data:
# foo: bar

updateHook:
enabled: false
image: docker.io/curlimages/curl
podSecurityContext:
fsGroup: 1000
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
runAsGroup: 1000
runAsUser: 1000
resources:
requests:
cpu: "20m"
memory: "32Mi"
limits:
cpu: "20m"
memory: "32Mi"
# kubernetesApi:
# ip: 10.20.30.40
# port: 8443
Loading