From 9bd0b7782f8a83870dbb157fededd78980f61e84 Mon Sep 17 00:00:00 2001 From: Philip Haupt <“der.mad.mob@gmail.com”> Date: Mon, 13 Oct 2025 00:11:57 +0200 Subject: [PATCH] keycloak cnpg --- keycloak/main.yaml | 84 ++++++ keycloak/src/kustomization.yaml | 8 + keycloak/src/values-cnpg.yaml | 503 ++++++++++++++++++++++++++++++++ 3 files changed, 595 insertions(+) create mode 100644 keycloak/src/values-cnpg.yaml diff --git a/keycloak/main.yaml b/keycloak/main.yaml index ff14c30..f51d88e 100644 --- a/keycloak/main.yaml +++ b/keycloak/main.yaml @@ -592,6 +592,51 @@ spec: app.kubernetes.io/instance: keycloak app.kubernetes.io/name: postgresql --- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + labels: + app.kubernetes.io/component: database-ping-test + name: cnpg-keycloak-cluster-ping-test + namespace: keycloak +spec: + template: + metadata: + labels: + app.kubernetes.io/component: database-ping-test + name: cnpg-keycloak-cluster-ping-test + spec: + containers: + - args: + - -c + - apk add postgresql-client && psql "postgresql://$PGUSER:$PGPASS@cnpg-keycloak-cluster-rw.keycloak.svc.cluster.local:5432/${PGDBNAME:-$PGUSER}" + -c 'SELECT 1' + command: + - sh + env: + - name: PGUSER + valueFrom: + secretKeyRef: + key: username + name: cnpg-keycloak-cluster-app + - name: PGPASS + valueFrom: + secretKeyRef: + key: password + name: cnpg-keycloak-cluster-app + - name: PGDBNAME + valueFrom: + secretKeyRef: + key: dbname + name: cnpg-keycloak-cluster-app + optional: true + image: alpine:3.17 + name: alpine + restartPolicy: Never +--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -648,3 +693,42 @@ spec: policyTypes: - Ingress - Egress +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + labels: + app.kubernetes.io/instance: cnpg-keycloak + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: cluster + app.kubernetes.io/part-of: cloudnative-pg + helm.sh/chart: cluster-0.3.1 + name: cnpg-keycloak-cluster + namespace: keycloak +spec: + affinity: + topologyKey: kubernetes.io/hostname + bootstrap: + initdb: + database: keycloak + owner: keycloak + enablePDB: true + enableSuperuserAccess: true + imageName: ghcr.io/cloudnative-pg/postgresql:17 + imagePullPolicy: IfNotPresent + instances: 3 + logLevel: info + monitoring: + disableDefaultQueries: false + enablePodMonitor: false + postgresGID: 26 + postgresUID: 26 + postgresql: null + primaryUpdateMethod: switchover + primaryUpdateStrategy: unsupervised + storage: + size: 10Gi + storageClass: openebs-hostpath + walStorage: + size: 1Gi + storageClass: openebs-hostpath diff --git a/keycloak/src/kustomization.yaml b/keycloak/src/kustomization.yaml index b56aa69..541a297 100644 --- a/keycloak/src/kustomization.yaml +++ b/keycloak/src/kustomization.yaml @@ -10,3 +10,11 @@ helmCharts: includeCRDs: true namespace: keycloak valuesFile: values.yaml + + - name: cluster + repo: https://cloudnative-pg.github.io/charts + version: 0.3.1 + releaseName: cnpg-keycloak + includeCRDs: true + namespace: keycloak + valuesFile: values-cnpg.yaml diff --git a/keycloak/src/values-cnpg.yaml b/keycloak/src/values-cnpg.yaml new file mode 100644 index 0000000..873014a --- /dev/null +++ b/keycloak/src/values-cnpg.yaml @@ -0,0 +1,503 @@ +# -- Override the name of the chart +nameOverride: "" +# -- Override the full name of the chart +fullnameOverride: "" +# -- Override the namespace of the chart +namespaceOverride: "" + +### +# -- Type of the CNPG database. Available types: +# * `postgresql` +# * `postgis` +# * `timescaledb` +type: postgresql + +version: + # -- PostgreSQL major version to use + postgresql: "17" + # -- If using TimescaleDB, specify the version + timescaledb: "2.15" + # -- If using PostGIS, specify the version + postgis: "3.4" + +### +# -- Cluster mode of operation. Available modes: +# * `standalone` - default mode. Creates new or updates an existing CNPG cluster. +# * `replica` - Creates a replica cluster from an existing CNPG cluster. # TODO +# * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup. +mode: standalone + +recovery: + ## + # -- Available recovery methods: + # * `backup` - Recovers a CNPG cluster from a CNPG backup (PITR supported) Needs to be on the same cluster in the same namespace. + # * `object_store` - Recovers a CNPG cluster from a barman object store (PITR supported). + # * `pg_basebackup` - Recovers a CNPG cluster viaa streaming replication protocol. Useful if you want to + # migrate databases to CloudNativePG, even from outside Kubernetes. + # * `import` - Import one or more databases from an existing Postgres cluster. + method: backup + + ## -- Point in time recovery target. Specify one of the following: + pitrTarget: + # -- Time in RFC3339 format + time: "" + + ## + # -- Backup Recovery Method + backupName: "" # Name of the backup to recover from. Required if method is `backup`. + + ## + # -- The original cluster name when used in backups. Also known as serverName. + clusterName: "" + # -- Name of the database used by the application. Default: `app`. + database: app + # -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. + owner: "" + # -- Overrides the provider specific default endpoint. Defaults to: + # S3: https://s3..amazonaws.com" + # Leave empty if using the default S3 endpoint + endpointURL: "" + # -- Specifies a CA bundle to validate a privately signed certificate. + endpointCA: + # -- Creates a secret with the given value if true, otherwise uses an existing secret. + create: false + name: "" + key: "" + value: "" + # -- Overrides the provider specific default path. Defaults to: + # S3: s3:// + # Azure: https://..core.windows.net/ + # Google: gs:// + destinationPath: "" + # -- One of `s3`, `azure` or `google` + provider: s3 + s3: + region: "" + bucket: "" + path: "/" + accessKey: "" + secretKey: "" + # -- Use the role based authentication without providing explicitly the keys + inheritFromIAMRole: false + azure: + path: "/" + connectionString: "" + storageAccount: "" + storageKey: "" + storageSasToken: "" + containerName: "" + serviceName: blob + inheritFromAzureAD: false + google: + path: "/" + bucket: "" + gkeEnvironment: false + applicationCredentials: "" + secret: + # -- Whether to create a secret for the backup credentials + create: true + # -- Name of the backup credentials secret + name: "" + + # See https://cloudnative-pg.io/documentation/1.22/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup + pgBaseBackup: + # -- Name of the database used by the application. Default: `app`. + database: app + # -- Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch + secret: "" + # -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. + owner: "" + source: + host: "" + port: 5432 + username: "" + database: "app" + sslMode: "verify-full" + passwordSecret: + # -- Whether to create a secret for the password + create: false + # -- Name of the secret containing the password + name: "" + # -- The key in the secret containing the password + key: "password" + # -- The password value to use when creating the secret + value: "" + sslKeySecret: + name: "" + key: "" + sslCertSecret: + name: "" + key: "" + sslRootCertSecret: + name: "" + key: "" + + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-Import + import: + # -- One of `microservice` or `monolith.` + # See: https://cloudnative-pg.io/documentation/current/database_import/#how-it-works + type: "microservice" + # -- Databases to import + databases: [] + # -- Roles to import + roles: [] + # -- List of SQL queries to be executed as a superuser in the application database right after is imported. + # To be used with extreme care. Only available in microservice type. + postImportApplicationSQL: [] + # -- When set to true, only the pre-data and post-data sections of pg_restore are invoked, avoiding data import. + schemaOnly: false + # -- List of custom options to pass to the `pg_dump` command. IMPORTANT: Use these options with caution and at your + # own risk, as the operator does not validate their content. Be aware that certain options may conflict with the + # operator's intended functionality or design. + pgDumpExtraOptions: [] + # -- List of custom options to pass to the `pg_restore` command. IMPORTANT: Use these options with caution and at + # your own risk, as the operator does not validate their content. Be aware that certain options may conflict with the + # operator's intended functionality or design. + pgRestoreExtraOptions: [] + source: + host: "" + port: 5432 + username: "" + database: "" + sslMode: "verify-full" + passwordSecret: + # -- Whether to create a secret for the password + create: false + # -- Name of the secret containing the password + name: "" + # -- The key in the secret containing the password + key: "password" + # -- The password value to use when creating the secret + value: "" + sslKeySecret: + name: "" + key: "" + sslCertSecret: + name: "" + key: "" + sslRootCertSecret: + name: "" + key: "" + + +cluster: + # -- Number of instances + instances: 3 + + # -- Name of the container image, supporting both tags (:) and digests for deterministic and repeatable deployments: + # :@sha256: + imageName: "" # Default value depends on type (postgresql/postgis/timescaledb) + + # -- Reference to `ImageCatalog` of `ClusterImageCatalog`, if specified takes precedence over `cluster.imageName` + imageCatalogRef: {} + # kind: ImageCatalog + # name: postgresql + + # -- Image pull policy. One of Always, Never or IfNotPresent. If not defined, it defaults to IfNotPresent. Cannot be updated. + # More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + imagePullPolicy: IfNotPresent + + # -- The list of pull secrets to be used to pull the images. + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-LocalObjectReference + imagePullSecrets: [] + + storage: + size: 10Gi + storageClass: "openebs-hostpath" + + walStorage: + enabled: true + size: 1Gi + storageClass: "openebs-hostpath" + + # -- The UID of the postgres user inside the image, defaults to 26 + postgresUID: -1 + + # -- The GID of the postgres user inside the image, defaults to 26 + postgresGID: -1 + + # -- Customization of service definitions. Please refer to https://cloudnative-pg.io/documentation/1.24/service_management/ + services: {} + + # -- Resources requirements of every generated Pod. + # Please refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for more information. + # We strongly advise you use the same setting for limits and requests so that your cluster pods are given a Guaranteed QoS. + # See: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/ + resources: {} + # limits: + # cpu: 2000m + # memory: 8Gi + # requests: + # cpu: 2000m + # memory: 8Gi + + priorityClassName: "" + + # -- Method to follow to upgrade the primary server during a rolling update procedure, after all replicas have been + # successfully updated. It can be switchover (default) or restart. + primaryUpdateMethod: switchover + + # -- Strategy to follow to upgrade the primary server during a rolling update procedure, after all replicas have been + # successfully updated: it can be automated (unsupervised - default) or manual (supervised) + primaryUpdateStrategy: unsupervised + + # -- The instances' log level, one of the following values: error, warning, info (default), debug, trace + logLevel: "info" + + # -- Affinity/Anti-affinity rules for Pods. + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration + affinity: + topologyKey: kubernetes.io/hostname + + # -- The configuration for the CA and related certificates. + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-CertificatesConfiguration + certificates: {} + + # -- When this option is enabled, the operator will use the SuperuserSecret to update the postgres user password. + # If the secret is not present, the operator will automatically create one. + # When this option is disabled, the operator will ignore the SuperuserSecret content, delete it when automatically created, + # and then blank the password of the postgres user by setting it to NULL. + enableSuperuserAccess: true + superuserSecret: "" + + # -- Allow to disable PDB, mainly useful for upgrade of single-instance clusters or development purposes + # See: https://cloudnative-pg.io/documentation/current/kubernetes_upgrade/#pod-disruption-budgets + enablePDB: true + + # -- This feature enables declarative management of existing roles, as well as the creation of new roles if they are not + # already present in the database. + # See: https://cloudnative-pg.io/documentation/current/declarative_role_management/ + roles: [] + # - name: dante + # ensure: present + # comment: Dante Alighieri + # login: true + # superuser: false + # inRoles: + # - pg_monitor + # - pg_signal_backend + + monitoring: + # -- Whether to enable monitoring + enabled: false + podMonitor: + # -- Whether to enable the PodMonitor + enabled: true + # --The list of relabelings for the PodMonitor. + # Applied to samples before scraping. + relabelings: [] + # -- The list of metric relabelings for the PodMonitor. + # Applied to samples before ingestion. + metricRelabelings: [] + prometheusRule: + # -- Whether to enable the PrometheusRule automated alerts + enabled: true + # -- Exclude specified rules + excludeRules: [] + # - CNPGClusterZoneSpreadWarning + # -- Whether the default queries should be injected. + # Set it to true if you don't want to inject default queries into the cluster. + disableDefaultQueries: false + # -- Custom Prometheus metrics + # Will be stored in the ConfigMap + customQueries: [] + # - name: "pg_cache_hit_ratio" + # query: "SELECT current_database() as datname, sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio FROM pg_statio_user_tables;" + # metrics: + # - datname: + # usage: "LABEL" + # description: "Name of the database" + # - ratio: + # usage: GAUGE + # description: "Cache hit ratio" + # -- The list of secrets containing the custom queries + customQueriesSecret: [] + # - name: custom-queries-secret + # key: custom-queries + + postgresql: + # -- PostgreSQL configuration options (postgresql.conf) + parameters: {} + # max_connections: 300 + # -- Quorum-based Synchronous Replication + synchronous: {} + # method: any + # number: 1 + # -- PostgreSQL Host Based Authentication rules (lines to be appended to the pg_hba.conf file) + pg_hba: [] + # - host all all 10.244.0.0/16 md5 + # -- PostgreSQL User Name Maps rules (lines to be appended to the pg_ident.conf file) + pg_ident: [] + # - mymap /^(.*)@mydomain\.com$ \1 + # -- Lists of shared preload libraries to add to the default ones + shared_preload_libraries: [] + # - pgaudit + # -- PostgreSQL LDAP configuration (see https://cloudnative-pg.io/documentation/current/postgresql_conf/#ldap-configuration) + ldap: {} + # https://cloudnative-pg.io/documentation/1.24/postgresql_conf/#ldap-configuration + # server: 'openldap.default.svc.cluster.local' + # bindSearchAuth: + # baseDN: 'ou=org,dc=example,dc=com' + # bindDN: 'cn=admin,dc=example,dc=com' + # bindPassword: + # name: 'ldapBindPassword' + # key: 'data' + # searchAttribute: 'uid' + + + # -- BootstrapInitDB is the configuration of the bootstrap process when initdb is used. + # See: https://cloudnative-pg.io/documentation/current/bootstrap/ + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-bootstrapinitdb + initdb: + database: keycloak + owner: keycloak # Defaults to the database name + # secret: + # name: "" # Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch + # options: [] + # encoding: UTF8 + # postInitSQL: + # - CREATE EXTENSION IF NOT EXISTS vector; + # postInitApplicationSQL: [] + # postInitTemplateSQL: [] + + # -- Configure the metadata of the generated service account + serviceAccountTemplate: {} + + additionalLabels: {} + annotations: {} + + +backups: + # -- You need to configure backups manually, so backups are disabled by default. + enabled: false + + # -- Overrides the provider specific default endpoint. Defaults to: + # S3: https://s3..amazonaws.com" + endpointURL: "" # Leave empty if using the default S3 endpoint + # -- Specifies a CA bundle to validate a privately signed certificate. + endpointCA: + # -- Creates a secret with the given value if true, otherwise uses an existing secret. + create: false + name: "" + key: "" + value: "" + + # -- Overrides the provider specific default path. Defaults to: + # S3: s3:// + # Azure: https://..core.windows.net/ + # Google: gs:// + destinationPath: "" + # -- One of `s3`, `azure` or `google` + provider: s3 + s3: + region: "" + bucket: "" + path: "/" + accessKey: "" + secretKey: "" + # -- Use the role based authentication without providing explicitly the keys + inheritFromIAMRole: false + azure: + path: "/" + connectionString: "" + storageAccount: "" + storageKey: "" + storageSasToken: "" + containerName: "" + serviceName: blob + inheritFromAzureAD: false + google: + path: "/" + bucket: "" + gkeEnvironment: false + applicationCredentials: "" + secret: + # -- Whether to create a secret for the backup credentials + create: true + # -- Name of the backup credentials secret + name: "" + + wal: + # -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: gzip + # -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: AES256 + # -- Number of WAL files to be archived or restored in parallel. + maxParallel: 1 + data: + # -- Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: gzip + # -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: AES256 + # -- Number of data files to be archived or restored in parallel. + jobs: 2 + + scheduledBackups: + - + # -- Scheduled backup name + name: daily-backup + # -- Schedule in cron format + schedule: "0 0 0 * * *" + # -- Backup owner reference + backupOwnerReference: self + # -- Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` + method: barmanObjectStore + + # -- Retention policy for backups + retentionPolicy: "30d" + +imageCatalog: + # -- Whether to provision an image catalog. If imageCatalog.images is empty this option will be ignored. + create: true + # -- List of images to be provisioned in an image catalog. + images: [] + # - image: ghcr.io/your_repo/your_image:your_tag + # major: 16 + +# -- List of PgBouncer poolers +poolers: [] + # - + # # -- Pooler name + # name: rw + # # -- PgBouncer type of service to forward traffic to. + # type: rw + # # -- PgBouncer pooling mode + # poolMode: transaction + # # -- Number of PgBouncer instances + # instances: 3 + # # -- PgBouncer configuration parameters + # parameters: + # max_client_conn: "1000" + # default_pool_size: "25" + # monitoring: + # # -- Whether to enable monitoring + # enabled: false + # podMonitor: + # # -- Whether to enable the PodMonitor + # enabled: true + # # -- Custom PgBouncer deployment template. + # # Use to override image, specify resources, etc. + # template: {} + # - + # # -- Pooler name + # name: ro + # # -- PgBouncer type of service to forward traffic to. + # type: ro + # # -- PgBouncer pooling mode + # poolMode: transaction + # # -- Number of PgBouncer instances + # instances: 3 + # # -- PgBouncer configuration parameters + # parameters: + # max_client_conn: "1000" + # default_pool_size: "25" + # monitoring: + # # -- Whether to enable monitoring + # enabled: false + # podMonitor: + # # -- Whether to enable the PodMonitor + # enabled: true + # # -- Custom PgBouncer deployment template. + # # Use to override image, specify resources, etc. + # template: {} +