diff --git a/charts/keycloakx/examples/infinispan-jdbcping/keycloak-cluster.yaml b/charts/keycloakx/examples/infinispan-jdbcping/keycloak-cluster.yaml new file mode 100644 index 000000000..75f039574 --- /dev/null +++ b/charts/keycloakx/examples/infinispan-jdbcping/keycloak-cluster.yaml @@ -0,0 +1,13 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: keycloak-db + namespace: keycloak +spec: + instances: 3 + storage: + size: 5Gi + bootstrap: + initdb: + database: keycloak + owner: keycloak diff --git a/charts/keycloakx/examples/infinispan-jdbcping/keycloak-server-values.yaml b/charts/keycloakx/examples/infinispan-jdbcping/keycloak-server-values.yaml new file mode 100644 index 000000000..cc48c74ea --- /dev/null +++ b/charts/keycloakx/examples/infinispan-jdbcping/keycloak-server-values.yaml @@ -0,0 +1,81 @@ +replicas: 3 +command: + - "/opt/keycloak/bin/kc.sh" + - "--verbose" + - "start" + - "--http-port=8080" + - "--hostname-strict=false" + - "--db=postgres" + - "--spi-events-listener-jboss-logging-success-level=info" + - "--spi-events-listener-jboss-logging-error-level=warn" +database: + existingSecret: "keycloak-db-credentials" + existingSecretKeys: + username: "username" + password: "password" + hostname: "host" + port: "port" + database: "database" + vendor: "vendor" +cache: + stack: jdbc-ping +infinispan: + owners: + sessions: 2 + authenticationSessions: 2 + userSessions: 2 + offlineSessions: 2 +loadShedding: + enabled: true + httpMaxQueuedRequests: 1000 +threads: + http: + poolMaxThreads: "" + jgroups: + maxThreads: "" +resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "1000m" + memory: "2Gi" +ingress: + enabled: true + ingressClassName: "" + rules: + - host: auth.example.com + paths: + - path: /auth + pathType: Prefix +autoscaling: + enabled: false + minReplicas: 3 + maxReplicas: 6 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 +podDisruptionBudget: + minAvailable: 2 +serviceMonitor: + enabled: false +dbchecker: + enabled: true +affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + {{- include "keycloak.selectorLabels" . | nindent 12 }} + topologyKey: kubernetes.io/hostname + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + {{- include "keycloak.selectorLabels" . | nindent 14 }} + topologyKey: topology.kubernetes.io/zone diff --git a/charts/keycloakx/examples/infinispan-jdbcping/readme.md b/charts/keycloakx/examples/infinispan-jdbcping/readme.md new file mode 100644 index 000000000..a5a068715 --- /dev/null +++ b/charts/keycloakx/examples/infinispan-jdbcping/readme.md @@ -0,0 +1,33 @@ +# Keycloak.X with JDBC Ping, Infinispan Replication and Load Shedding + +## Deploy Kubernetes Cluster + +## Deploy a PostgreSQL database +``` +kubectl apply -f keycloak-cluster.yaml +kubectl wait -for=condition=Ready cluster/keycloak-database --timeout=300s +``` + +# Deploy Keycloak +``` +helm install keycloak . \ + --namespace keycloak --create-namespace \ + --values examples/infinispan-jdbc-ping/keycloak-server-values.yaml +``` + +# Access Keycloak +Once Keycloak is running, forward the HTTP service port to 8080. + +``` +kubectl port-forward service/keycloak-keycloakx-http 8080:80 +``` + +You can then access the Keycloak Admin-Console via `http://localhost:8080/auth` with +username: `admin` and password: `secret`. + +# Remove Keycloak + +``` +helm uninstall keycloak +kubectl delete -f keycloak-cluster.yaml +``` diff --git a/charts/keycloakx/templates/_helpers.tpl b/charts/keycloakx/templates/_helpers.tpl index 18d7ca6dc..1a3632845 100644 --- a/charts/keycloakx/templates/_helpers.tpl +++ b/charts/keycloakx/templates/_helpers.tpl @@ -65,6 +65,35 @@ Create the service DNS name. {{ include "keycloak.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} {{- end }} +{{/* +Get database hostname from existingSecretKeys or direct value +*/}} +{{- define "keycloak.databaseHostname" -}} +{{- if .Values.database.existingSecretKeys.hostname }} +{{- .Values.database.existingSecretKeys.hostname }} +{{- else if .Values.database.hostname }} +{{- .Values.database.hostname }} +{{- else }} +{{- fail "database hostname is required" }} +{{- end }} +{{- end }} + +{{/* +Get database port from existingSecretKeys or direct value +*/}} +{{- define "keycloak.databasePort" -}} +{{- if .Values.database.existingSecretKeys.port }} +{{- .Values.database.existingSecretKeys.port }} +{{- else if .Values.database.port }} +{{- .Values.database.port }} +{{- else }} +{{- fail "database port is required" }} +{{- end }} +{{- end }} + +{{/* +Database password environment variable handling +*/}} {{- define "keycloak.databasePasswordEnv" -}} {{- if or .Values.database.password .Values.database.existingSecret -}} - name: KC_DB_PASSWORD @@ -74,3 +103,53 @@ Create the service DNS name. key: {{ .Values.database.existingSecretKey | default "password" }} {{- end }} {{- end -}} + +{{/* +Database credential environment variable handling from existing secret +*/}} +{{- define "keycloak.databaseCredentialEnv" -}} +{{- if .Values.database.existingSecret -}} + {{- if .Values.database.existingSecretKeys.username }} +- name: KC_DB_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.username }} + {{- end }} + {{- if .Values.database.existingSecretKeys.password }} +- name: KC_DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.password }} + {{- end }} + {{- if .Values.database.existingSecretKeys.hostname }} +- name: KC_DB_URL_HOST + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.hostname }} + {{- end }} + {{- if .Values.database.existingSecretKeys.port }} +- name: KC_DB_URL_PORT + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.port }} + {{- end }} + {{- if .Values.database.existingSecretKeys.database }} +- name: KC_DB_URL_DATABASE + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.database }} + {{- end }} + {{- if .Values.database.existingSecretKeys.vendor }} +- name: KC_DB + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.vendor }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/charts/keycloakx/templates/statefulset.yaml b/charts/keycloakx/templates/statefulset.yaml index 07b96238f..13618751e 100644 --- a/charts/keycloakx/templates/statefulset.yaml +++ b/charts/keycloakx/templates/statefulset.yaml @@ -48,13 +48,43 @@ spec: imagePullPolicy: {{ .Values.dbchecker.image.pullPolicy }} securityContext: {{- toYaml .Values.dbchecker.securityContext | nindent 12 }} + env: + {{- if .Values.database.existingSecret }} + # Read hostname from secret + {{- if .Values.database.existingSecretKeys.hostname }} + - name: DB_HOST + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.hostname }} + {{- else if .Values.database.hostname }} + - name: DB_HOST + value: {{ .Values.database.hostname | quote }} + {{- end }} + # Read port from secret + {{- if .Values.database.existingSecretKeys.port }} + - name: DB_PORT + valueFrom: + secretKeyRef: + name: {{ .Values.database.existingSecret }} + key: {{ .Values.database.existingSecretKeys.port }} + {{- else if .Values.database.port }} + - name: DB_PORT + value: {{ .Values.database.port | quote }} + {{- end }} + {{- else }} + - name: DB_HOST + value: {{ .Values.database.hostname | quote }} + - name: DB_PORT + value: {{ .Values.database.port | quote }} + {{- end }} command: - sh - -c - | echo 'Waiting for Database to become ready...' - until printf "." && nc -z -w 2 {{ required ".Values.database.hostname is required if dbchecker is enabled!" .Values.database.hostname }} {{ required ".Values.database.port is required if dbchecker is enabled!" .Values.database.port }}; do + until printf "." && nc -z -w 2 "$DB_HOST" "$DB_PORT"; do sleep 2; done; @@ -98,6 +128,16 @@ spec: value: "ispn" - name: KC_CACHE_STACK value: "jdbc-ping" + {{- else if eq .Values.cache.stack "jdbc-ping" }} + - name: KC_CACHE + value: "ispn" + - name: KC_CACHE_STACK + value: "jdbc-ping" + {{- end }} + {{- if and (eq .Values.cache.stack "jdbc-ping") .Values.cache.jgroups.config }} + - name: KC_CACHE_STACK_CONFIG + value: | +{{ tpl .Values.cache.jgroups.config . | indent 16 }} {{- end }} {{- if .Values.proxy.enabled }} - name: KC_PROXY_HEADERS @@ -107,29 +147,42 @@ spec: - name: KC_HTTP_ENABLED value: "true" {{- end }} - {{- if .Values.database.vendor }} + {{- if and .Values.database.vendor (not .Values.database.existingSecretKeys.vendor) }} - name: KC_DB value: {{ .Values.database.vendor }} {{- end }} - {{- if .Values.database.hostname }} + {{- if not .Values.database.existingSecret }} + {{- if .Values.database.hostname }} - name: KC_DB_URL_HOST value: {{ .Values.database.hostname }} - {{- end }} - {{- if .Values.database.port }} + {{- end }} + {{- if .Values.database.port }} - name: KC_DB_URL_PORT value: {{ .Values.database.port | quote }} - {{- end }} - {{- if .Values.database.database }} + {{- end }} + {{- if .Values.database.database }} - name: KC_DB_URL_DATABASE value: {{ .Values.database.database }} + {{- end }} + {{- if .Values.database.username }} + - name: KC_DB_USERNAME + value: {{ .Values.database.username }} + {{- end }} {{- end }} - {{- if .Values.database.username }} + {{- if .Values.database.existingSecret }} + {{- if not .Values.database.existingSecretKeys.username }} + {{- if .Values.database.username }} - name: KC_DB_USERNAME value: {{ .Values.database.username }} + {{- end }} + {{- end }} + {{- include "keycloak.databaseCredentialEnv" . | nindent 12 }} {{- end }} {{- if or .Values.database.password .Values.database.existingSecret -}} + {{- if not .Values.database.existingSecretKeys.password }} {{- include "keycloak.databasePasswordEnv" . | nindent 12 }} {{- end }} + {{- end }} {{- if .Values.metrics.enabled }} - name: KC_METRICS_ENABLED value: "true" @@ -138,6 +191,48 @@ spec: - name: KC_HEALTH_ENABLED value: "true" {{- end }} + {{- if .Values.infinispan.owners.sessions }} + - name: KC_CACHE__OWNERS_SESSIONS + value: {{ .Values.infinispan.owners.sessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.authenticationSessions }} + - name: KC_CACHE__OWNERS_AUTHENTICATION_SESSIONS + value: {{ .Values.infinispan.owners.authenticationSessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.userSessions }} + - name: KC_CACHE__OWNERS_USER_SESSIONS + value: {{ .Values.infinispan.owners.userSessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.offlineSessions }} + - name: KC_CACHE__OWNERS_OFFLINE_SESSIONS + value: {{ .Values.infinispan.owners.offlineSessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.clientSessions }} + - name: KC_CACHE__OWNERS_CLIENT_SESSIONS + value: {{ .Values.infinispan.owners.clientSessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.offlineClientSessions }} + - name: KC_CACHE__OWNERS_OFFLINE_CLIENT_SESSIONS + value: {{ .Values.infinispan.owners.offlineClientSessions | quote }} + {{- end }} + {{- if .Values.infinispan.owners.loginFailures }} + - name: KC_CACHE__OWNERS_LOGIN_FAILURES + value: {{ .Values.infinispan.owners.loginFailures | quote }} + {{- end }} + {{- if .Values.loadShedding.enabled }} + {{- if .Values.loadShedding.httpMaxQueuedRequests }} + - name: KC_HTTP_MAX_QUEUED_REQUESTS + value: {{ .Values.loadShedding.httpMaxQueuedRequests | quote }} + {{- end }} + {{- end }} + {{- if and .Values.threads.http.poolMaxThreads (ne .Values.threads.http.poolMaxThreads "") }} + - name: KC_HTTP_POOL_MAX_THREADS + value: {{ .Values.threads.http.poolMaxThreads | quote }} + {{- end }} + {{- if and .Values.threads.jgroups.maxThreads (ne .Values.threads.jgroups.maxThreads "") }} + - name: KC_THREADS_MAX + value: {{ .Values.threads.jgroups.maxThreads | quote }} + {{- end }} {{- with .Values.extraEnv }} {{- tpl . $ | nindent 12 }} {{- end }} @@ -236,4 +331,4 @@ spec: {{- with .Values.volumeClaimTemplates }} volumeClaimTemplates: {{- tpl . $ | nindent 4 }} - {{- end }} + {{- end }} \ No newline at end of file diff --git a/charts/keycloakx/values.schema.json b/charts/keycloakx/values.schema.json index ad571a7fa..10eccf612 100644 --- a/charts/keycloakx/values.schema.json +++ b/charts/keycloakx/values.schema.json @@ -37,6 +37,69 @@ } } } + }, + "infinispan": { + "type": "object", + "properties": { + "owners": { + "type": "object", + "properties": { + "sessions": { + "type": "integer" + }, + "authenticationSessions": { + "type": "integer" + }, + "userSessions": { + "type": "integer" + }, + "offlineSessions": { + "type": "integer" + }, + "clientSessions": { + "type": "integer" + }, + "offlineClientSessions": { + "type": "integer" + }, + "loginFailures": { + "type": "integer" + } + } + } + } + }, + "loadShedding": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "httpMaxQueuedRequests": { + "type": "integer" + } + } + }, + "threads": { + "type": "object", + "properties": { + "http": { + "type": "object", + "properties": { + "poolMaxThreads": { + "type": "string" + } + } + }, + "jgroups": { + "type": "object", + "properties": { + "maxThreads": { + "type": "string" + } + } + } + } } }, "properties": { @@ -239,9 +302,26 @@ "properties": { "stack": { "type": "string" + }, + "jgroups": { + "type": "object", + "properties": { + "config": { + "type": "string" + } + } } } }, + "infinispan": { + "$ref": "#/definitions/infinispan" + }, + "loadShedding": { + "$ref": "#/definitions/loadShedding" + }, + "threads": { + "$ref": "#/definitions/threads" + }, "proxy": { "type": "object", "properties": { @@ -292,6 +372,29 @@ }, "existingSecret": { "type": "string" + }, + "existingSecretKeys": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "port": { + "type": "string" + }, + "database": { + "type": "string" + }, + "vendor": { + "type": "string" + } + } } } }, diff --git a/charts/keycloakx/values.yaml b/charts/keycloakx/values.yaml index 709a7960c..d36f7e6e7 100644 --- a/charts/keycloakx/values.yaml +++ b/charts/keycloakx/values.yaml @@ -1,12 +1,9 @@ # Optionally override the fully qualified name fullnameOverride: "" - # Optionally override the name nameOverride: "" - # The number of replicas to create (has no effect if autoscaling enabled) replicas: 1 - image: # The Keycloak image repository repository: quay.io/keycloak/keycloak @@ -16,7 +13,6 @@ image: digest: "" # The Keycloak image pull policy pullPolicy: IfNotPresent - # Image pull secrets for the Pod imagePullSecrets: [] # - name: myRegistrKeySecretName @@ -29,16 +25,12 @@ hostAliases: [] # Indicates whether information about services should be injected into Pod's environment variables, matching the syntax of Docker links enableServiceLinks: true - # Pod management policy. One of `Parallel` or `OrderedReady` podManagementPolicy: OrderedReady - # StatefulSet's update strategy updateStrategy: RollingUpdate - # Pod restart policy. One of `Always`, `OnFailure`, or `Never` restartPolicy: Always - serviceAccount: # Specifies whether a ServiceAccount should be created create: true @@ -55,7 +47,6 @@ serviceAccount: imagePullSecrets: [] # Automount API credentials for the Service Account automountServiceAccountToken: true - rbac: create: false rules: [] @@ -67,30 +58,24 @@ rbac: # verbs: # - get # - list - # SecurityContext for the entire Pod. Every container running in the Pod will inherit this SecurityContext. This might be relevant when other components of the environment inject additional containers into running Pods (service meshes are the most prominent example for this) podSecurityContext: fsGroup: 1000 - # SecurityContext for the Keycloak container securityContext: runAsUser: 1000 runAsNonRoot: true - # Additional init containers, e. g. for providing custom themes extraInitContainers: "" - # When using service meshes which rely on a sidecar, it may be necessary to skip init containers altogether, # since the sidecar doesn't start until the init containers are done, and the sidecar may be required # for network access. # For example, Istio in strict mTLS mode prevents the dbchecker init container from ever completing skipInitContainers: false - # Additional sidecar containers, e. g. for a database proxy, such as Google's cloudsql-proxy extraContainers: "" - # Lifecycle hooks for the Keycloak container -lifecycleHooks: | +lifecycleHooks: "" # postStart: # exec: # command: @@ -100,27 +85,36 @@ lifecycleHooks: | # Termination grace period in seconds for Keycloak shutdown. Clusters with a large cache might need to extend this to give Infinispan more time to rebalance terminationGracePeriodSeconds: 60 - # The internal Kubernetes cluster domain clusterDomain: cluster.local - ## Overrides the default entrypoint of the Keycloak container command: [] - ## Overrides the default args for the Keycloak container args: [] - +# Load shedding configuration for handling high load (recommended by Keycloak) +loadShedding: + # Enable load shedding to protect against overload + enabled: false + # Maximum number of queued HTTP requests + httpMaxQueuedRequests: 1000 +# Thread management - LET QUARKUS MANAGE AUTOMATICALLY (recommended) +# Quarkus automatically optimizes thread pools based on CPU cores and workload +# Override only if you have specific requirements +threads: + # Override Quarkus defaults ONLY if necessary + http: + poolMaxThreads: "" # Let Quarkus decide (usually CPU cores * 2) + jgroups: + maxThreads: "" # Let Quarkus optimize for clustering # Additional environment variables for Keycloak extraEnv: "" - # - name: KC_LOG_LEVEL - # value: DEBUG +# - name: KC_LOG_LEVEL +# value: DEBUG # Additional environment variables for Keycloak mapped from Secret or ConfigMap extraEnvFrom: "" - # Pod priority class name priorityClassName: "" - # Pod affinity affinity: | podAntiAffinity: @@ -146,22 +140,16 @@ affinity: | values: - test topologyKey: topology.kubernetes.io/zone - # Topology spread constraints template topologySpreadConstraints: - # Node labels for Pod assignment nodeSelector: {} - # Node taints to tolerate tolerations: [] - # Additional Pod labels podLabels: {} - # Additional Pod annotations podAnnotations: {} - # Liveness probe configuration livenessProbe: | httpGet: @@ -170,7 +158,6 @@ livenessProbe: | scheme: '{{ .Values.http.internalScheme }}' initialDelaySeconds: 0 timeoutSeconds: 5 - # Readiness probe configuration readinessProbe: | httpGet: @@ -179,7 +166,6 @@ readinessProbe: | scheme: '{{ .Values.http.internalScheme }}' initialDelaySeconds: 10 timeoutSeconds: 1 - # Startup probe configuration startupProbe: | httpGet: @@ -190,36 +176,32 @@ startupProbe: | timeoutSeconds: 1 failureThreshold: 60 periodSeconds: 5 - # Pod resource requests and limits resources: {} - # requests: - # cpu: "500m" - # memory: "1024Mi" - # limits: - # cpu: "500m" - # memory: "1024Mi" +# requests: +# cpu: "500m" +# memory: "1024Mi" +# limits: +# cpu: "500m" +# memory: "1024Mi" # Add additional volumes, e. g. for custom themes extraVolumes: "" - # Add volume claim templates to the StatefulSet, e. g. for dynamic provisioning volumeClaimTemplates: "" - # - metadata: - # name: themes - # spec: - # accessModes: [ "ReadWriteOncePod" ] - # storageClassName: "my-storage-class" - # resources: - # requests: - # storage: 1Gi +# - metadata: +# name: themes +# spec: +# accessModes: [ "ReadWriteOncePod" ] +# storageClassName: "my-storage-class" +# resources: +# requests: +# storage: 1Gi # Add additional volumes mounts, e. g. for custom themes extraVolumeMounts: "" - # Add additional ports, e. g. for admin console or exposing JGroups ports extraPorts: [] - # Pod disruption budget podDisruptionBudget: {} # maxUnavailable: 1 @@ -227,18 +209,16 @@ podDisruptionBudget: {} # Annotations for the StatefulSet statefulsetAnnotations: {} - # Additional labels for the StatefulSet statefulsetLabels: {} - # Configuration for secrets that should be created secrets: {} - # mysecret: - # type: {} - # annotations: {} - # labels: {} - # stringData: {} - # data: {} +# mysecret: +# type: {} +# annotations: {} +# labels: {} +# stringData: {} +# data: {} service: # Annotations for HTTP service @@ -273,13 +253,11 @@ service: sessionAffinity: "" # Session affinity config sessionAffinityConfig: {} - serviceHeadless: # Annotations for headless service annotations: {} # Add additional ports to the headless service, e. g. for admin console or exposing JGroups ports extraPorts: [] - ingress: # If `true`, an Ingress is created enabled: false @@ -289,16 +267,15 @@ ingress: servicePort: http # Ingress annotations annotations: {} - ## Resolve HTTP 502 error using ingress-nginx: - ## See https://www.ibm.com/support/pages/502-error-ingress-keycloak-response - # nginx.ingress.kubernetes.io/proxy-buffer-size: 128k + ## Resolve HTTP 502 error using ingress-nginx: + ## See https://www.ibm.com/support/pages/502-error-ingress-keycloak-response + # nginx.ingress.kubernetes.io/proxy-buffer-size: 128k # Additional Ingress labels labels: {} - # List of rules for the Ingress + # List of rules for the Ingress rules: - - - # Ingress host + - # Ingress host host: '{{ .Release.Name }}.keycloak.example.com' # Paths for the host paths: @@ -322,33 +299,27 @@ ingress: # Additional Ingress labels for console path only labels: {} rules: - - - # Ingress host + - # Ingress host host: '{{ .Release.Name }}.keycloak.example.com' # Paths for the host paths: - path: '{{ tpl .Values.http.relativePath $ | trimSuffix "/" }}/admin' pathType: Prefix - # Console TLS configuration tls: [] # - hosts: # - console.keycloak.example.com # secretName: "" - ## Network policy configuration # https://kubernetes.io/docs/concepts/services-networking/network-policies/ networkPolicy: # If true, the Network policies are deployed enabled: false - # Additional Network policy labels labels: {} - # Define all other external allowed source # See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#networkpolicypeer-v1-networking-k8s-io extraFrom: [] - # Define egress networkpolicies for the Keycloak pods (external database for example) # See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#networkpolicyegressrule-v1-networking-k8s-io # egress: @@ -359,7 +330,6 @@ networkPolicy: # - protocol: TCP # port: 3306 egress: [] - route: # If `true`, an OpenShift Route is created enabled: false @@ -379,7 +349,6 @@ route: insecureEdgeTerminationPolicy: Redirect # TLS termination of the route. Can be `edge`, `passthrough`, or `reencrypt` termination: edge - dbchecker: enabled: false image: @@ -403,13 +372,21 @@ dbchecker: limits: cpu: "20m" memory: "32Mi" - database: # don't create secret for db password. Instead use existing k8s secret # existingSecret: "my-existent-dbpass-secret" # existingSecretKey: "password" existingSecret: "" existingSecretKey: "" + # Comprehensive database credentials from existing secret + # Maps secret keys to database configuration fields + existingSecretKeys: + username: "" + password: "" + hostname: "" + port: "" + database: "" + vendor: "" # E.g. dev-file, dev-mem, mariadb, mssql, mysql, oracle or postgres vendor: hostname: @@ -417,29 +394,57 @@ database: database: username: password: - cache: # Use "custom" to disable automatic cache configuration stack: default - + # Advanced cache stack configuration for jdbc-ping + # When stack is "jdbc-ping", JGroups configuration will be generated + jgroups: + # JGroups protocol stack configuration (optional) + # If not provided, default jdbc-ping configuration will be used + # Use template functions for dynamic database configuration: + # config: | + # + # + # + # + config: "" + # Additional JGroups properties + properties: {} +# Infinispan session replication configuration +infinispan: + # Number of owners for cache entries (replication factor) + owners: + # Number of owners for sessions cache (default: 2) + sessions: 2 + # Number of owners for authenticationSessions cache (default: 2) + authenticationSessions: 2 + # Number of owners for userSessions cache (default: 2) + userSessions: 2 + # Number of owners for offlineSessions cache (default: 2) + offlineSessions: 2 + # Number of owners for clientSessions cache (default: 2) + clientSessions: 2 + # Number of owners for offlineClientSessions cache (default: 2) + offlineClientSessions: 2 + # Number of owners for loginFailures cache (default: 2) + loginFailures: 2 + # Additional Infinispan configuration + additionalConfig: "" proxy: enabled: true mode: forwarded http: enabled: true - metrics: enabled: true - health: enabled: true - http: # For backwards compatibility reasons we set this to the value used by previous Keycloak versions. relativePath: "/auth" internalPort: http-internal internalScheme: HTTP - serviceMonitor: # If `true`, a ServiceMonitor resource for the prometheus-operator is created enabled: false @@ -463,7 +468,6 @@ serviceMonitor: path: '{{ tpl .Values.http.relativePath $ | trimSuffix "/" }}/metrics' # The Service port at which metrics are served port: '{{ .Values.http.internalPort }}' - extraServiceMonitor: # If `true`, a ServiceMonitor resource for the prometheus-operator is created enabled: false @@ -487,7 +491,6 @@ extraServiceMonitor: path: '{{ tpl .Values.http.relativePath $ | trimSuffix "/" }}/metrics' # The Service port at which metrics are served port: '{{ .Values.http.internalPort }}' - prometheusRule: # If `true`, a PrometheusRule resource for the prometheus-operator is created enabled: false @@ -519,7 +522,6 @@ prometheusRule: # for: 5m # labels: # severity: warning - autoscaling: # If `true`, an autoscaling/v2 HorizontalPodAutoscaler resource is created (requires Kubernetes 1.23 or above) # Autoscaling seems to be most reliable when using KUBE_PING service discovery (see README for details) @@ -547,7 +549,6 @@ autoscaling: - type: Pods value: 1 periodSeconds: 300 - test: # If `true`, test resources are created enabled: false