Skip to content

Commit

Permalink
Merge pull request #135 from projectsyn/quarkus-postgresql
Browse files Browse the repository at this point in the history
Migration to Quarkus
  • Loading branch information
megian authored Jun 16, 2022
2 parents 1fc3cca + aaee4b3 commit 4992b60
Show file tree
Hide file tree
Showing 66 changed files with 1,081 additions and 753 deletions.
97 changes: 62 additions & 35 deletions class/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ parameters:
# This lookup table controls whether to enable the chart depending on the value of `keycloak.database.provider`
builtin: true
external: false
=_hostname_strict:
# This lookup table controls whether to enable KC_HOSTNAME_STRICT depending on the value of `keycloak.ingress.tls.termination`
passthrough: 'true'
reencrypt: 'false'
=_ingress_annotations:
# This lookup table controls whether to set specific annotations depending on the value of `keycloak.ingress.controller`,
# `keycloak.ingress.tls.termination` and `keycloak.ingress.tls.provider`
Expand Down Expand Up @@ -36,9 +40,12 @@ parameters:
namespace: syn-${_instance}
name: keycloak
charts:
keycloak: "18.1.1"
keycloakx: "1.3.2"
postgresql: "10.16.2"
# FQDN should be overwritten on the cluster level
fqdn: keycloak.example.com
# Disables dynamically resolving the hostname from request headers.
hostnameStrict: ${keycloak:_hostname_strict:${keycloak:ingress:tls:termination}}
# Namespace labels
namespaceLabels: {}
# Keycloak Admin
Expand Down Expand Up @@ -116,7 +123,6 @@ parameters:
# the metrics endpoint by default.
monitoring:
enabled: true
statistics: all
rules: []
# Use Bitnami Postgres installed by the Keycloak chart by default
database:
Expand Down Expand Up @@ -159,6 +165,14 @@ parameters:
replicas: ${keycloak:replicas}
statefulsetLabels: ${keycloak:labels}
resources: ${keycloak:resources}

# See https://www.keycloak.org/server/configuration
# See https://www.keycloak.org/server/all-config
args:
- start
- --auto-build
- --http-enabled=true # Helm chart requires it currently

# extraEnv *MUST* be a string, as it's fed through a templating
# function.
extraEnv: |
Expand All @@ -167,21 +181,17 @@ parameters:
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=50.0
-Djava.net.preferIPv4Stack=true
-Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS
-Djava.awt.headless=true
-Djgroups.dns.query={{ include "keycloak.fullname" . }}-headless
${keycloak:extraJavaOpts}
- name: KEYCLOAK_STATISTICS
value: ${keycloak:monitoring:statistics}
- name: JGROUPS_DISCOVERY_PROTOCOL
value: dns.DNS_PING
- name: JGROUPS_DISCOVERY_PROPERTIES
value: 'dns_query={{ include "keycloak.serviceDnsName" . }}'
- name: CACHE_OWNERS_COUNT
value: "${keycloak:helm_values:replicas}"
- name: CACHE_OWNERS_AUTH_SESSIONS_COUNT
value: "${keycloak:helm_values:replicas}"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
- name: KC_HOSTNAME
value: ${keycloak:fqdn}
- name: KC_HOSTNAME_STRICT
value: '${keycloak:hostnameStrict}'
- name: KC_HTTPS_CERTIFICATE_FILE
value: /etc/x509/https/tls.crt
- name: KC_HTTPS_CERTIFICATE_KEY_FILE
value: /etc/x509/https/tls.key
extraEnvFrom: |
- secretRef:
name: ${keycloak:admin:secretname}
Expand Down Expand Up @@ -249,23 +259,40 @@ parameters:
enabled: ${keycloak:monitoring:enabled}
labels: ${keycloak:labels}
rules: ${keycloak:monitoring:rules}
postgresql:
enabled: ${keycloak:_enable_pg_chart:${keycloak:database:provider}}
existingSecret: ${keycloak:database:secretname}
primary:
podAnnotations:
# Annotations to support both K8up v1 and v2
k8up.syn.tools/backupcommand: sh -c 'PGDATABASE="$POSTGRES_DB" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" pg_dump --clean'
k8up.syn.tools/file-extension: .sql
k8up.io/backupcommand: sh -c 'PGDATABASE="$POSTGRES_DB" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" pg_dump --clean'
k8up.io/file-extension: .sql
labels: ${keycloak:labels}
volumePermissions:
enabled: ${keycloak:database:tls:enabled}
tls:
enabled: ${keycloak:database:tls:enabled}
certificatesSecret: ${keycloak:database:tls:certSecretName}
certFilename: tls.crt
certKeyFilename: tls.key
networkPolicy:
enabled: true
dbchecker:
enabled: 'true'
proxy:
enabled: 'true'
mode: ${keycloak:ingress:tls:termination}

metrics:
enabled: ${keycloak:monitoring:enabled}
database:
vendor: ${keycloak:database:external:vendor}
hostname: keycloak-postgresql
port: ${keycloak:database:external:port}
database: ${keycloak:database:database}
username: ${keycloak:database:username}

postgresql_helm_values:
enabled: ${keycloak:_enable_pg_chart:${keycloak:database:provider}}
postgresqlDatabase: ${keycloak:database:database}
postgresqlUsername: ${keycloak:database:username}
existingSecret: ${keycloak:database:secretname}
primary:
podAnnotations:
# Annotations to support both K8up v1 and v2
k8up.syn.tools/backupcommand: sh -c 'PGDATABASE="$POSTGRES_DB" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" pg_dump --clean'
k8up.syn.tools/file-extension: .sql
k8up.io/backupcommand: sh -c 'PGDATABASE="$POSTGRES_DB" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" pg_dump --clean'
k8up.io/file-extension: .sql
labels: ${keycloak:labels}
volumePermissions:
enabled: ${keycloak:database:tls:enabled}
tls:
enabled: ${keycloak:database:tls:enabled}
certificatesSecret: ${keycloak:database:tls:certSecretName}
certFilename: tls.crt
certKeyFilename: tls.key
networkPolicy:
enabled: true
29 changes: 23 additions & 6 deletions class/keycloak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ parameters:
kapitan:
dependencies:
- type: helm
chart_name: keycloak
version: ${keycloak:charts:keycloak}
chart_name: keycloakx
version: ${keycloak:charts:keycloakx}
source: https://codecentric.github.io/helm-charts
output_path: dependencies/keycloak/helmcharts/keycloak/${keycloak:charts:keycloak}/
output_path: dependencies/keycloak/helmcharts/keycloakx/${keycloak:charts:keycloakx}/
- type: helm
chart_name: postgresql
version: ${keycloak:charts:postgresql}
source: https://charts.bitnami.com/bitnami
output_path: dependencies/keycloak/helmcharts/postgresql/${keycloak:charts:postgresql}/
compile:
- input_paths:
- keycloak/component/app.jsonnet
Expand All @@ -23,18 +28,30 @@ parameters:
input_type: helm
output_type: yaml
input_paths:
- keycloak/helmcharts/keycloak/${keycloak:charts:keycloak}/
- keycloak/helmcharts/keycloakx/${keycloak:charts:keycloakx}/
helm_params:
name: ${keycloak:name}
name: keycloakx
namespace: "${keycloak:namespace}"
# Tell Helm to generate networking.k8s.io/v1 Ingress objects
# This specifies argument `-a networking.k8s.io/v1/Ingress` for
# `helm template`.
api_versions: networking.k8s.io/v1/Ingress
helm_values: ${keycloak:helm_values}
- output_path: ${_instance}/01_keycloak_helmchart
input_type: helm
output_type: yaml
input_paths:
- keycloak/helmcharts/postgresql/${keycloak:charts:postgresql}/
helm_params:
name: keycloak
namespace: "${keycloak:namespace}"
helm_values: ${keycloak:postgresql_helm_values}
commodore:
postprocess:
filters:
- type: jsonnet
filter: postprocess/extra-env.jsonnet
path: ${_instance}/01_keycloak_helmchart/keycloak/templates
path: ${_instance}/01_keycloak_helmchart/keycloakx/templates
- type: jsonnet
filter: postprocess/postgresql.jsonnet
path: ${_instance}/01_keycloak_helmchart/postgresql/templates
43 changes: 35 additions & 8 deletions component/main.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,43 @@ local namespace = kube.Namespace(params.namespace) {
},
};

local networkpolicy_infinispan_labels = {
'app.kubernetes.io/instance': 'keycloakx',
'app.kubernetes.io/name': 'keycloakx',
};

// https://infinispan.org/docs/stable/titles/security/security.html#jgroups-ports_network
local networkpolicy_infinispan = kube.NetworkPolicy('keycloakx-infinispan') {
metadata+: {
labels+: params.labels,
},
spec+: {
ingress: [ {
from: [ {
podSelector: {
matchLabels: networkpolicy_infinispan_labels,
},
} ],
ports: [
{
port: 7800,
protocol: 'TCP',
},
],
} ],
podSelector: {
matchLabels: networkpolicy_infinispan_labels,
},
},
};

local admin_secret = kube.Secret(params.admin.secretname) {
metadata+: {
labels+: params.labels,
},
stringData: {
KEYCLOAK_USER: params.admin.username,
KEYCLOAK_PASSWORD: params.admin.password,
KEYCLOAK_ADMIN: params.admin.username,
KEYCLOAK_ADMIN_PASSWORD: params.admin.password,
},
};

Expand All @@ -32,15 +62,11 @@ local connection_secrets = {
'postgresql-postgres-password': params.database.password,
// this secret is shared between Keycloak and PostgreSQL
'postgresql-password': params.database.password,
KC_DB_PASSWORD: params.database.password,
[if params.database.jdbcParams != '' then 'JDBC_PARAMS']: params.database.jdbcParams,
},
external: {
DB_DATABASE: params.database.database,
DB_USER: params.database.username,
DB_PASSWORD: params.database.password,
DB_VENDOR: params.database.external.vendor,
DB_ADDR: params.database.external.host,
DB_PORT: std.toString(params.database.external.port),
KC_DB_PASSWORD: params.database.password,
[if params.database.jdbcParams != '' then 'JDBC_PARAMS']: params.database.jdbcParams,
},
};
Expand Down Expand Up @@ -176,6 +202,7 @@ local k8up_schedule =
// Define outputs below
{
'00_namespace': namespace,
[if params.replicas >= 2 then '01_networkpolicy_infinispan']: networkpolicy_infinispan,
[if params.ingress.enabled && params.helm_values.networkPolicy.enabled then '01_ingress_controller_ns_patch']: ns_patch,
'10_admin_secret': admin_secret,
'11_db_secret': db_secret,
Expand Down
44 changes: 44 additions & 0 deletions docs/modules/ROOT/pages/explanations/migration-to-quarkus.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
= Migration to Quarkus

Keycloak v17 is https://www.keycloak.org/docs/17.0/upgrading/#default-distribution-is-now-powered-by-quarkus[changing their runtime] from https://www.wildfly.org[Wildfly] to https://quarkus.io[Quarkus].
This brings a complete new way of how the Keycloak container has to be https://www.keycloak.org/server/containers[deployed] (https://github.com/keycloak/keycloak/tree/main/quarkus/container[Quarkus based Keycloak Image] vs the https://github.com/keycloak/keycloak-containers[Wildfly based image]) and https://www.keycloak.org/server/all-config[parameterized].
While Wildfly is a full-fledged application server for Java, Quarkus is a Kubernetes Native Java stack.

The Keycloak default image requires a "build" before startup.
This can be automatized using the `--auto-build`, which is the default in the component.
This additional step can be removed by creating a https://www.keycloak.org/operator/customizing-keycloak[customized Keycloak image].

== New variables

* `KC_HOSTNAME` containing the FQDN of the Keycloak service.
Verification can be turned off by using the parameters `--hostname-strict=false` and `--hostname-strict-https=false`.
However, for production the hostname verification should be turned on!
* `KC_HTTP_RELATIVE_PATH` in Keycloak is `/` by default.
However, the Helm chart contains the default value of `/auth`, so for upgrades there is no breaking change.

== Changed variables

* The Wildfily container did automatically create a truststore file out of PEM files existing in `/etc/x509/https`.
Now the public and private key file must be defined in variables, for example `KC_HTTPS_CERTIFICATE_FILE=/etc/x509/https/tls.crt` and `KC_HTTPS_CERTIFICATE_KEY_FILE=/etc/x509/https/tls.key`.
* `KEYCLOAK_STATISTICS` is replaced by `KC_METRICS_ENABLED`.
* `JGROUPS_DISCOVERY_PROTOCOL` and `JGROUPS_DISCOVERY_PROPERTIES` are replaced by `JAVA_OPTS=-Djgroups.dns.query=keycloakx-headless` (see https://artifacthub.io/packages/helm/codecentric/keycloakx#dns_ping-service-discovery[Helm chart documentation]).
* `PROXY_ADDRESS_FORWARDING` removed, see https://www.keycloak.org/server/reverseproxy#_proxy_modes[Using a reverse proxy] and `KC_PROXY` for more information.
If `KC_PROXY` is set to a value of `edge`, `reencyrpt` or `passthrough` the `X-Forwarded-For`, `X-Forwarded-Proto` and `X-Forwarded-Host` HTTP headers are used by Keycloak (see https://github.com/keycloak/keycloak/blob/17.0.1/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java#L35[Source Code]).
* `KEYCLOAK_USER` renamed to `KEYCLOAK_ADMIN`
* `KEYCLOAK_PASSWORD` renamed to `KEYCLOAK_ADMIN_PASSWORD`
* `DB_DATABASE` renamed to `KC_DB_URL_DATABASE`
* `DB_USER` renamed to `KC_DB_USERNAME`
* `DB_PASSWORD` renamed to `KC_DB_PASSWORD`
* `DB_VENDOR` renamed to `KC_DB`
* `DB_ADDR` renamed to `KC_DB_URL_HOST`
* `DB_PORT` renamed to `KC_DB_URL_PORT`
* Theme path has changed from `/opt/jboss/keycloak/themes/` to `/opt/keycloak/themes/`.
* `KEYCLOAK_WELCOME_THEME` renamed to `KC_SPI_THEME_WELCOME_THEME`

== Removed variables

* `CACHE_OWNERS_AUTH_SESSIONS_COUNT` and `CACHE_OWNERS_COUNT` have no direct equivalent in the Quarkus setup.
A cache replica/owner number of `>= 2` is required to preserve the Infinispan cache over single Keycloak pod restarts.
The https://github.com/keycloak/keycloak-containers/blob/main/server/tools/cli/infinispan/cache-owners.cli[Wildfly default value] of those variables has been `1` and defined the amount of replicas/owners for a specific cache.
Now the default in the Quarkus Setup is https://www.keycloak.org/server/caching#_cache_types_and_defaults["Each distributed cache has two owners per default, which means that two nodes have a copy of the specific cache entries"].
A https://www.keycloak.org/server/caching#_specify_your_own_cache_configuration_file[custom Infinispan configuration file] can be configured using the environment variable `KC_CACHE_CONFIG_FILE` to override the default.
17 changes: 7 additions & 10 deletions docs/modules/ROOT/pages/how-tos/custom-theme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A theme can provide one or more types to customize different aspects of Keycloak
A theme consists of: HTML templates, images, message bundles, stylesheets, scripts and theme properties.


Follow xref:how-tos/keycloak-tls.adoc[the official guide] on how to create a custom theme
Follow https://www.keycloak.org/docs/17.0/server_development/index.html#_themes[the official guide] on how to create a custom theme

Once you have created your custom theme, you'll need to package it into a container image.

Expand Down Expand Up @@ -60,30 +60,27 @@ parameters:
extraVolumeMounts:
theme-company:
name: themes
mountPath: /opt/jboss/keycloak/themes/company
mountPath: /opt/keycloak/themes/company
subPath: company
readOnly: true
theme-other:
name: themes
readOnly: true
mountPath: /opt/jboss/keycloak/themes/other-theme
mountPath: /opt/keycloak/themes/other-theme
subPath: other-theme
readOnly: true
# Change the theme for the welcome page or default theme with extraEnvs (see also https://hub.docker.com/r/jboss/keycloak/)
# Change the theme for the welcome page or default theme with extraEnvs
# Theme name is the same as the folder in mountPath
extraEnv:
KEYCLOAK_WELCOME_THEME:
KC_SPI_THEME_WELCOME_THEME:
value: 'company'
KEYCLOAK_DEFAULT_THEME:
value: 'company'
----

Note that simply mounting the "themes" volume to `+/opt/jboss/keycloak/themes+` will overwrite the default Keycloak themes.
Note that simply mounting the "themes" volume to `+/opt/keycloak/themes+` will overwrite the default Keycloak themes.

[TIP]
====
See xref:how-tos/keycloak-tls.adoc[the official deploy guide] for a more detailed look into deploying themes.
See https://www.keycloak.org/docs/17.0/server_development/index.html#_themes[the official deploy guide] for a more detailed look into deploying themes.
====
22 changes: 15 additions & 7 deletions docs/modules/ROOT/pages/how-tos/openshift-4.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@ parameters:
ingress:
tls:
termination: reencrypt
extraVolumes:
data:
emptyDir: {}
extraVolumeMounts:
# Required as the OpenShift user can not create the data directory in the keycloak directory UID 1000/GID 0
data:
mountPath: /opt/keycloak/data
helm_values:
podSecurityContext: null
securityContext: null
pgchecker:
dbchecker:
securityContext: null
----

Expand All @@ -31,13 +38,14 @@ If you are using the built-in database provider (by default unless `keycloak.dat
----
parameters:
keycloak:
helm_values:
postgresql:
postgresql_helm_values:
securityContext:
enabled: false
containerSecurityContext:
enabled: false
volumePermissions:
securityContext:
enabled: false
volumePermissions:
securityContext:
runAsUser: auto
runAsUser: auto
shmVolume:
chmod:
enabled: false
Expand Down
Loading

0 comments on commit 4992b60

Please sign in to comment.