diff --git a/addons/index.yaml b/addons/index.yaml index 2bfb50a..c5e13ea 100644 --- a/addons/index.yaml +++ b/addons/index.yaml @@ -49,6 +49,8 @@ entries: description: "PostgreSQL is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance." - version: 17 description: "PostgreSQL is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance." + - version: 18 + description: "PostgreSQL is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance." seaweedfs: - version: 3 description: "SeaweedFS is a fast distributed storage system for blobs, objects, files, and data lake, for billions of files." diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/Chart.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/Chart.yaml new file mode 100644 index 0000000..d3b5cd0 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/Chart.yaml @@ -0,0 +1,28 @@ +annotations: + category: Database +apiVersion: v2 +appVersion: "18" +dependencies: + - name: common + repository: oci://registry.drycc.cc/charts + version: ~1.1.1 +description: PostgreSQL (Postgres) is an open source object-relational database known for reliability and data integrity. ACID-compliant, it supports foreign keys, joins, views, triggers and stored procedures. +engine: gotpl +home: https://github.com/drycc/charts/tree/master/drycc/postgresql +icon: https://drycc.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png +keywords: + - postgresql + - postgres + - database + - sql + - replication + - cluster + - patroni +maintainers: + - email: zhang.eamon@hotmail.com + name: zhangeamon +name: postgresql +sources: + - https://github.com/drycc-addons/ + - https://www.postgresql.org/ +version: "18.6" diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/NOTES.txt b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/NOTES.txt new file mode 100644 index 0000000..22a4f2d --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/NOTES.txt @@ -0,0 +1,25 @@ +Patroni can be accessed via port 5432 on the following DNS name from within your cluster: +{{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +To get your password for superuser run: + + # superuser password + PGPASSWORD_SUPERUSER=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "patroni.fullname" . }} -o jsonpath="{.data.password-superuser}" | base64 --decode) + + # admin password + PGPASSWORD_ADMIN=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "patroni.fullname" . }} -o jsonpath="{.data.password-admin}" | base64 --decode) + +To connect to your database: + +1. Run a postgres pod and connect using the psql cli: + # login as superuser + kubectl run -i --tty --rm psql --image=postgres \ + --env "PGPASSWORD=$PGPASSWORD_SUPERUSER" \ + --command -- psql -U postgres \ + -h {{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres + + # login as admin + kubectl run -i -tty --rm psql --image=postgres \ + --env "PGPASSWORD=$PGPASSWORD_ADMIN" \ + --command -- psql -U admin \ + -h {{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/_helpers.tpl b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/_helpers.tpl new file mode 100644 index 0000000..d587663 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/_helpers.tpl @@ -0,0 +1,219 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "patroni.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "patroni.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "patroni.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use. +*/}} +{{- define "patroni.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "patroni.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return true if a cronjob object should be created for Postgresql HA patroni ## TODO feature +*/}} +{{- define "patroni.createCronJob" -}} +{{- if and .Values.backup.enabled }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a cronjob object should be created for Postgresql HA patroni ## TODO feature +*/}} +{{- define "patroni.createLogicalBackupCronJob" -}} +{{- if and .Values.logicalbackup.enabled }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for Postgresql HA patroni +*/}} +{{- define "patroni.createConfigmap" -}} +{{- if and .Values.preInitScript }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Create patroni envs. +*/}} +{{- define "patroni.envs" }} +{{- if .Values.kubernetes.configmaps.enable }} +- name: KUBERNETES_USE_CONFIGMAPS + value: "true" +{{- end }} +{{- if .Values.kubernetes.endpoints.enable }} +- name: PATRONI_KUBERNETES_USE_ENDPOINTS + value: 'true' +{{- end }} +- name: PATRONI_KUBERNETES_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP +- name: PATRONI_KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace +- name: PATRONI_KUBERNETES_BYPASS_API_SERVICE + value: 'true' +- name: PATRONI_KUBERNETES_LABELS + value: '{application: {{ template "patroni.fullname" . }},release: {{ .Release.Name }},cluster-name: {{ template "patroni.fullname" . }}}' +- name: PATRONI_SUPERUSER_USERNAME + value: postgres +- name: PATRONI_SUPERUSER_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: password-superuser +- name: PATRONI_REPLICATION_USERNAME + value: standby +- name: PATRONI_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: password-replication +- name: PATRONI_REWIND_USERNAME + value: rewinder +- name: PATRONI_REWIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: password-rewind +- name: ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: admin-user +- name: ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: admin-password +- name: PATRONI_SCOPE + value: {{ template "patroni.fullname" . }} +- name: PATRONI_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name +- name: PATRONI_POSTGRESQL_DATA_DIR + value: "{{ .Values.persistentVolume.mountPath }}/data" +- name: PGDATA + value: "{{ .Values.persistentVolume.mountPath }}/data" +- name: PATRONI_POSTGRESQL_PGPASS + value: /tmp/pgpass +- name: PATRONI_POSTGRESQL_LISTEN + value: '0.0.0.0:5432' +- name: PATRONI_RESTAPI_LISTEN + value: '0.0.0.0:8008' +{{- end -}} + +{{/* +Return true if a configmap object should be created for PG backup. +*/}} +{{- define "backup.createConfigmap" -}} +{{- if and .Values.backup.enabled }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Generate random password +*/}} + +{{/* +Get the super user password ; +*/}} +{{- define "credentials.superuserValue" }} +{{- if .Values.credentials.superuser }} + {{- .Values.credentials.superuser -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "password-superuser") -}} +{{- end -}} +{{- end }} + +{{/* +Get the rewind password ; +*/}} +{{- define "credentials.rewindValue" }} +{{- if .Values.credentials.rewind }} + {{- .Values.credentials.rewind -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "password-rewind") -}} +{{- end -}} +{{- end }} + +{{/* +Get the replication password ; +*/}} +{{- define "credentials.replicationValue" }} +{{- if .Values.credentials.replication }} + {{- .Values.credentials.replication -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "password-replication") -}} +{{- end -}} +{{- end }} + +{{/* +Get the administrator password ; +*/}} +{{- define "adminRole.passwordValue" }} +{{- if .Values.adminRole.password }} + {{- .Values.adminRole.password -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "admin-password") -}} +{{- end -}} +{{- end }} + +{{/* +Returns the available value for certain key in an existing secret (if it exists), +otherwise it generates a random value. +*/}} +{{- define "getValueFromSecret" }} +{{- $len := (default 16 .Length) | int -}} +{{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} +{{- if $obj }} +{{- index $obj .Key | b64dec -}} +{{- else -}} +{{- randAlphaNum $len -}} +{{- end -}} +{{- end }} + diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-backup.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-backup.yaml new file mode 100644 index 0000000..fdc6219 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-backup.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-backup + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + backup.env: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.backupEnv "context" $ ) | nindent 4 }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-logicalbackup .yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-logicalbackup .yaml new file mode 100644 index 0000000..8de6110 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-logicalbackup .yaml @@ -0,0 +1,19 @@ +{{- if (include "patroni.createLogicalBackupCronJob" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-logicalbackup + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + logicalbackup.sh: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.logicalbackupScript "context" $ ) | nindent 4 }} + +{{- end }} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-patroni.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-patroni.yaml new file mode 100644 index 0000000..ad4b584 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-patroni.yaml @@ -0,0 +1,20 @@ +{{- if (include "patroni.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-patroni + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + pre_init.sh: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.preInitScript "context" $ ) | nindent 4 }} + post_init.sh: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.postInitScript "context" $ ) | nindent 4 }} +{{- end -}} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-postgresql.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-postgresql.yaml new file mode 100644 index 0000000..8aba698 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cm-postgresql.yaml @@ -0,0 +1,18 @@ +{{- if (include "patroni.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-postgresql + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + custom_conf.conf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.postgresql.config "context" $ ) | nindent 4 }} +{{- end -}} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cronjob.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cronjob.yaml new file mode 100644 index 0000000..495dfa7 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/cronjob.yaml @@ -0,0 +1,43 @@ +{{- /* +Copyright Drycc Community. +SPDX-License-Identifier: APACHE-2.0 +*/}} +{{- if (include "patroni.createCronJob" .) }} +apiVersion: {{ include "common.capabilities.cronjob.apiVersion" . }} +kind: CronJob +metadata: + name: {{ include "patroni.fullname" . }}-backup + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + application: {{ template "patroni.fullname" . }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + +spec: + schedule: "{{ .Values.backup.scheduleCronJob }}" + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: {{ .Chart.Name }}-backup + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + command: + - /usr/bin/env + - bash + - -c + - | + curl "http://${REPLHOST}:9000/pg_backup" + env: + - name: REPLHOST + value: {{ include "patroni.fullname" . }}-repl +{{- end -}} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/logicalbackup-cronjob.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/logicalbackup-cronjob.yaml new file mode 100644 index 0000000..071b9bd --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/logicalbackup-cronjob.yaml @@ -0,0 +1,69 @@ +{{- /* +Copyright Drycc Community. +SPDX-License-Identifier: APACHE-2.0 +*/}} +{{- if (include "patroni.createLogicalBackupCronJob" .) }} +apiVersion: {{ include "common.capabilities.cronjob.apiVersion" . }} +kind: CronJob +metadata: + name: {{ include "patroni.fullname" . }}-logicalbackup + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + application: {{ template "patroni.fullname" . }} + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + +spec: + schedule: "{{ .Values.logicalbackup.scheduleCronJob }}" + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: {{ .Chart.Name }}-logicalbackup + image: "{{ .Values.logicalbackupImages.repository }}:{{ .Values.logicalbackupImages.tag }}" + imagePullPolicy: {{ .Values.logicalbackupImages.pullPolicy | quote }} + command: + - /usr/bin/env + - bash + - -c + - | + sh /opt/drycc/logicalbackup/logicalbackup.sh + env: + - name: PGHOST + value: {{ include "patroni.fullname" . }}-repl + - name: PGPORT + value: "5432" + - name: PGUSER + value: postgres + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: password-superuser + - name: MINIO_BUCKET + value: {{ .Values.logicalbackup.minio.bucket }} + - name: MINIO_HOST + value: {{ .Values.logicalbackup.minio.endpoint }} + - name: MINIO_ACCESS_KEY + value: {{ .Values.logicalbackup.minio.access_key }} + - name: MINIO_SECRET_KEY + value: {{ .Values.logicalbackup.minio.secret_key }} + + volumeMounts: + - mountPath: "/opt/drycc/logicalbackup/" + name: logicalbackup-config + + volumes: + - name: logicalbackup-config + configMap: + name: {{ template "common.names.fullname" . }}-logicalbackup +{{- end -}} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/networkpolicy.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/networkpolicy.yaml new file mode 100644 index 0000000..19ff228 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/networkpolicy.yaml @@ -0,0 +1,54 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: patroni + cluster-name: {{ template "patroni.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + {{- if eq .Values.service.type "ClusterIP" }} + ingress: + # Allow inbound connections + - ports: + - port: 5432 + - port: 9000 + - port: 80 + - port: 8008 + {{- if and .Values.metrics.enabled }} + - port: {{ .Values.metrics.containerPort }} + {{ end }} + {{- if or .Values.networkPolicy.allowCurrentNamespace .Values.networkPolicy.allowNamespaces }} + from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: backup + {{- if .Values.networkPolicy.allowCurrentNamespace }} + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Release.Namespace }} + {{- end }} + {{- range $namespace := .Values.networkPolicy.allowNamespaces }} + {{- if $namespace }} + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ $namespace }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if eq .Values.service.type "LoadBalancer" }} + ingress: + - {} + {{- end }} +{{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/role.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/role.yaml new file mode 100644 index 0000000..8dec530 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/role.yaml @@ -0,0 +1,49 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "patroni.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: + - create + - get + - list + - patch + - update + - watch + # delete is required only for 'patronictl remove' + - delete +- apiGroups: [""] + resources: ["services"] + verbs: + - create +- apiGroups: [""] + resources: ["endpoints"] + verbs: + - create + - get + - patch + - update + # the following three privileges are necessary only when using endpoints + - list + - watch + # delete is required only for for 'patronictl remove' + - delete + - deletecollection +- apiGroups: [""] + resources: ["pods"] + verbs: + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/rolebinding.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/rolebinding.yaml new file mode 100644 index 0000000..5e15948 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "patroni.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ template "patroni.serviceAccountName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "patroni.fullname" . }} +{{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/sec.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/sec.yaml new file mode 100644 index 0000000..c2e1305 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/sec.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "patroni.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} +type: Opaque +data: + password-superuser: {{ include "credentials.superuserValue" . | b64enc | quote }} + password-rewind: {{ include "credentials.rewindValue" . | b64enc | quote }} + password-replication: {{ include "credentials.replicationValue" . | b64enc | quote }} + admin-user: {{ .Values.adminRole.username | b64enc | quote }} + admin-password: {{ include "adminRole.passwordValue" . | b64enc | quote }} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/serviceaccount.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/serviceaccount.yaml new file mode 100644 index 0000000..e1b2ebf --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "patroni.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/statefulset.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/statefulset.yaml new file mode 100644 index 0000000..3f1efb1 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/statefulset.yaml @@ -0,0 +1,273 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "patroni.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} +spec: + serviceName: {{ template "patroni.fullname" . }} + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} + template: + metadata: + name: {{ template "patroni.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} + spec: + {{- if .Values.patroni.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.patroni.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.patroni.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.patroni.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.patroni.nodeAffinityPreset.type "key" .Values.patroni.nodeAffinityPreset.key "values" .Values.patroni.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.patroni.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.patroni.nodeSelector "context" $) | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "patroni.serviceAccountName" . }} + # securityContext: + # runAsUser: postgres + # fsGroup: postgres + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + # securityContext: + # runAsUser: postgres + # fsGroup: postgres + env: + {{- include "patroni.envs" . | indent 8 }} + {{- if .Values.env }} + {{- range $key, $val := .Values.env }} + - name: {{ $key | quote | upper }} + value: {{ $val | quote }} + {{- end }} + {{- end }} + readinessProbe: + httpGet: + scheme: HTTP + path: /readiness + port: 8008 + initialDelaySeconds: 3 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /liveness + port: 8008 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /usr/bin/env + - bash + - -c + - | + # switch leader pod if the current pod is the leader + if curl --fail http://localhost:8008/read-write; then + init-stack patronictl switchover --force + fi + ports: + - containerPort: 8008 + protocol: TCP + - containerPort: 5432 + protocol: TCP + volumeMounts: + - name: storage-volume + mountPath: "{{ .Values.persistentVolume.mountPath }}" + - mountPath: "/opt/drycc/postgresql/scripts/" + name: patroni-config + - mountPath: "/opt/drycc/postgresql/config/" + name: postgresql-config + # readOnly: true + - mountPath: "/opt/drycc/postgresql/backup/" + name: backup-config + - name: dshm + mountPath: /dev/shm + # readOnly: true + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: "{{ .Values.metrics.image.repository }}:{{ .Values.metrics.image.tag }}" + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.metrics.customMetrics }} + args: ["--extend.query-path", "/conf/custom-metrics.yaml"] + {{- end }} + env: + - name: DATA_SOURCE_NAME + value: {{ printf "postgresql://tea_mon:password@127.0.0.1:5432/postgres?sslmode=disable" }} + ports: + - name: http-metrics + containerPort: {{ .Values.metrics.containerPort }} + startupProbe: + initialDelaySeconds: 10 + tcpSocket: + port: http-metrics + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 15 + successThreshold: 1 + livenessProbe: + initialDelaySeconds: 5 + httpGet: + path: / + port: http-metrics + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + readinessProbe: + initialDelaySeconds: 5 + httpGet: + path: / + port: http-metrics + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} + {{- end }} + - name: {{ .Chart.Name }}-backup + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + # securityContext: + # runAsUser: postgres + # fsGroup: postgres + command: + - /usr/bin/env + - bash + - -c + - | + python3 /opt/drycc/postgresql/pgbackup.py 0.0.0.0 9000 + env: + - name: PGHOST + value: localhost + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ template "patroni.fullname" . }} + key: password-superuser + - name: PGUSER + value: postgres + - name: PGDATABASE + value: postgres + - name: PGPORT + value: "5432" + - name: PGDATA + value: "{{ .Values.persistentVolume.mountPath }}/data" + ports: + - containerPort: 9000 + volumeMounts: + - name: storage-volume + mountPath: "{{ .Values.persistentVolume.mountPath }}" + - mountPath: "/opt/drycc/postgresql/backup/" + name: backup-config + + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ .Values.affinity | toYaml | indent 8 }} + {{- else if .Values.affinityTemplate }} + affinity: +{{ tpl .Values.affinityTemplate . | indent 8 }} + {{- end }} + volumes: + - name: patroni-config + configMap: + name: {{ template "common.names.fullname" . }}-patroni + - name: postgresql-config + configMap: + name: {{ template "common.names.fullname" . }}-postgresql + - name: backup-config + configMap: + name: {{ template "common.names.fullname" . }}-backup + {{- if not .Values.persistentVolume.enabled }} + - name: storage-volume + emptyDir: {} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + {{- if .Values.shmVolume.sizeLimit }} + sizeLimit: {{ .Values.shmVolume.sizeLimit }} + {{- end }} + {{- end }} + + {{- if .Values.persistentVolumeClaimRetentionPolicy.enabled }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.persistentVolumeClaimRetentionPolicy.whenDeleted }} + whenScaled: {{ .Values.persistentVolumeClaimRetentionPolicy.whenScaled }} + {{- end }} + {{- if .Values.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: storage-volume + annotations: + {{- if .Values.persistentVolume.annotations }} +{{ toYaml .Values.persistentVolume.annotations | indent 10 }} + {{- end }} + labels: + application: {{ template "patroni.fullname" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + spec: + accessModes: +{{ toYaml .Values.persistentVolume.accessModes | indent 8 }} + resources: + requests: + storage: "{{ .Values.persistentVolume.size }}" + {{- if .Values.persistentVolume.storageClass }} + {{- if (eq "-" .Values.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.persistentVolume.storageClass }}" + {{- end }} + {{- end }} + {{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-config.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-config.yaml new file mode 100644 index 0000000..5f7b0f6 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-config.yaml @@ -0,0 +1,11 @@ +# headless service to avoid deletion of patronidemo-config endpoint +apiVersion: v1 +kind: Service +metadata: + name: {{ template "patroni.fullname" . }}-config + labels: + application: {{ template "patroni.fullname" . }} + release: {{ .Release.Name }} + cluster-name: {{ template "patroni.fullname" . }} +spec: + clusterIP: None diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-master.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-master.yaml new file mode 100644 index 0000000..609ed5b --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-master.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "patroni.fullname" . }}-master + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} + role: primary +spec: + type: {{ .Values.service.type }} + selector: + application: {{ template "patroni.fullname" . }} + cluster-name: {{ template "patroni.fullname" . }} + role: primary + ports: + - name: postgresql + port: 5432 + targetPort: 5432 + protocol: TCP \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-metrics.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-metrics.yaml new file mode 100644 index 0000000..862c6a0 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-metrics.yaml @@ -0,0 +1,32 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "patroni.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: patroni + app.kubernetes.io/component: metrics + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + sessionAffinity: {{ .Values.metrics.service.sessionAffinity }} + {{- if .Values.metrics.service.clusterIP }} + clusterIP: {{ .Values.metrics.service.clusterIP }} + {{- end }} + ports: + - name: http-metrics + port: {{ .Values.metrics.service.ports.metrics }} + targetPort: http-metrics + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: patroni +{{- end }} diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-relp.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-relp.yaml new file mode 100644 index 0000000..252882b --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc-relp.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "patroni.fullname" . }}-repl + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} + role: replica +spec: + type: {{ .Values.service.type }} + selector: + application: {{ template "patroni.fullname" . }} + cluster-name: {{ template "patroni.fullname" . }} + role: replica + ports: + - name: postgresql + port: 5432 + targetPort: 5432 + - name: pgbackup + port: 9000 + targetPort: 9000 \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc.yaml new file mode 100644 index 0000000..ac0c2c4 --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/templates/svc.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "patroni.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: patroni + application: {{ template "patroni.fullname" . }} + chart: {{ template "patroni.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + cluster-name: {{ template "patroni.fullname" . }} +spec: + type: ClusterIP + ports: + - port: 5432 + targetPort: 5432 + protocol: TCP \ No newline at end of file diff --git a/addons/postgresql-cluster/18/chart/postgresql-cluster-18/values.yaml b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/values.yaml new file mode 100644 index 0000000..1ecfd7c --- /dev/null +++ b/addons/postgresql-cluster/18/chart/postgresql-cluster-18/values.yaml @@ -0,0 +1,440 @@ +replicaCount: 3 +diagnosticMode: + enable: false + +service: + type: ClusterIP + +image: + # Image was built from registry.drycc.cc/drycc-addons/patroni:3.2 + # https://github.com/zalando/spilo/tree/master/postgres-appliance + repository: registry.drycc.cc/drycc-addons/postgresql-patroni + tag: 18 + # IfNotPresent , Always + pullPolicy: "IfNotPresent" + +logicalbackupImages: + repository: registry.drycc.cc/drycc-addons/postgresql-logicalbackup + tag: 18 + # IfNotPresent , Always + pullPolicy: "IfNotPresent" + +# Credentials used by Patroni , passwd +# https://github.com/zalando/patroni/blob/master/docs/SETTINGS.rst#postgresql +# https://github.com/zalando/spilo/blob/master/ENVIRONMENT.rst +credentials: + superuser: "" + rewind: "" + replication: "" + +adminRole: + username: administrator + password: "" + +# Distribution Configuration stores +# Please note that only one of the following stores should be enabled. +kubernetes: + endpoints: + enable: true + configmaps: + enable: false + +# Extra custom environment variables. +env: {} + +# +#custom patroni.yaml used by patroni boot +# configuration: {} +preInitScript: | + mkdir -p /home/postgres/pgdata/log + ln -sf /dev/stdout "/home/postgres/pgdata/log/postgresql.csv" + cat > /opt/drycc/postgresql/patroni.yml <<__EOF__ + log: + level: INFO + restapi: + listen: 0.0.0.0:8008 + connect_address: 0.0.0.0:8008 + bootstrap: + dcs: + ttl: 30 + loop_wait: 10 + retry_timeout: 10 + maximum_lag_on_failover: 1048576 + failsafe_mode: true + postgresql: + use_pg_rewind: true + use_slots: true + pg_hba: + - local all all peer + - host all tea_mon 127.0.0.1/32 trust + - host all all 0.0.0.0/0 scram-sha-256 + - host replication ${PATRONI_REPLICATION_USERNAME} 0.0.0.0/0 scram-sha-256 + - host replication postgres 0.0.0.0/0 scram-sha-256 + custom_conf: '/opt/drycc/postgresql/config/custom_conf.conf' + parameters: + max_connections: {{ .Values.patroni.pgParameters.max_connections }} + max_worker_processes: {{ .Values.patroni.pgParameters.max_worker_processes }} + max_parallel_workers: {{ .Values.patroni.pgParameters.max_parallel_workers }} + wal_level: logical + hot_standby: "on" + max_wal_senders: 10 + max_replication_slots: 10 + hot_standby_feedback: on + max_prepared_transactions: 0 + max_locks_per_transaction: 64 + wal_log_hints: "on" + wal_keep_size: "1 GB" + max_slot_wal_keep_size: {{ .Values.patroni.pgParameters.max_slot_wal_keep_size | quote }} + track_commit_timestamp: "off" + archive_mode: "on" + archive_timeout: 300s + archive_command: sh /opt/drycc/postgresql/walbackup.sh %p + # timescaledb.license: 'timescale' + shared_preload_libraries: 'auto_explain,pg_stat_statements,timescaledb' + log_destination: 'csvlog' + log_filename: postgresql.log + logging_collector: on + log_directory: /home/postgres/pgdata/log + log_min_messages: 'info' + log_min_duration_statement: 1000 + log_lock_waits: on + log_statement: 'ddl' + {{ if .Values.postgresql.timezone -}} timezone: {{ .Values.postgresql.timezone }} {{- end }} + initdb: + - auth-host: scram-sha-256 + - auth-local: trust + - encoding: UTF8 + - locale: en_US.UTF-8 + - data-checksums + post_bootstrap: sh /opt/drycc/postgresql/scripts/post_init.sh + restapi: + connect_address: '${PATRONI_KUBERNETES_POD_IP}:8008' + postgresql: + connect_address: '${PATRONI_KUBERNETES_POD_IP}:5432' + authentication: + superuser: + username: postgres + password: '${PATRONI_SUPERUSER_PASSWORD}' + replication: + username: standby + password: '${PATRONI_REPLICATION_PASSWORD}' + rewind: # Has no effect on postgres 10 and lower + username: rewinder + password: '${PATRONI_REWIND_PASSWORD}' + watchdog: + mode: off + __EOF__ + +postInitScript: | + #!/bin/bash + set -Eeu + # Create monitor user + psql -w -c "CREATE USER tea_mon ;GRANT pg_monitor TO tea_mon ;create extension pg_stat_statements;create extension pg_buffercache ;" + # Create admin user + if [[( -n "$ADMIN_USER") && ( -n "$ADMIN_PASSWORD")]]; then + + echo "Creating user ${ADMIN_USER}" + psql -w -c "CREATE USER ${ADMIN_USER} WITH SUPERUSER CREATEDB CREATEROLE CONNECTION LIMIT 10 LOGIN ENCRYPTED PASSWORD '${ADMIN_PASSWORD}'" + + else + echo "Skipping create admin user" + fi + psql -w -c "CHECKPOINT;CHECKPOINT;" + +backupEnv: | + #!/bin/bash + export USE_WALG={{ .Values.backup.enabled | quote }} + export BACKUP_NUM_TO_RETAIN={{ .Values.backup.retainBackups | quote}} + export WALG_BACKUP_THRESHOLD_MEGABYTES={{ .Values.backup.backupThresholdMegabytes | quote }} + export WALE_BACKUP_THRESHOLD_PERCENTAGE={{ .Values.backup.backupThresholdPercentage | quote }} + export AWS_ACCESS_KEY_ID={{ .Values.backup.s3.awsAccessKeyID | quote }} + export AWS_SECRET_ACCESS_KEY={{ .Values.backup.s3.awsSecretAccessKey | quote }} + export WALG_S3_PREFIX={{ .Values.backup.s3.walGS3Prefix | quote }} + export AWS_ENDPOINT={{ .Values.backup.s3.awsEndpoint | quote }} + export AWS_S3_FORCE_PATH_STYLE={{ .Values.backup.s3.awsS3ForcePathStyle | quote }} + export AWS_REGION={{ .Values.backup.s3.awsRegion | quote }} + +logicalbackupScript: | + #!/bin/bash + + # PostgreSQL 设置 + # POSTGRES_USER="postgres" + # POSTGRES_HOST="127.0.0.1" + + # MinIO 设置 + # MINIO_BUCKET="pgbackup" + # MINIO_HOST="http://localhost:9000" + # MINIO_ACCESS_KEY="admin123" + # MINIO_SECRET_KEY="admin123" + + # 设置 MinIO 客户端别名 + mc alias set myminio $MINIO_HOST $MINIO_ACCESS_KEY $MINIO_SECRET_KEY + + # 创建以当前日期和时间命名的备份目录 + BACKUP_DIR="$(date +%Y%m%d%H%M)" + MINIO_PATH="myminio/$MINIO_BUCKET/$BACKUP_DIR" + + # 备份全局对象 + echo "Backing up global objects to $MINIO_PATH/roles_globals.sql.gz" + pg_dumpall -g -U "$POSTGRES_USER" -h "$POSTGRES_HOST" | pigz | mc pipe "$MINIO_PATH/roles_globals.sql.gz" + + # 获取所有非模板数据库的列表 + DATABASES=$(psql -U "$POSTGRES_USER" -h "$POSTGRES_HOST" -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;") + + # 为每个数据库执行备份 + for DB in $DATABASES; do + echo "Backing up $DB to $MINIO_PATH/$DB.sql.gz" + pg_dump -U "$POSTGRES_USER" -h "$POSTGRES_HOST" "$DB" | pigz | mc pipe "$MINIO_PATH/$DB.sql.gz" + done + + echo "Backup process completed!" + +postgresql: + timezone: + config: |- + log_min_duration_statement = 1000 + max_wal_size = 4GB + min_wal_size = 4GB + max_wal_senders = 10 + max_replication_slots = 10 + max_prepared_transactions = 0 + max_locks_per_transaction = 64 + +patroni: + pgParameters: + max_worker_processes: 64 + max_parallel_workers: 32 + max_connections: 2000 + max_slot_wal_keep_size: "2 GB" + + ## @param patroni.podAnnotations Additional pod annotations for Postgresql patroni pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param patroni.podAffinityPreset Postgresql patroni pod affinity preset. Ignored if `patroni.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param patroni.podAntiAffinityPreset Postgresql patroni pod anti-affinity preset. Ignored if `patroni.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Postgresql Primary node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param patroni.nodeAffinityPreset.type Postgresql patroni node affinity preset type. Ignored if `patroni.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param patroni.nodeAffinityPreset.key Postgresql patroni node label key to match Ignored if `patroni.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param patroni.nodeAffinityPreset.values Postgresql patroni node label values to match. Ignored if `patroni.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param patroni.affinity Affinity for Postgresql patroni pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param patroni.nodeSelector Node labels for Postgresql patroni pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + +## Postgresql Prometheus exporter parameters +## +metrics: + enabled: true + image: + repository: registry.drycc.cc/drycc-addons/postgres-exporter + tag: "0" + # IfNotPresent , Always + pullPolicy: "IfNotPresent" + ## @param metrics.customMetrics Define additional custom metrics + ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file + ## customMetrics: + ## pg_database:.... + ## query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size_bytes FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" + ## metrics: + ## - name: + ## usage: "LABEL" + ## description: "Name of the database" + ## - size_bytes: + ## usage: "GAUGE" + ## description: "Size of the database in bytes" + ## + service: + ports: + metrics: 9187 + clusterIP: "" + ## @param metrics.service.sessionAffinity Control where client requests go, to the same pod or round-robin + ## Values: ClientIP or None + ## ref: https://kubernetes.io/docs/user-guide/services/ + ## + sessionAffinity: None + ## @param metrics.service.annotations [object] Annotations for Prometheus to auto-discover the metrics endpoint + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metrics.service.ports.metrics }}" + + customMetrics: {} + containerPort: 9187 + containerSecurityContext: + enabled: false + runAsUser: 1001 + runAsNonRoot: true + customLivenessProbe: {} + customReadinessProbe: + enabled: true + resources: + limits: + cpu: 100m + hugepages-2Mi: 20Mi + memory: 512Mi + requests: + cpu: 100m + memory: 512Mi + +logicalbackup: + enabled: false + scheduleCronJob: "22 0 * * 0" + minio: + used: true + buckect: "s3://xx" + access_key: "" + secret_key: "" + endpoint: "http://xxxx:9000" + awsS3ForcePathStyle: "true" + awsRegion: dx-1 + +backup: + # Specifies whether Wal-G should be enabled + enabled: false + # Cron schedule for doing base backups + scheduleCronJob: "22 0 * * 0" + # Amount of base backups to retain + retainBackups: 2 + # Name of the secret that holds the credentials to the bucket + kubernetesSecret: + # Maximum size of the WAL segments accumulated after the base backup to + # consider WAL-G restore instead of pg_basebackup + backupThresholdMegabytes: 1024 + # Maximum ratio (in percents) of the accumulated WAL files to the base backup + # to consider WAL-G restore instead of pg_basebackup + backupThresholdPercentage: 30 + s3: + used: true + awsAccessKeyID: "" + awsSecretAccessKey: "" + walGS3Prefix: "s3://xx" + awsEndpoint: "http://xxxx:9000" + awsS3ForcePathStyle: "true" + awsRegion: dx-1 + +logicalBackup: + enabled: false + +## persistentVolumeClaimRetentionPolicy +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention +## @param persistentVolumeClaimRetentionPolicy.enabled Controls if and how PVCs are deleted during the lifecycle of a StatefulSet +## @param persistentVolumeClaimRetentionPolicy.whenScaled Volume retention behavior when the replica count of the StatefulSet is reduced +## @param persistentVolumeClaimRetentionPolicy.whenDeleted Volume retention behavior that applies when the StatefulSet is deleted +persistentVolumeClaimRetentionPolicy: + enabled: true + whenScaled: Retain + whenDeleted: Delete +persistentVolume: + enabled: true + size: 10G + ## database data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + subPath: "" + mountPath: "/home/postgres/pgdata" + annotations: {} + accessModes: + - ReadWriteOnce + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 100m + hugepages-2Mi: 4Mi + memory: 512Mi + requests: + cpu: 100m + memory: 512Mi + +shmVolume: + ## @param shmVolume.enabled Enable emptyDir volume for /dev/shm for PostgreSQL pod(s) + ## + enabled: true + ## @param shmVolume.sizeLimit Set this to enable a size limit on the shm tmpfs + ## Note: the size of the tmpfs counts against container's memory limit + ## e.g: + ## sizeLimit: 1Gi + ## + sizeLimit: "1Gi" + +# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +nodeSelector: {} + +# https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinityTemplate: | + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: "kubernetes.io/hostname" + labelSelector: + matchLabels: + application: {{ template "patroni.name" . }} + release: {{ .Release.Name | quote }} +affinity: {} +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +rbac: + # Specifies whether RBAC resources should be created + create: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: +## Postgresql Nework Policy configuration +## +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources + ## + enabled: true + ## @param networkPolicy.allowExternal The Policy model to apply. + ## When set to false, only pods with the correct + ## client label will have network access to the port Postgresql is listening + ## on. When true, Postgresql will accept connections from any source + ## (with the correct destination port). + ## + allowCurrentNamespace: true + allowNamespaces: +clusterDomain: cluster.local diff --git a/addons/postgresql-cluster/18/meta.yaml b/addons/postgresql-cluster/18/meta.yaml new file mode 100644 index 0000000..df9589f --- /dev/null +++ b/addons/postgresql-cluster/18/meta.yaml @@ -0,0 +1,30 @@ +name: postgresql-cluster-18 +version: 18 +id: d0c8ade8-6950-4efa-89b3-f6da5f0a36dc +description: "postgresql-cluster-18" +displayName: "postgresql-cluster-18" +metadata: + displayName: "postgresql-cluster-18" + provider: + name: drycc + supportURL: https://www.postgresql.org/ + documentationURL: https://github.com/drycc-addons/drycc-docker-postgresql-cluster +tags: postgresql-cluster +bindable: true +instances_retrievable: true +bindings_retrievable: true +plan_updateable: true +allow_parameters: + - name: "networkPolicy.allowNamespaces" + required: false + description: "networkPolicy allowNamespaces config for values.yaml" + - name: "service.type" + required: false + description: "service type config for values.yaml" + - name: "backup" + required: false + description: "Whether to use S3 for backup your data. default false . ps: Make sure there is a available S3 " + - name: "logicalbackup" + required: false + description: "Whether to use S3 for logical backup your data. default false . ps: Make sure there is a available S3 " +archive: false diff --git a/addons/postgresql-cluster/18/plans/standard-16c64g400/bind.yaml b/addons/postgresql-cluster/18/plans/standard-16c64g400/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-16c64g400/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-16c64g400/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-16c64g400/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-16c64g400/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-16c64g400/meta.yaml b/addons/postgresql-cluster/18/plans/standard-16c64g400/meta.yaml new file mode 100644 index 0000000..2089565 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-16c64g400/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-16c64g400" +id: 6f846a7c-0495-4810-a768-6769b1f6430e +description: "PostgreSQL Cluster standard-16c64g400 plan: Disk 400Gi ,vCPUs 16 , RAM 64G , DB MAX Connection 2000" +displayName: "standard-16c64g400" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-16c64g400/values.yaml b/addons/postgresql-cluster/18/plans/standard-16c64g400/values.yaml new file mode 100644 index 0000000..72b92be --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-16c64g400/values.yaml @@ -0,0 +1,81 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-400 +patroni: + pgParameters: + max_worker_processes: 32 + max_parallel_workers: 16 + max_connections: 2000 + max_slot_wal_keep_size: "10 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '16384 MB' + work_mem = '32 MB' + maintenance_work_mem = '520 MB' + huge_pages = try # NB! requires also activation of huge pages via kernel params, see here for more: https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-HUGE-PAGES + effective_cache_size = '45 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '30 min' + checkpoint_completion_target = 0.9 + max_wal_size = '16 GB' + min_wal_size = '2 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 8 + max_parallel_maintenance_workers = 8 + max_parallel_workers = 16 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 40GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 16000m + hugepages-2Mi: 40Mi + memory: 64Gi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 400Gi + +shmVolume: + sizeLimit: "32Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-2c4g20/bind.yaml b/addons/postgresql-cluster/18/plans/standard-2c4g20/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c4g20/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-2c4g20/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-2c4g20/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c4g20/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-2c4g20/meta.yaml b/addons/postgresql-cluster/18/plans/standard-2c4g20/meta.yaml new file mode 100644 index 0000000..14c2050 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c4g20/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-2c4g20" +id: 83de47d0-97c8-4133-a633-d1f9c0c2cc83 +description: "PostgreSQL Cluster standard-2c4g20 plan: Disk 20Gi ,vCPUs 2 , RAM 4G , DB MAX Connection 1000" +displayName: "standard-2c4g20" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-2c4g20/values.yaml b/addons/postgresql-cluster/18/plans/standard-2c4g20/values.yaml new file mode 100644 index 0000000..098a0a0 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c4g20/values.yaml @@ -0,0 +1,81 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-20 + +patroni: + pgParameters: + max_worker_processes: 4 + max_parallel_workers: 2 + max_connections: 1000 + max_slot_wal_keep_size: "2 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '1024 MB' + work_mem = '32 MB' + maintenance_work_mem = '320 MB' + huge_pages = off + effective_cache_size = '3 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '15 min' + checkpoint_completion_target = 0.9 + max_wal_size = '2 GB' + min_wal_size = '1 GB' + + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 1 + max_parallel_maintenance_workers = 1 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 2000m + hugepages-2Mi: 20Mi + memory: 4Gi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 20Gi + +shmVolume: + sizeLimit: "2Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-2c8g50/bind.yaml b/addons/postgresql-cluster/18/plans/standard-2c8g50/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c8g50/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-2c8g50/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-2c8g50/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c8g50/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-2c8g50/meta.yaml b/addons/postgresql-cluster/18/plans/standard-2c8g50/meta.yaml new file mode 100644 index 0000000..175d236 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c8g50/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-2c8g50" +id: 108376d3-0f87-4226-8e80-f200022383aa +description: "PostgreSQL Cluster standard-2c8g50 plan: Disk 50Gi ,vCPUs 2 , RAM 8G , DB MAX Connection 2000" +displayName: "standard-2c8g50" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-2c8g50/values.yaml b/addons/postgresql-cluster/18/plans/standard-2c8g50/values.yaml new file mode 100644 index 0000000..affca34 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-2c8g50/values.yaml @@ -0,0 +1,83 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-50 + +patroni: + pgParameters: + max_worker_processes: 4 + max_parallel_workers: 2 + max_connections: 2000 + max_slot_wal_keep_size: "5 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '2048 MB' + work_mem = '32 MB' + maintenance_work_mem = '320 MB' + huge_pages = off + effective_cache_size = '6 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '15 min' + checkpoint_completion_target = 0.9 + max_wal_size = '4 GB' + min_wal_size = '1 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 1 + max_parallel_maintenance_workers = 1 + max_parallel_workers = 2 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 5GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 2000m + hugepages-2Mi: 20Mi + memory: 8Gi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 50Gi + +shmVolume: + sizeLimit: "4Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-32c128g800/bind.yaml b/addons/postgresql-cluster/18/plans/standard-32c128g800/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c128g800/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-32c128g800/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-32c128g800/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c128g800/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-32c128g800/meta.yaml b/addons/postgresql-cluster/18/plans/standard-32c128g800/meta.yaml new file mode 100644 index 0000000..a2e3bd1 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c128g800/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-32c128g800" +id: 9f2af58a-6e67-4df7-8092-17c5ca94c357 +description: "PostgreSQL Cluster standard-32c128g800 plan: Disk 800Gi ,vCPUs 32 , RAM 128G , DB MAX Connection 2000" +displayName: "standard-32c128g800" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-32c128g800/values.yaml b/addons/postgresql-cluster/18/plans/standard-32c128g800/values.yaml new file mode 100644 index 0000000..c2ca047 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c128g800/values.yaml @@ -0,0 +1,82 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-800 + +patroni: + pgParameters: + max_worker_processes: 64 + max_parallel_workers: 32 + max_connections: 2000 + max_slot_wal_keep_size: "100 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '32768 MB' + work_mem = '64 MB' + maintenance_work_mem = '720 MB' + huge_pages = try # NB! requires also activation of huge pages via kernel params, see here for more: https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-HUGE-PAGES + effective_cache_size = '90 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '30 min' + checkpoint_completion_target = 0.9 + max_wal_size = '64 GB' + min_wal_size = '4 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 16 + max_parallel_maintenance_workers = 16 + max_parallel_workers = 32 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 80GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 32000m + memory: 128Gi + hugepages-2Mi: 80Mi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 800Gi + +shmVolume: + sizeLimit: "64Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-32c64g4000/bind.yaml b/addons/postgresql-cluster/18/plans/standard-32c64g4000/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c64g4000/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-32c64g4000/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-32c64g4000/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c64g4000/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-32c64g4000/meta.yaml b/addons/postgresql-cluster/18/plans/standard-32c64g4000/meta.yaml new file mode 100644 index 0000000..3670757 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c64g4000/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-32c64g4000" +id: 71afa502-7b03-41da-b9f7-61d8d7168dd6 +description: "PostgreSQL Cluster standard-32c64g4000 plan: Disk 4Ti ,vCPUs 32 , RAM 64G , DB MAX Connection 2000" +displayName: "standard-32c64g4000" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-32c64g4000/values.yaml b/addons/postgresql-cluster/18/plans/standard-32c64g4000/values.yaml new file mode 100644 index 0000000..56fc31f --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-32c64g4000/values.yaml @@ -0,0 +1,82 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-800 + +patroni: + pgParameters: + max_worker_processes: 64 + max_parallel_workers: 32 + max_connections: 2000 + max_slot_wal_keep_size: "200 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '16384 MB' + work_mem = '256 MB' + maintenance_work_mem = '2048 MB' + huge_pages = try # NB! requires also activation of huge pages via kernel params, see here for more: https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-HUGE-PAGES + effective_cache_size = '45 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '30 min' + checkpoint_completion_target = 0.9 + max_wal_size = '32 GB' + min_wal_size = '4 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 16 + max_parallel_maintenance_workers = 16 + max_parallel_workers = 32 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 100GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 32000m + memory: 64Gi + hugepages-2Mi: 80Mi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 4Ti + +shmVolume: + sizeLimit: "32Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-4c16g100/bind.yaml b/addons/postgresql-cluster/18/plans/standard-4c16g100/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-4c16g100/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-4c16g100/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-4c16g100/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-4c16g100/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-4c16g100/meta.yaml b/addons/postgresql-cluster/18/plans/standard-4c16g100/meta.yaml new file mode 100644 index 0000000..2026241 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-4c16g100/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-4c16g100" +id: 5aea991e-3809-4c67-adf1-7b4ad04ce0f1 +description: "PostgreSQL Cluster standard-4c16g100 plan: Disk 100Gi ,vCPUs 4 , RAM 16G , DB MAX Connection 2000" +displayName: "standard-4c16g100" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-4c16g100/values.yaml b/addons/postgresql-cluster/18/plans/standard-4c16g100/values.yaml new file mode 100644 index 0000000..83ac277 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-4c16g100/values.yaml @@ -0,0 +1,83 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-100 + +patroni: + pgParameters: + max_worker_processes: 8 + max_parallel_workers: 4 + max_connections: 2000 + max_slot_wal_keep_size: "10 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '4096 MB' + work_mem = '32 MB' + maintenance_work_mem = '320 MB' + huge_pages = off + effective_cache_size = '11 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '25 min' + checkpoint_completion_target = 0.9 + max_wal_size = '8 GB' + min_wal_size = '2 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 2 + max_parallel_maintenance_workers = 2 + max_parallel_workers = 4 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 10GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 4000m + hugepages-2Mi: 50Mi + memory: 16Gi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 100Gi + +shmVolume: + sizeLimit: "8Gi" diff --git a/addons/postgresql-cluster/18/plans/standard-8c32g200/bind.yaml b/addons/postgresql-cluster/18/plans/standard-8c32g200/bind.yaml new file mode 100644 index 0000000..55955ed --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-8c32g200/bind.yaml @@ -0,0 +1,41 @@ +credential: +{{- if (eq .Values.service.type "LoadBalancer") }} + - name: EXTRANET_MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' + - name: EXTRANET_REPL_HOST + valueFrom: + serviceRef: + name: {{ template "common.names.fullname" . }}-repl + jsonpath: '{ .status.loadBalancer.ingress[*].ip }' +{{- end }} + - name: DOMAIN_MASTER + value: {{ template "common.names.fullname" . }}-master.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: DOMAIN_REPL + value: {{ template "common.names.fullname" . }}-repl.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: MASTER_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-master + jsonpath: '{ .spec.clusterIP }' + - name: REPL_HOST + valueFrom: + serviceRef: + name: {{ include "common.names.fullname" . }}-repl + jsonpath: '{ .spec.clusterIP }' + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-password }' + - name: USERNAME + valueFrom: + secretKeyRef: + name: {{ template "common.names.fullname" . }} + jsonpath: '{ .data.admin-user }' + - name: PORT + value: 5432 + - name: DATABASE + value: postgres \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-8c32g200/instance-schema.json b/addons/postgresql-cluster/18/plans/standard-8c32g200/instance-schema.json new file mode 100644 index 0000000..66ebbaa --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-8c32g200/instance-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "default": "IfNotPresent", + "title": "Image pull policy" + } + } +} \ No newline at end of file diff --git a/addons/postgresql-cluster/18/plans/standard-8c32g200/meta.yaml b/addons/postgresql-cluster/18/plans/standard-8c32g200/meta.yaml new file mode 100644 index 0000000..dd992c0 --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-8c32g200/meta.yaml @@ -0,0 +1,6 @@ +name: "standard-8c32g200" +id: 3af96fe4-66d5-41f6-8efa-00209fbe4e31 +description: "PostgreSQL Cluster standard-8c32g200 plan: Disk 200Gi ,vCPUs 8 , RAM 32G , DB MAX Connection 2000" +displayName: "standard-8c32g200" +bindable: true +maximum_polling_duration: 1800 diff --git a/addons/postgresql-cluster/18/plans/standard-8c32g200/values.yaml b/addons/postgresql-cluster/18/plans/standard-8c32g200/values.yaml new file mode 100644 index 0000000..297ca6a --- /dev/null +++ b/addons/postgresql-cluster/18/plans/standard-8c32g200/values.yaml @@ -0,0 +1,82 @@ +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: hb-postgresql-cluster-standard-200 + +patroni: + pgParameters: + max_worker_processes: 16 + max_parallel_workers: 8 + max_connections: 2000 + max_slot_wal_keep_size: "10 GB" + +postgresql: + config: |- + # Connectivity + superuser_reserved_connections = 3 + + # Memory Settings + shared_buffers = '8192 MB' + work_mem = '32 MB' + maintenance_work_mem = '420 MB' + huge_pages = try # NB! requires also activation of huge pages via kernel params, see here for more: https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-HUGE-PAGES + effective_cache_size = '22 GB' + effective_io_concurrency = 100 # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost = 1.25 # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing=on # measure exact block IO times + track_functions=pl # track execution times of pl-language procedures if any + + # Replication + max_wal_senders = 10 + synchronous_commit = on + + # Checkpointing: + checkpoint_timeout = '25 min' + checkpoint_completion_target = 0.9 + max_wal_size = '16 GB' + min_wal_size = '3 GB' + + # WAL writing + wal_compression = on + wal_buffers = -1 # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay = 200ms + wal_writer_flush_after = 1MB + + # Background writer + bgwriter_delay = 200ms + bgwriter_lru_maxpages = 100 + bgwriter_lru_multiplier = 2.0 + bgwriter_flush_after = 0 + + # Parallel queries: + max_parallel_workers_per_gather = 4 + max_parallel_maintenance_workers = 4 + max_parallel_workers = 8 + parallel_leader_participation = on + + # Advanced features + enable_partitionwise_join = on + enable_partitionwise_aggregate = on + jit = off + max_slot_wal_keep_size = 20GB + track_wal_io_timing = on + maintenance_io_concurrency = 100 + +resources: + # If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + limits: + cpu: 8000m + hugepages-2Mi: 60Mi + memory: 32Gi + requests: + cpu: 100m + memory: 1Gi + +persistentVolume: + enabled: true + size: 200Gi + +shmVolume: + sizeLimit: "16Gi"