From 679596c21c863e8922f48e83254068a3bed59904 Mon Sep 17 00:00:00 2001 From: Vassiliy Yegorov Date: Tue, 2 Jul 2024 19:58:16 +0700 Subject: [PATCH] init --- .gitignore | 3 + 1.k8s/README.md | 52 ++ 1.k8s/cluster.yml | 56 ++ 2.longhorn/README.md | 16 + 2.longhorn/minioSecret.yaml | 10 + 2.longhorn/storageClass.yaml | 14 + 3.zalando/baseCluster.yaml | 47 ++ 3.zalando/extendedCluster.yaml | 49 ++ 3.zalando/poolerCluster.yaml | 114 +++ 3.zalando/z-fullCluster.yaml | 95 +++ README.md | 12 + charts/README.md | 15 + charts/longhorn/README.md | 1 + charts/longhorn/storageClasses.yaml | 12 + charts/postgres-operator-ui/.helmignore | 22 + charts/postgres-operator-ui/Chart.yaml | 19 + charts/postgres-operator-ui/index.yaml | 165 +++++ .../postgres-operator-ui/templates/NOTES.txt | 3 + .../templates/_helpers.tpl | 39 + .../templates/clusterrole.yaml | 53 ++ .../templates/clusterrolebinding.yaml | 19 + .../templates/deployment.yaml | 105 +++ .../templates/ingress.yaml | 60 ++ .../templates/service.yaml | 28 + .../templates/serviceaccount.yaml | 12 + charts/postgres-operator-ui/values.yaml | 128 ++++ charts/postgres-operator/.helmignore | 21 + charts/postgres-operator/Chart.yaml | 18 + .../crds/operatorconfigurations.yaml | 698 ++++++++++++++++++ .../postgres-operator/crds/postgresqls.yaml | 683 +++++++++++++++++ .../postgres-operator/crds/postgresteams.yaml | 70 ++ charts/postgres-operator/index.yaml | 158 ++++ charts/postgres-operator/templates/NOTES.txt | 3 + .../postgres-operator/templates/_helpers.tpl | 79 ++ .../templates/clusterrole-postgres-pod.yaml | 71 ++ .../templates/clusterrole.yaml | 254 +++++++ .../templates/clusterrolebinding.yaml | 19 + .../templates/configmap.yaml | 30 + .../templates/deployment.yaml | 80 ++ .../templates/operatorconfiguration.yaml | 45 ++ .../postgres-pod-priority-class.yaml | 16 + .../postgres-operator/templates/service.yaml | 19 + .../templates/serviceaccount.yaml | 12 + .../templates/user-facing-clusterroles.yaml | 71 ++ charts/postgres-operator/values.yaml | 526 +++++++++++++ 45 files changed, 4022 insertions(+) create mode 100644 .gitignore create mode 100644 1.k8s/README.md create mode 100644 1.k8s/cluster.yml create mode 100644 2.longhorn/README.md create mode 100644 2.longhorn/minioSecret.yaml create mode 100644 2.longhorn/storageClass.yaml create mode 100644 3.zalando/baseCluster.yaml create mode 100644 3.zalando/extendedCluster.yaml create mode 100644 3.zalando/poolerCluster.yaml create mode 100644 3.zalando/z-fullCluster.yaml create mode 100644 README.md create mode 100644 charts/README.md create mode 100644 charts/longhorn/README.md create mode 100644 charts/longhorn/storageClasses.yaml create mode 100644 charts/postgres-operator-ui/.helmignore create mode 100644 charts/postgres-operator-ui/Chart.yaml create mode 100644 charts/postgres-operator-ui/index.yaml create mode 100644 charts/postgres-operator-ui/templates/NOTES.txt create mode 100644 charts/postgres-operator-ui/templates/_helpers.tpl create mode 100644 charts/postgres-operator-ui/templates/clusterrole.yaml create mode 100644 charts/postgres-operator-ui/templates/clusterrolebinding.yaml create mode 100644 charts/postgres-operator-ui/templates/deployment.yaml create mode 100644 charts/postgres-operator-ui/templates/ingress.yaml create mode 100644 charts/postgres-operator-ui/templates/service.yaml create mode 100644 charts/postgres-operator-ui/templates/serviceaccount.yaml create mode 100644 charts/postgres-operator-ui/values.yaml create mode 100644 charts/postgres-operator/.helmignore create mode 100644 charts/postgres-operator/Chart.yaml create mode 100644 charts/postgres-operator/crds/operatorconfigurations.yaml create mode 100644 charts/postgres-operator/crds/postgresqls.yaml create mode 100644 charts/postgres-operator/crds/postgresteams.yaml create mode 100644 charts/postgres-operator/index.yaml create mode 100644 charts/postgres-operator/templates/NOTES.txt create mode 100644 charts/postgres-operator/templates/_helpers.tpl create mode 100644 charts/postgres-operator/templates/clusterrole-postgres-pod.yaml create mode 100644 charts/postgres-operator/templates/clusterrole.yaml create mode 100644 charts/postgres-operator/templates/clusterrolebinding.yaml create mode 100644 charts/postgres-operator/templates/configmap.yaml create mode 100644 charts/postgres-operator/templates/deployment.yaml create mode 100644 charts/postgres-operator/templates/operatorconfiguration.yaml create mode 100644 charts/postgres-operator/templates/postgres-pod-priority-class.yaml create mode 100644 charts/postgres-operator/templates/service.yaml create mode 100644 charts/postgres-operator/templates/serviceaccount.yaml create mode 100644 charts/postgres-operator/templates/user-facing-clusterroles.yaml create mode 100644 charts/postgres-operator/values.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..389f4a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +cluster.rkestate +kube_config_cluster.yml diff --git a/1.k8s/README.md b/1.k8s/README.md new file mode 100644 index 0000000..3ea431e --- /dev/null +++ b/1.k8s/README.md @@ -0,0 +1,52 @@ +# k8s кластер + +## Нужно + +1. rke - +2. k8s-lens - +3. helm - +4. Три машины на ubuntu 22.04 + docker + +## Разворачиваем куб + +1. `rke up --ignore-docker-version` +2. полученный конфиг импортируем в линзу +3. в настройках подключаем метрики + +## Полезные команды + +```bash +apt update && apt install -y mc htop zip wget curl git jq net-tools gnupg2 screen open-iscsi +curl https://get.docker.com -o install.sh && sh install.sh +``` + +## Твики + +### is apparently in use by the system; will not make a filesystem here! + +* Create the default configuration file /etc/multipath.conf if not existed +* Add the following line to blacklist section devnode "^sd[a-z0-9]+" + +```config +blacklist { + devnode "^sd[a-z0-9]+" +} +``` + +* Restart multipath service# systemctl restart multipathd.service +* Verify that configuration is applied# multipath -t + + +### Failed to allocate directory watch: Too many open files + +на всех нодах кластера: + +```bash +sysctl fs.inotify.max_user_watches=65536 +sysctl fs.inotify.max_user_instances=8192 +sysctl net.ipv4.tcp_max_syn_backlog=100000 +sysctl net.core.somaxconn=100000 +sysctl net.ipv4.tcp_wmem='4096 12582912 16777216' +sysctl net.ipv4.tcp_rmem='4096 12582912 16777216' +sysctl net.ipv4.ip_local_port_range='10240 65535' +``` diff --git a/1.k8s/cluster.yml b/1.k8s/cluster.yml new file mode 100644 index 0000000..7b059c7 --- /dev/null +++ b/1.k8s/cluster.yml @@ -0,0 +1,56 @@ +cluster_name: k8s-zalando +kubernetes_version: "v1.28.10-rancher1-1" + +enable_cri_dockerd: true +ignore_docker_version: true + +nodes: + - address: 192.168.23.101 + hostname_override: node-01 + user: root + labels: + location: pve1-nsk + role: [controlplane, worker, etcd] + + - address: 192.168.23.102 + hostname_override: node-02 + user: root + labels: + location: pve1-nsk + role: [controlplane, worker, etcd] + + - address: 192.168.23.103 + hostname_override: node-03 + user: root + labels: + location: pve1-nsk + role: [controlplane, worker, etcd] + +services: + etcd: + snapshot: true + creation: 6h + retention: 30h + kubelet: + extra_args: + max-pods: 350 + +ingress: + provider: nginx + node_selector: + orc_ingress: yes + +monitoring: + provider: metrics-server + replicas: 0 + +# authentication: +# strategy: x509 +# sans: +# - "192.168.23.2" + +#dns: +# provider: coredns +# upstreamnameservers: +# - 8.8.8.8 +# - 1.1.1.1 diff --git a/2.longhorn/README.md b/2.longhorn/README.md new file mode 100644 index 0000000..f743e3c --- /dev/null +++ b/2.longhorn/README.md @@ -0,0 +1,16 @@ +# longhorn + +## Установка + +```bash +helm upgrade --install --create-namespace -n longhorn-system longhorn charts/longhorn/ +``` + +## Бекапы + +1. заполняем файлик секретов кредами для подключения к s3 +2. применяем, подключаем в настройках longhorn, проверяем + +## Storage классы + +Дополнительные storage-классы позволят создавать блочные устройства с разными вариациями настроек, например кол-вом реплик diff --git a/2.longhorn/minioSecret.yaml b/2.longhorn/minioSecret.yaml new file mode 100644 index 0000000..c28b6a2 --- /dev/null +++ b/2.longhorn/minioSecret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: minio-secret + namespace: longhorn-system +data: + AWS_ACCESS_KEY_ID: + AWS_ENDPOINTS: + AWS_SECRET_ACCESS_KEY: +type: Opaque diff --git a/2.longhorn/storageClass.yaml b/2.longhorn/storageClass.yaml new file mode 100644 index 0000000..a2f7031 --- /dev/null +++ b/2.longhorn/storageClass.yaml @@ -0,0 +1,14 @@ +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: longhorn-reclaim2 + annotations: + storageclass.kubernetes.io/is-default-class: "false" +provisioner: driver.longhorn.io +allowVolumeExpansion: true +parameters: + numberOfReplicas: "2" + staleReplicaTimeout: "30" + fromBackup: "" + baseImage: "" +reclaimPolicy: Delete diff --git a/3.zalando/baseCluster.yaml b/3.zalando/baseCluster.yaml new file mode 100644 index 0000000..e653b6e --- /dev/null +++ b/3.zalando/baseCluster.yaml @@ -0,0 +1,47 @@ +kind: "postgresql" +apiVersion: "acid.zalan.do/v1" +metadata: + name: "rm-psql" + labels: + team: rm + app: rm-pgsql + resource-group: rm-pgsql +spec: + teamId: "rm" + dockerImage: ghcr.io/zalando/spilo-16:3.2-p2 + numberOfInstances: 2 + spiloRunAsUser: 101 + spiloRunAsGroup: 103 + spiloFSGroup: 103 + postgresql: + version: "16" + parameters: + hot_standby_feedback: "on" + max_standby_archive_delay: 300s + max_standby_streaming_delay: 300s + max_connections: "300" + log_rotation_size: '1024000' + log_min_duration_statement: '1000' + volume: + size: "5Gi" + storageClass: "longhorn" + users: + rmu: + - superuser + - createdb + preparedDatabases: + rm: + defaultUsers: true + patroni: + pg_hba: + - local all all trust + - host all all 0.0.0.0/0 md5 + - host all all ::1/128 md5 + resources: + requests: + cpu: "0.4" + memory: "500Mi" + limits: + cpu: "0.8" + memory: "1Gi" +--- diff --git a/3.zalando/extendedCluster.yaml b/3.zalando/extendedCluster.yaml new file mode 100644 index 0000000..add2a68 --- /dev/null +++ b/3.zalando/extendedCluster.yaml @@ -0,0 +1,49 @@ +kind: "postgresql" +apiVersion: "acid.zalan.do/v1" +metadata: + name: "rm-psql" + labels: + team: rm + app: rm-pgsql + resource-group: rm-pgsql +spec: + teamId: "rm" + dockerImage: ghcr.io/zalando/spilo-16:3.2-p2 + numberOfInstances: 2 + spiloRunAsUser: 101 + spiloRunAsGroup: 103 + spiloFSGroup: 103 + postgresql: + version: "16" + parameters: + hot_standby_feedback: "on" + max_standby_archive_delay: 300s + max_standby_streaming_delay: 300s + max_connections: "300" + log_rotation_size: '1024000' + log_min_duration_statement: '1000' + volume: + size: "5Gi" + storageClass: "longhorn" + users: + rmu: + - superuser + - createdb + preparedDatabases: + rm: + defaultUsers: true + extensions: + pgcrypto: public + patroni: + pg_hba: + - local all all trust + - host all all 0.0.0.0/0 md5 + - host all all ::1/128 md5 + resources: + requests: + cpu: "0.4" + memory: "500Mi" + limits: + cpu: "0.8" + memory: "1Gi" + \ No newline at end of file diff --git a/3.zalando/poolerCluster.yaml b/3.zalando/poolerCluster.yaml new file mode 100644 index 0000000..5e45399 --- /dev/null +++ b/3.zalando/poolerCluster.yaml @@ -0,0 +1,114 @@ +kind: "postgresql" +apiVersion: "acid.zalan.do/v1" +metadata: + name: "rm-psql" + labels: + team: rm + app: rm-pgsql + resource-group: rm-pgsql +spec: + teamId: "rm" + dockerImage: ghcr.io/zalando/spilo-16:3.2-p2 + numberOfInstances: 2 + spiloRunAsUser: 101 + spiloRunAsGroup: 103 + spiloFSGroup: 103 + postgresql: + version: "16" + parameters: + hot_standby_feedback: "on" + max_standby_archive_delay: 300s + max_standby_streaming_delay: 300s + max_connections: "300" + log_rotation_size: '1024000' + log_min_duration_statement: '1000' + volume: + size: "5Gi" + storageClass: "longhorn" + users: + rmu: + - superuser + - createdb + preparedDatabases: + rm: + defaultUsers: true + extensions: + pgcrypto: public + patroni: + pg_hba: + - local all all trust + - host all all 0.0.0.0/0 md5 + - host all all ::1/128 md5 + enableLogicalBackup: false + enableConnectionPooler: false + # enableReplicaConnectionPooler: true + connectionPooler: + numberOfInstances: 2 + mode: "transaction" + schema: "pooler" + user: "pooler" + resources: + requests: + cpu: 300m + memory: 100Mi + limits: + cpu: "1" + memory: 100Mi + resources: + requests: + cpu: "0.4" + memory: "500Mi" + limits: + cpu: "0.8" + memory: "1Gi" + # tolerations: + # - key: postgres + # operator: Exists + # effect: NoSchedule + sidecars: + - name: "zalando-exporter" + image: "wrouesnel/postgres_exporter" + ports: + - name: exporter + containerPort: 9187 + protocol: TCP + resources: + limits: + cpu: 100m + memory: 256M + requests: + cpu: 50m + memory: 128M + env: + - name: "DATA_SOURCE_URI" + value: "localhost:5432/rm?sslmode=disable" + - name: "DATA_SOURCE_USER" + valueFrom: + secretKeyRef: + name: postgres.rm-psql + key: username + - name: "DATA_SOURCE_PASS" + valueFrom: + secretKeyRef: + name: postgres.rm-psql + key: password + - name: "zalando-df-exporter" + image: "hub.realmanual.ru/pub/df-exporter:0.1" + ports: + - name: df-exporter + containerPort: 9873 + protocol: TCP + env: + - name: "MYPATH" + value: "/home/postgres/pgdata" + - name: "PORT" + value: "9873" + resources: + limits: + cpu: 100m + memory: 256M + requests: + cpu: 50m + memory: 128M + +--- diff --git a/3.zalando/z-fullCluster.yaml b/3.zalando/z-fullCluster.yaml new file mode 100644 index 0000000..a986f6d --- /dev/null +++ b/3.zalando/z-fullCluster.yaml @@ -0,0 +1,95 @@ +kind: "postgresql" +apiVersion: "acid.zalan.do/v1" +metadata: + name: "rm-psql" + labels: + team: rm + app: rm-pgsql + resource-group: rm-pgsql +spec: + teamId: "rm" + dockerImage: ghcr.io/zalando/spilo-16:3.2-p2 + numberOfInstances: 2 + spiloRunAsUser: 101 + spiloRunAsGroup: 103 + spiloFSGroup: 103 + postgresql: + version: "16" + parameters: + hot_standby_feedback: "on" + max_standby_archive_delay: 300s + max_standby_streaming_delay: 300s + max_connections: "300" + log_rotation_size: '1024000' + log_min_duration_statement: '1000' + volume: + size: "5Gi" + storageClass: "longhorn" + users: + rmu: + - superuser + - createdb + preparedDatabases: + rm: + defaultUsers: true + extensions: + pgcrypto: public + patroni: + pg_hba: + - local all all trust + - host all all 0.0.0.0/0 md5 + - host all all ::1/128 md5 + enableLogicalBackup: false + enableConnectionPooler: true + enableReplicaConnectionPooler: true + connectionPooler: + numberOfInstances: 2 + mode: "transaction" + schema: "pooler" + user: "pooler" + resources: + requests: + cpu: 300m + memory: 100Mi + limits: + cpu: "1" + memory: 100Mi + resources: + requests: + cpu: "0.4" + memory: "500Mi" + limits: + cpu: "0.8" + memory: "1Gi" + # tolerations: + # - key: postgres + # operator: Exists + # effect: NoSchedule + sidecars: + - name: "zalando-exporter" + image: "wrouesnel/postgres_exporter" + ports: + - name: exporter + containerPort: 9187 + protocol: TCP + resources: + limits: + cpu: 100m + memory: 256M + requests: + cpu: 50m + memory: 128M + env: + - name: "DATA_SOURCE_URI" + value: "localhost:5432/rm?sslmode=disable" + - name: "DATA_SOURCE_USER" + valueFrom: + secretKeyRef: + name: postgres.rm-psql + key: username + - name: "DATA_SOURCE_PASS" + valueFrom: + secretKeyRef: + name: postgres.rm-psql + key: password +--- diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f76045 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Репо к курсу ZL: Базы в кубе + +## Видео к курсу + +- [видео](https://promo.realmanual.ru/zalando) + +### Автор + +- **Vassiliy Yegorov** +- [школа](https://realmanual.ru) +- [youtube](https://youtube.com/realmanual) +- [группа в ТГ](https://t.me/realmanual_group) diff --git a/charts/README.md b/charts/README.md new file mode 100644 index 0000000..5a5efd2 --- /dev/null +++ b/charts/README.md @@ -0,0 +1,15 @@ +# Устанока зависимостей + +## Longhorn + +```bash +kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml +``` + +## Оператор zalando + +- устанавливаем оператора + +`helm upgrade --install --create-namespace zalando-operator -n zalando charts/postgres-operator/` + +- после чего можно сетапить кластер базы. пример в yamls/init-cluster.yaml diff --git a/charts/longhorn/README.md b/charts/longhorn/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/charts/longhorn/README.md @@ -0,0 +1 @@ + diff --git a/charts/longhorn/storageClasses.yaml b/charts/longhorn/storageClasses.yaml new file mode 100644 index 0000000..0fb6769 --- /dev/null +++ b/charts/longhorn/storageClasses.yaml @@ -0,0 +1,12 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: longhorn-reclaim0 + annotations: + storageclass.kubernetes.io/is-default-class: 'false' +provisioner: driver.longhorn.io +parameters: + numberOfReplicas: '2' +reclaimPolicy: Delete +allowVolumeExpansion: true +volumeBindingMode: Immediate diff --git a/charts/postgres-operator-ui/.helmignore b/charts/postgres-operator-ui/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/charts/postgres-operator-ui/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/postgres-operator-ui/Chart.yaml b/charts/postgres-operator-ui/Chart.yaml new file mode 100644 index 0000000..836aaae --- /dev/null +++ b/charts/postgres-operator-ui/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +appVersion: 1.12.2 +description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience +home: https://github.com/zalando/postgres-operator +keywords: +- postgres +- operator +- ui +- cloud-native +- patroni +- spilo +maintainers: +- email: opensource@zalando.de + name: Zalando +name: postgres-operator-ui +sources: +- https://github.com/zalando/postgres-operator +version: 1.12.2 diff --git a/charts/postgres-operator-ui/index.yaml b/charts/postgres-operator-ui/index.yaml new file mode 100644 index 0000000..e498431 --- /dev/null +++ b/charts/postgres-operator-ui/index.yaml @@ -0,0 +1,165 @@ +apiVersion: v1 +entries: + postgres-operator-ui: + - apiVersion: v2 + appVersion: 1.12.1 + created: "2024-06-10T12:33:32.731242273+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: da4142735e940860d2a72bf559d41fa19ff7c753aa642fe45e3c18b4fae149ad + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.12.1.tgz + version: 1.12.1 + - apiVersion: v2 + appVersion: 1.12.0 + created: "2024-06-10T12:33:32.729316881+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: 498b8254dc0e24bc3cdc98e250a5640dc104b75e1dbba5d9fdb90a3b39e7eb8c + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.12.0.tgz + version: 1.12.0 + - apiVersion: v2 + appVersion: 1.11.0 + created: "2024-06-10T12:33:32.727093777+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: a45f2284045c2a9a79750a36997386444f39b01ac722b17c84b431457577a3a2 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.11.0.tgz + version: 1.11.0 + - apiVersion: v2 + appVersion: 1.10.1 + created: "2024-06-10T12:33:32.725156907+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: 2e5e7a82aebee519ec57c6243eb8735124aa4585a3a19c66ffd69638fbeb11ce + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.10.1.tgz + version: 1.10.1 + - apiVersion: v2 + appVersion: 1.10.0 + created: "2024-06-10T12:33:32.719707841+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: 47413650e3188539ae778a601998efa2c4f80b8aa16e3668a2fc7b72e014b605 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.10.0.tgz + version: 1.10.0 + - apiVersion: v2 + appVersion: 1.9.0 + created: "2024-06-10T12:33:32.737192609+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: df434af6c8b697fe0631017ecc25e3c79e125361ae6622347cea41a545153bdc + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.9.0.tgz + version: 1.9.0 + - apiVersion: v2 + appVersion: 1.8.2 + created: "2024-06-10T12:33:32.733885274+02:00" + description: Postgres Operator UI provides a graphical interface for a convenient + database-as-a-service user experience + digest: fbfc90fa8fd007a08a7c02e0ec9108bb8282cbb42b8c976d88f2193d6edff30c + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - ui + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator-ui + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-ui-1.8.2.tgz + version: 1.8.2 +generated: "2024-06-10T12:33:32.717072704+02:00" diff --git a/charts/postgres-operator-ui/templates/NOTES.txt b/charts/postgres-operator-ui/templates/NOTES.txt new file mode 100644 index 0000000..7e91428 --- /dev/null +++ b/charts/postgres-operator-ui/templates/NOTES.txt @@ -0,0 +1,3 @@ +To verify that postgres-operator has started, run: + + kubectl --namespace={{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ template "postgres-operator-ui.name" . }}" \ No newline at end of file diff --git a/charts/postgres-operator-ui/templates/_helpers.tpl b/charts/postgres-operator-ui/templates/_helpers.tpl new file mode 100644 index 0000000..d83b929 --- /dev/null +++ b/charts/postgres-operator-ui/templates/_helpers.tpl @@ -0,0 +1,39 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "postgres-operator-ui.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 "postgres-operator-ui.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 a service account name. +*/}} +{{- define "postgres-operator-ui.serviceAccountName" -}} +{{ default (include "postgres-operator-ui.fullname" .) .Values.serviceAccount.name }} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "postgres-operator-ui.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/postgres-operator-ui/templates/clusterrole.yaml b/charts/postgres-operator-ui/templates/clusterrole.yaml new file mode 100644 index 0000000..57a1a63 --- /dev/null +++ b/charts/postgres-operator-ui/templates/clusterrole.yaml @@ -0,0 +1,53 @@ +{{ if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "postgres-operator-ui.serviceAccountName" . }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + verbs: + - create + - delete + - get + - list + - patch + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list +- apiGroups: + - apps + resources: + - deployments + - statefulsets + verbs: + - get + - list +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list +{{ end }} diff --git a/charts/postgres-operator-ui/templates/clusterrolebinding.yaml b/charts/postgres-operator-ui/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..7c874d3 --- /dev/null +++ b/charts/postgres-operator-ui/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{ if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "postgres-operator-ui.serviceAccountName" . }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "postgres-operator-ui.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "postgres-operator-ui.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/charts/postgres-operator-ui/templates/deployment.yaml b/charts/postgres-operator-ui/templates/deployment.yaml new file mode 100644 index 0000000..3161ae0 --- /dev/null +++ b/charts/postgres-operator-ui/templates/deployment.yaml @@ -0,0 +1,105 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator-ui.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "postgres-operator-ui.serviceAccountName" . }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: "service" + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8081 + protocol: "TCP" + readinessProbe: + httpGet: + path: "/health" + port: 8081 + initialDelaySeconds: 5 + timeoutSeconds: 1 + resources: + {{- toYaml .Values.resources | nindent 12 }} + env: + - name: "APP_URL" + value: {{ .Values.envs.appUrl }} + - name: "OPERATOR_API_URL" + value: {{ .Values.envs.operatorApiUrl | quote }} + - name: "OPERATOR_CLUSTER_NAME_LABEL" + value: {{ .Values.envs.operatorClusterNameLabel | quote }} + - name: "RESOURCES_VISIBLE" + value: {{ .Values.envs.resourcesVisible | quote }} + - name: "TARGET_NAMESPACE" + value: {{ .Values.envs.targetNamespace | quote }} + - name: "TEAMS" + value: |- + [ + {{- range(initial .Values.envs.teams) }} + {{ . | quote }}, + {{- end }} + {{ last .Values.envs.teams | quote }} + ] + - name: "OPERATOR_UI_CONFIG" + value: |- + { + "docs_link":"https://postgres-operator.readthedocs.io/en/latest/", + "dns_format_string": "{0}.{1}", + "databases_visible": true, + "master_load_balancer_visible": true, + "nat_gateways_visible": false, + "replica_load_balancer_visible": true, + "resources_visible": true, + "users_visible": true, + "cost_ebs": 0.0952, + "cost_iops": 0.006, + "cost_throughput": 0.0476, + "cost_core": 0.0575, + "cost_memory": 0.014375, + "free_iops": 3000, + "free_throughput": 125, + "limit_iops": 16000, + "limit_throughput": 1000, + "postgresql_versions": [ + "16", + "15", + "14", + "13", + "12" + ] + } + {{- if .Values.extraEnvs }} + {{- .Values.extraEnvs | toYaml | nindent 12 }} + {{- end }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} \ No newline at end of file diff --git a/charts/postgres-operator-ui/templates/ingress.yaml b/charts/postgres-operator-ui/templates/ingress.yaml new file mode 100644 index 0000000..75bf790 --- /dev/null +++ b/charts/postgres-operator-ui/templates/ingress.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "postgres-operator-ui.fullname" . -}} +{{- $svcPort := .Values.service.port -}} + +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + {{ if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion -}} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else -}} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/postgres-operator-ui/templates/service.yaml b/charts/postgres-operator-ui/templates/service.yaml new file mode 100644 index 0000000..c93e076 --- /dev/null +++ b/charts/postgres-operator-ui/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "postgres-operator-ui.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: {{ .Values.service.port }} + targetPort: 8081 + {{- if and (eq .Values.service.type "NodePort") .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + protocol: TCP + selector: + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + type: {{ .Values.service.type }} + + diff --git a/charts/postgres-operator-ui/templates/serviceaccount.yaml b/charts/postgres-operator-ui/templates/serviceaccount.yaml new file mode 100644 index 0000000..94a9ca5 --- /dev/null +++ b/charts/postgres-operator-ui/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "postgres-operator-ui.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }} + helm.sh/chart: {{ template "postgres-operator-ui.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +{{ end }} diff --git a/charts/postgres-operator-ui/values.yaml b/charts/postgres-operator-ui/values.yaml new file mode 100644 index 0000000..2342496 --- /dev/null +++ b/charts/postgres-operator-ui/values.yaml @@ -0,0 +1,128 @@ +# Default values for postgres-operator-ui. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +# configure ui image +image: + registry: ghcr.io + repository: zalando/postgres-operator-ui + tag: v1.12.2 + pullPolicy: "IfNotPresent" + +# Optionally specify an array of imagePullSecrets. +# Secrets must be manually created in the namespace. +# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod +# imagePullSecrets: +# - name: + +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: + +# configure UI pod resources +resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + +# configure UI ENVs +envs: + # IMPORTANT: While operator chart and UI chart are independent, this is the interface between + # UI and operator API. Insert the service name of the operator API here! + appUrl: "http://localhost:8081" + operatorApiUrl: "http://postgres-operator:8080" + operatorClusterNameLabel: "cluster-name" + resourcesVisible: "False" + # Set to "*" to allow viewing/creation of clusters in all namespaces + targetNamespace: "default" + teams: + - "acid" + +# Extra pod annotations +podAnnotations: + {} + +# configure extra UI ENVs +# Extra ENVs are writen in kubenertes format and added "as is" to the pod's env variables +# https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ +# https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables +# UI specific env variables can be found here: https://github.com/zalando/postgres-operator/blob/master/ui/operator_ui/main.py +extraEnvs: + [] + # Exemple of settings to make snapshot view working in the ui when using AWS + # - name: WALE_S3_ENDPOINT + # value: https+path://s3.us-east-1.amazonaws.com:443 + # - name: SPILO_S3_BACKUP_PREFIX + # value: spilo/ + # - name: AWS_ACCESS_KEY_ID + # valueFrom: + # secretKeyRef: + # name: + # key: AWS_ACCESS_KEY_ID + # - name: AWS_SECRET_ACCESS_KEY + # valueFrom: + # secretKeyRef: + # name: + # key: AWS_SECRET_ACCESS_KEY + # - name: AWS_DEFAULT_REGION + # valueFrom: + # secretKeyRef: + # name: + # key: AWS_DEFAULT_REGION + # - name: SPILO_S3_BACKUP_BUCKET + # value: + # - name: "USE_AWS_INSTANCE_PROFILE" + # value: "true" + +# configure UI service +service: + type: "ClusterIP" + port: "80" + # If the type of the service is NodePort a port can be specified using the nodePort field + # If the nodePort field is not specified, or if it has no value, then a random port is used + # nodePort: 32521 + annotations: + {} + +# configure UI ingress. If needed: "enabled: true" +ingress: + enabled: false + annotations: + {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + ingressClassName: "" + hosts: + - host: ui.example.org + paths: ["/"] + tls: [] + # - secretName: ui-tls + # hosts: + # - ui.exmaple.org + +# priority class for operator-ui pod +priorityClassName: "" + +# Affinity for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] diff --git a/charts/postgres-operator/.helmignore b/charts/postgres-operator/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/postgres-operator/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/postgres-operator/Chart.yaml b/charts/postgres-operator/Chart.yaml new file mode 100644 index 0000000..c14be91 --- /dev/null +++ b/charts/postgres-operator/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +appVersion: 1.12.2 +description: Postgres Operator creates and manages PostgreSQL clusters running in + Kubernetes +home: https://github.com/zalando/postgres-operator +keywords: +- postgres +- operator +- cloud-native +- patroni +- spilo +maintainers: +- email: opensource@zalando.de + name: Zalando +name: postgres-operator +sources: +- https://github.com/zalando/postgres-operator +version: 1.12.2 diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml new file mode 100644 index 0000000..bf4ae34 --- /dev/null +++ b/charts/postgres-operator/crds/operatorconfigurations.yaml @@ -0,0 +1,698 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: operatorconfigurations.acid.zalan.do + labels: + app.kubernetes.io/name: postgres-operator +spec: + group: acid.zalan.do + names: + kind: OperatorConfiguration + listKind: OperatorConfigurationList + plural: operatorconfigurations + singular: operatorconfiguration + shortNames: + - opconfig + categories: + - all + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - name: Image + type: string + description: Spilo image to be used for Pods + jsonPath: .configuration.docker_image + - name: Cluster-Label + type: string + description: Label for K8s resources created by operator + jsonPath: .configuration.kubernetes.cluster_name_label + - name: Service-Account + type: string + description: Name of service account to be used + jsonPath: .configuration.kubernetes.pod_service_account_name + - name: Min-Instances + type: integer + description: Minimum number of instances per Postgres cluster + jsonPath: .configuration.min_instances + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + schema: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - configuration + properties: + kind: + type: string + enum: + - OperatorConfiguration + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + configuration: + type: object + properties: + crd_categories: + type: array + nullable: true + items: + type: string + docker_image: + type: string + default: "ghcr.io/zalando/spilo-16:3.2-p3" + enable_crd_registration: + type: boolean + default: true + enable_crd_validation: + type: boolean + description: deprecated + default: true + enable_lazy_spilo_upgrade: + type: boolean + default: false + enable_pgversion_env_var: + type: boolean + default: true + enable_shm_volume: + type: boolean + default: true + enable_spilo_wal_path_compat: + type: boolean + default: false + enable_team_id_clustername_prefix: + type: boolean + default: false + etcd_host: + type: string + default: "" + ignore_instance_limits_annotation_key: + type: string + kubernetes_use_configmaps: + type: boolean + default: false + max_instances: + type: integer + description: "-1 = disabled" + minimum: -1 + default: -1 + min_instances: + type: integer + description: "-1 = disabled" + minimum: -1 + default: -1 + resync_period: + type: string + default: "30m" + repair_period: + type: string + default: "5m" + set_memory_request_to_limit: + type: boolean + default: false + sidecar_docker_images: + type: object + additionalProperties: + type: string + sidecars: + type: array + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true + workers: + type: integer + minimum: 1 + default: 8 + users: + type: object + properties: + additional_owner_roles: + type: array + nullable: true + items: + type: string + enable_password_rotation: + type: boolean + default: false + password_rotation_interval: + type: integer + default: 90 + password_rotation_user_retention: + type: integer + default: 180 + replication_username: + type: string + default: standby + super_username: + type: string + default: postgres + major_version_upgrade: + type: object + properties: + major_version_upgrade_mode: + type: string + default: "off" + major_version_upgrade_team_allow_list: + type: array + items: + type: string + minimal_major_version: + type: string + default: "12" + target_major_version: + type: string + default: "16" + kubernetes: + type: object + properties: + additional_pod_capabilities: + type: array + items: + type: string + cluster_domain: + type: string + default: "cluster.local" + cluster_labels: + type: object + additionalProperties: + type: string + default: + application: spilo + cluster_name_label: + type: string + default: "cluster-name" + custom_pod_annotations: + type: object + additionalProperties: + type: string + delete_annotation_date_key: + type: string + delete_annotation_name_key: + type: string + downscaler_annotations: + type: array + items: + type: string + enable_cross_namespace_secret: + type: boolean + default: false + enable_finalizers: + type: boolean + default: false + enable_init_containers: + type: boolean + default: true + enable_secrets_deletion: + type: boolean + default: true + enable_persistent_volume_claim_deletion: + type: boolean + default: true + enable_pod_antiaffinity: + type: boolean + default: false + enable_pod_disruption_budget: + type: boolean + default: true + enable_readiness_probe: + type: boolean + default: false + enable_sidecars: + type: boolean + default: true + ignored_annotations: + type: array + items: + type: string + infrastructure_roles_secret_name: + type: string + infrastructure_roles_secrets: + type: array + nullable: true + items: + type: object + required: + - secretname + - userkey + - passwordkey + properties: + secretname: + type: string + userkey: + type: string + passwordkey: + type: string + rolekey: + type: string + defaultuservalue: + type: string + defaultrolevalue: + type: string + details: + type: string + template: + type: boolean + inherited_annotations: + type: array + items: + type: string + inherited_labels: + type: array + items: + type: string + master_pod_move_timeout: + type: string + default: "20m" + node_readiness_label: + type: object + additionalProperties: + type: string + node_readiness_label_merge: + type: string + enum: + - "AND" + - "OR" + oauth_token_secret_name: + type: string + default: "postgresql-operator" + pdb_master_label_selector: + type: boolean + default: true + pdb_name_format: + type: string + default: "postgres-{cluster}-pdb" + persistent_volume_claim_retention_policy: + type: object + properties: + when_deleted: + type: string + enum: + - "delete" + - "retain" + when_scaled: + type: string + enum: + - "delete" + - "retain" + pod_antiaffinity_preferred_during_scheduling: + type: boolean + default: false + pod_antiaffinity_topology_key: + type: string + default: "kubernetes.io/hostname" + pod_environment_configmap: + type: string + pod_environment_secret: + type: string + pod_management_policy: + type: string + enum: + - "ordered_ready" + - "parallel" + default: "ordered_ready" + pod_priority_class_name: + type: string + pod_role_label: + type: string + default: "spilo-role" + pod_service_account_definition: + type: string + default: "" + pod_service_account_name: + type: string + default: "postgres-pod" + pod_service_account_role_binding_definition: + type: string + default: "" + pod_terminate_grace_period: + type: string + default: "5m" + secret_name_template: + type: string + default: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" + share_pgsocket_with_sidecars: + type: boolean + default: false + spilo_allow_privilege_escalation: + type: boolean + default: true + spilo_runasuser: + type: integer + spilo_runasgroup: + type: integer + spilo_fsgroup: + type: integer + spilo_privileged: + type: boolean + default: false + storage_resize_mode: + type: string + enum: + - "ebs" + - "mixed" + - "pvc" + - "off" + default: "pvc" + toleration: + type: object + additionalProperties: + type: string + watched_namespace: + type: string + postgres_pod_resources: + type: object + properties: + default_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + max_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + max_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + min_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + min_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + timeouts: + type: object + properties: + patroni_api_check_interval: + type: string + default: "1s" + patroni_api_check_timeout: + type: string + default: "5s" + pod_label_wait_timeout: + type: string + default: "10m" + pod_deletion_wait_timeout: + type: string + default: "10m" + ready_wait_interval: + type: string + default: "4s" + ready_wait_timeout: + type: string + default: "30s" + resource_check_interval: + type: string + default: "3s" + resource_check_timeout: + type: string + default: "10m" + load_balancer: + type: object + properties: + custom_service_annotations: + type: object + additionalProperties: + type: string + db_hosted_zone: + type: string + default: "db.example.com" + enable_master_load_balancer: + type: boolean + default: true + enable_master_pooler_load_balancer: + type: boolean + default: false + enable_replica_load_balancer: + type: boolean + default: false + enable_replica_pooler_load_balancer: + type: boolean + default: false + external_traffic_policy: + type: string + enum: + - "Cluster" + - "Local" + default: "Cluster" + master_dns_name_format: + type: string + default: "{cluster}.{namespace}.{hostedzone}" + master_legacy_dns_name_format: + type: string + default: "{cluster}.{team}.{hostedzone}" + replica_dns_name_format: + type: string + default: "{cluster}-repl.{namespace}.{hostedzone}" + replica_legacy_dns_name_format: + type: string + default: "{cluster}-repl.{team}.{hostedzone}" + aws_or_gcp: + type: object + properties: + additional_secret_mount: + type: string + additional_secret_mount_path: + type: string + default: "/meta/credentials" + aws_region: + type: string + default: "eu-central-1" + enable_ebs_gp3_migration: + type: boolean + default: false + enable_ebs_gp3_migration_max_size: + type: integer + default: 1000 + gcp_credentials: + type: string + kube_iam_role: + type: string + log_s3_bucket: + type: string + wal_az_storage_account: + type: string + wal_gs_bucket: + type: string + wal_s3_bucket: + type: string + logical_backup: + type: object + properties: + logical_backup_azure_storage_account_name: + type: string + logical_backup_azure_storage_container: + type: string + logical_backup_azure_storage_account_key: + type: string + logical_backup_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + logical_backup_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + logical_backup_docker_image: + type: string + default: "ghcr.io/zalando/postgres-operator/logical-backup:v1.12.2" + logical_backup_google_application_credentials: + type: string + logical_backup_job_prefix: + type: string + default: "logical-backup-" + logical_backup_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + logical_backup_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + logical_backup_provider: + type: string + enum: + - "az" + - "gcs" + - "s3" + default: "s3" + logical_backup_s3_access_key_id: + type: string + logical_backup_s3_bucket: + type: string + logical_backup_s3_bucket_prefix: + type: string + logical_backup_s3_endpoint: + type: string + logical_backup_s3_region: + type: string + logical_backup_s3_secret_access_key: + type: string + logical_backup_s3_sse: + type: string + logical_backup_s3_retention_time: + type: string + logical_backup_schedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + default: "30 00 * * *" + logical_backup_cronjob_environment_secret: + type: string + debug: + type: object + properties: + debug_logging: + type: boolean + default: true + enable_database_access: + type: boolean + default: true + teams_api: + type: object + properties: + enable_admin_role_for_users: + type: boolean + default: true + enable_postgres_team_crd: + type: boolean + default: true + enable_postgres_team_crd_superusers: + type: boolean + default: false + enable_team_member_deprecation: + type: boolean + default: false + enable_team_superuser: + type: boolean + default: false + enable_teams_api: + type: boolean + default: true + pam_configuration: + type: string + default: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees" + pam_role_name: + type: string + default: "zalandos" + postgres_superuser_teams: + type: array + items: + type: string + protected_role_names: + type: array + items: + type: string + default: + - admin + - cron_admin + role_deletion_suffix: + type: string + default: "_deleted" + team_admin_role: + type: string + default: "admin" + team_api_role_configuration: + type: object + additionalProperties: + type: string + default: + log_statement: all + teams_api_url: + type: string + default: "https://teams.example.com/api/" + logging_rest_api: + type: object + properties: + api_port: + type: integer + default: 8080 + cluster_history_entries: + type: integer + default: 1000 + ring_log_lines: + type: integer + default: 100 + scalyr: # deprecated + type: object + properties: + scalyr_api_key: + type: string + scalyr_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "1" + scalyr_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "100m" + scalyr_image: + type: string + scalyr_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "500Mi" + scalyr_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "50Mi" + scalyr_server_url: + type: string + default: "https://upload.eu.scalyr.com" + connection_pooler: + type: object + properties: + connection_pooler_schema: + type: string + default: "pooler" + connection_pooler_user: + type: string + default: "pooler" + connection_pooler_image: + type: string + default: "registry.opensource.zalan.do/acid/pgbouncer:master-32" + connection_pooler_max_db_connections: + type: integer + default: 60 + connection_pooler_mode: + type: string + enum: + - "session" + - "transaction" + default: "transaction" + connection_pooler_number_of_instances: + type: integer + minimum: 1 + default: 2 + connection_pooler_default_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + connection_pooler_default_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + connection_pooler_default_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + connection_pooler_default_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + patroni: + type: object + properties: + enable_patroni_failsafe_mode: + type: boolean + default: false + status: + type: object + additionalProperties: + type: string diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml new file mode 100644 index 0000000..0498625 --- /dev/null +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -0,0 +1,683 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: postgresqls.acid.zalan.do + labels: + app.kubernetes.io/name: postgres-operator +spec: + group: acid.zalan.do + names: + kind: postgresql + listKind: postgresqlList + plural: postgresqls + singular: postgresql + shortNames: + - pg + categories: + - all + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + additionalPrinterColumns: + - name: Team + type: string + description: Team responsible for Postgres cluster + jsonPath: .spec.teamId + - name: Version + type: string + description: PostgreSQL version + jsonPath: .spec.postgresql.version + - name: Pods + type: integer + description: Number of Pods per Postgres cluster + jsonPath: .spec.numberOfInstances + - name: Volume + type: string + description: Size of the bound volume + jsonPath: .spec.volume.size + - name: CPU-Request + type: string + description: Requested CPU for Postgres containers + jsonPath: .spec.resources.requests.cpu + - name: Memory-Request + type: string + description: Requested memory for Postgres containers + jsonPath: .spec.resources.requests.memory + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + - name: Status + type: string + description: Current sync status of postgresql resource + jsonPath: .status.PostgresClusterStatus + schema: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - spec + properties: + kind: + type: string + enum: + - postgresql + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + spec: + type: object + required: + - numberOfInstances + - teamId + - postgresql + - volume + properties: + additionalVolumes: + type: array + items: + type: object + required: + - name + - mountPath + - volumeSource + properties: + isSubPathExpr: + type: boolean + name: + type: string + mountPath: + type: string + subPath: + type: string + targetContainers: + type: array + nullable: true + items: + type: string + volumeSource: + type: object + x-kubernetes-preserve-unknown-fields: true + allowedSourceRanges: + type: array + nullable: true + items: + type: string + pattern: '^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\/(\d|[1-2]\d|3[0-2])$' + clone: + type: object + required: + - cluster + properties: + cluster: + type: string + s3_endpoint: + type: string + s3_access_key_id: + type: string + s3_secret_access_key: + type: string + s3_force_path_style: + type: boolean + s3_wal_path: + type: string + timestamp: + type: string + pattern: '^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$' + # The regexp matches the date-time format (RFC 3339 Section 5.6) that specifies a timezone as an offset relative to UTC + # Example: 1996-12-19T16:39:57-08:00 + # Note: this field requires a timezone + uid: + format: uuid + type: string + connectionPooler: + type: object + properties: + dockerImage: + type: string + maxDBConnections: + type: integer + mode: + type: string + enum: + - "session" + - "transaction" + numberOfInstances: + type: integer + minimum: 1 + resources: + type: object + properties: + limits: + type: object + properties: + cpu: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + memory: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + requests: + type: object + properties: + cpu: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + memory: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + schema: + type: string + user: + type: string + databases: + type: object + additionalProperties: + type: string + # Note: usernames specified here as database owners must be declared in the users key of the spec key. + dockerImage: + type: string + enableConnectionPooler: + type: boolean + enableReplicaConnectionPooler: + type: boolean + enableLogicalBackup: + type: boolean + enableMasterLoadBalancer: + type: boolean + enableMasterPoolerLoadBalancer: + type: boolean + enableReplicaLoadBalancer: + type: boolean + enableReplicaPoolerLoadBalancer: + type: boolean + enableShmVolume: + type: boolean + env: + type: array + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true + init_containers: + type: array + description: deprecated + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true + initContainers: + type: array + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true + logicalBackupRetention: + type: string + logicalBackupSchedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + maintenanceWindows: + type: array + items: + type: string + pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$' + masterServiceAnnotations: + type: object + additionalProperties: + type: string + nodeAffinity: + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + type: array + items: + type: object + required: + - preference + - weight + properties: + preference: + type: object + properties: + matchExpressions: + type: array + items: + type: object + required: + - key + - operator + properties: + key: + type: string + operator: + type: string + values: + type: array + items: + type: string + matchFields: + type: array + items: + type: object + required: + - key + - operator + properties: + key: + type: string + operator: + type: string + values: + type: array + items: + type: string + weight: + format: int32 + type: integer + requiredDuringSchedulingIgnoredDuringExecution: + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + type: array + items: + type: object + properties: + matchExpressions: + type: array + items: + type: object + required: + - key + - operator + properties: + key: + type: string + operator: + type: string + values: + type: array + items: + type: string + matchFields: + type: array + items: + type: object + required: + - key + - operator + properties: + key: + type: string + operator: + type: string + values: + type: array + items: + type: string + numberOfInstances: + type: integer + minimum: 0 + patroni: + type: object + properties: + failsafe_mode: + type: boolean + initdb: + type: object + additionalProperties: + type: string + loop_wait: + type: integer + maximum_lag_on_failover: + type: integer + pg_hba: + type: array + items: + type: string + retry_timeout: + type: integer + slots: + type: object + additionalProperties: + type: object + additionalProperties: + type: string + synchronous_mode: + type: boolean + synchronous_mode_strict: + type: boolean + synchronous_node_count: + type: integer + ttl: + type: integer + podAnnotations: + type: object + additionalProperties: + type: string + pod_priority_class_name: + type: string + description: deprecated + podPriorityClassName: + type: string + postgresql: + type: object + required: + - version + properties: + version: + type: string + enum: + - "11" + - "12" + - "13" + - "14" + - "15" + - "16" + parameters: + type: object + additionalProperties: + type: string + preparedDatabases: + type: object + additionalProperties: + type: object + properties: + defaultUsers: + type: boolean + extensions: + type: object + additionalProperties: + type: string + schemas: + type: object + additionalProperties: + type: object + properties: + defaultUsers: + type: boolean + defaultRoles: + type: boolean + secretNamespace: + type: string + replicaLoadBalancer: + type: boolean + description: deprecated + replicaServiceAnnotations: + type: object + additionalProperties: + type: string + resources: + type: object + properties: + limits: + type: object + properties: + cpu: + type: string + # Decimal natural followed by m, or decimal natural followed by + # dot followed by up to three decimal digits. + # + # This is because the Kubernetes CPU resource has millis as the + # maximum precision. The actual values are checked in code + # because the regular expression would be huge and horrible and + # not very helpful in validation error messages; this one checks + # only the format of the given number. + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + # Note: the value specified here must not be zero or be lower + # than the corresponding request. + memory: + type: string + # You can express memory as a plain integer or as a fixed-point + # integer using one of these suffixes: E, P, T, G, M, k. You can + # also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero or be higher + # than the corresponding limit. + hugepages-2Mi: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + hugepages-1Gi: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + requests: + type: object + properties: + cpu: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + memory: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + hugepages-2Mi: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + hugepages-1Gi: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + schedulerName: + type: string + serviceAnnotations: + type: object + additionalProperties: + type: string + sidecars: + type: array + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true + spiloRunAsUser: + type: integer + spiloRunAsGroup: + type: integer + spiloFSGroup: + type: integer + standby: + type: object + properties: + s3_wal_path: + type: string + gs_wal_path: + type: string + standby_host: + type: string + standby_port: + type: string + oneOf: + - required: + - s3_wal_path + - required: + - gs_wal_path + - required: + - standby_host + streams: + type: array + items: + type: object + required: + - applicationId + - database + - tables + properties: + applicationId: + type: string + batchSize: + type: integer + database: + type: string + enableRecovery: + type: boolean + filter: + type: object + additionalProperties: + type: string + tables: + type: object + additionalProperties: + type: object + required: + - eventType + properties: + eventType: + type: string + idColumn: + type: string + payloadColumn: + type: string + recoveryEventType: + type: string + teamId: + type: string + tls: + type: object + required: + - secretName + properties: + secretName: + type: string + certificateFile: + type: string + privateKeyFile: + type: string + caFile: + type: string + caSecretName: + type: string + tolerations: + type: array + items: + type: object + properties: + key: + type: string + operator: + type: string + enum: + - Equal + - Exists + value: + type: string + effect: + type: string + enum: + - NoExecute + - NoSchedule + - PreferNoSchedule + tolerationSeconds: + type: integer + useLoadBalancer: + type: boolean + description: deprecated + users: + type: object + additionalProperties: + type: array + nullable: true + items: + type: string + enum: + - bypassrls + - BYPASSRLS + - nobypassrls + - NOBYPASSRLS + - createdb + - CREATEDB + - nocreatedb + - NOCREATEDB + - createrole + - CREATEROLE + - nocreaterole + - NOCREATEROLE + - inherit + - INHERIT + - noinherit + - NOINHERIT + - login + - LOGIN + - nologin + - NOLOGIN + - replication + - REPLICATION + - noreplication + - NOREPLICATION + - superuser + - SUPERUSER + - nosuperuser + - NOSUPERUSER + usersIgnoringSecretRotation: + type: array + nullable: true + items: + type: string + usersWithInPlaceSecretRotation: + type: array + nullable: true + items: + type: string + usersWithSecretRotation: + type: array + nullable: true + items: + type: string + volume: + type: object + required: + - size + properties: + isSubPathExpr: + type: boolean + iops: + type: integer + selector: + type: object + properties: + matchExpressions: + type: array + items: + type: object + required: + - key + - operator + properties: + key: + type: string + operator: + type: string + enum: + - DoesNotExist + - Exists + - In + - NotIn + values: + type: array + items: + type: string + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + size: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero. + storageClass: + type: string + subPath: + type: string + throughput: + type: integer + status: + type: object + additionalProperties: + type: string diff --git a/charts/postgres-operator/crds/postgresteams.yaml b/charts/postgres-operator/crds/postgresteams.yaml new file mode 100644 index 0000000..b7a3684 --- /dev/null +++ b/charts/postgres-operator/crds/postgresteams.yaml @@ -0,0 +1,70 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: postgresteams.acid.zalan.do + labels: + app.kubernetes.io/name: postgres-operator +spec: + group: acid.zalan.do + names: + kind: PostgresTeam + listKind: PostgresTeamList + plural: postgresteams + singular: postgresteam + shortNames: + - pgteam + categories: + - all + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - spec + properties: + kind: + type: string + enum: + - PostgresTeam + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + spec: + type: object + properties: + additionalSuperuserTeams: + type: object + description: "Map for teamId and associated additional superuser teams" + additionalProperties: + type: array + nullable: true + description: "List of teams to become Postgres superusers" + items: + type: string + additionalTeams: + type: object + description: "Map for teamId and associated additional teams" + additionalProperties: + type: array + nullable: true + description: "List of teams whose members will also be added to the Postgres cluster" + items: + type: string + additionalMembers: + type: object + description: "Map for teamId and associated additional users" + additionalProperties: + type: array + nullable: true + description: "List of users who will also be added to the Postgres cluster" + items: + type: string diff --git a/charts/postgres-operator/index.yaml b/charts/postgres-operator/index.yaml new file mode 100644 index 0000000..8442f63 --- /dev/null +++ b/charts/postgres-operator/index.yaml @@ -0,0 +1,158 @@ +apiVersion: v1 +entries: + postgres-operator: + - apiVersion: v2 + appVersion: 1.12.1 + created: "2024-06-10T12:32:31.856484906+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: 152080481a3971ab2f71600dae41d8a29d93d03537c5dff45fb9c995bfd9eef9 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.12.1.tgz + version: 1.12.1 + - apiVersion: v2 + appVersion: 1.12.0 + created: "2024-06-10T12:32:31.848143762+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: d56e9471096d3e0dfd3a35619bfd8e81895979e95a0cad44eb021335814d19cf + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.12.0.tgz + version: 1.12.0 + - apiVersion: v2 + appVersion: 1.11.0 + created: "2024-06-10T12:32:31.84219356+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: 3914b5e117bda0834f05c9207f007e2ac372864cf6e86dcc2e1362bbe46c14d9 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.11.0.tgz + version: 1.11.0 + - apiVersion: v2 + appVersion: 1.10.1 + created: "2024-06-10T12:32:31.836895732+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: cc3baa41753da92466223d0b334df27e79c882296577b404a8e9071411fcf19c + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.10.1.tgz + version: 1.10.1 + - apiVersion: v2 + appVersion: 1.10.0 + created: "2024-06-10T12:32:31.831456969+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: 60fc5c8059dfed175d14e1034b40997d9c59d33ec8ea158c0597f7228ab04b51 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.10.0.tgz + version: 1.10.0 + - apiVersion: v2 + appVersion: 1.9.0 + created: "2024-06-10T12:32:31.867035666+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: 64df90c898ca591eb3a330328173ffaadfbf9ddd474d8c42ed143edc9e3f4276 + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.9.0.tgz + version: 1.9.0 + - apiVersion: v2 + appVersion: 1.8.2 + created: "2024-06-10T12:32:31.86187559+02:00" + description: Postgres Operator creates and manages PostgreSQL clusters running + in Kubernetes + digest: f77ffad2e98b72a621e5527015cf607935d3ed688f10ba4b626435acb9631b5b + home: https://github.com/zalando/postgres-operator + keywords: + - postgres + - operator + - cloud-native + - patroni + - spilo + maintainers: + - email: opensource@zalando.de + name: Zalando + name: postgres-operator + sources: + - https://github.com/zalando/postgres-operator + urls: + - postgres-operator-1.8.2.tgz + version: 1.8.2 +generated: "2024-06-10T12:32:31.825703117+02:00" diff --git a/charts/postgres-operator/templates/NOTES.txt b/charts/postgres-operator/templates/NOTES.txt new file mode 100644 index 0000000..f1fe050 --- /dev/null +++ b/charts/postgres-operator/templates/NOTES.txt @@ -0,0 +1,3 @@ +To verify that postgres-operator has started, run: + + kubectl --namespace={{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ template "postgres-operator.name" . }}" diff --git a/charts/postgres-operator/templates/_helpers.tpl b/charts/postgres-operator/templates/_helpers.tpl new file mode 100644 index 0000000..cb8c69c --- /dev/null +++ b/charts/postgres-operator/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "postgres-operator.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 "postgres-operator.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 a service account name. +*/}} +{{- define "postgres-operator.serviceAccountName" -}} +{{ default (include "postgres-operator.fullname" .) .Values.serviceAccount.name }} +{{- end -}} + +{{/* +Create a pod service account name. +*/}} +{{- define "postgres-pod.serviceAccountName" -}} +{{ default (printf "%s-%v" (include "postgres-operator.fullname" .) "pod") .Values.podServiceAccount.name }} +{{- end -}} + +{{/* +Create a pod priority class name. +*/}} +{{- define "postgres-pod.priorityClassName" -}} +{{ default (printf "%s-%v" (include "postgres-operator.fullname" .) "pod") .Values.podPriorityClassName.name }} +{{- end -}} + +{{/* +Create a controller ID. +*/}} +{{- define "postgres-operator.controllerID" -}} +{{ default (include "postgres-operator.fullname" .) .Values.controllerID.name }} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "postgres-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Flatten nested config options when ConfigMap is used as ConfigTarget +*/}} +{{- define "flattenValuesForConfigMap" }} +{{- range $key, $value := . }} + {{- if kindIs "slice" $value }} +{{ $key }}: {{ join "," $value | quote }} + {{- else if kindIs "map" $value }} + {{- $list := list }} + {{- range $subKey, $subValue := $value }} + {{- $list = append $list (printf "%s:%s" $subKey $subValue) }} + {{- end }} +{{ $key }}: {{ join "," $list | quote }} + {{- else }} +{{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml b/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml new file mode 100644 index 0000000..fdccf16 --- /dev/null +++ b/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml @@ -0,0 +1,71 @@ +{{ if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "postgres-pod.serviceAccountName" . }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +rules: +# Patroni needs to watch and manage config maps or endpoints +{{- if toString .Values.configGeneral.kubernetes_use_configmaps | eq "true" }} +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- else }} +- apiGroups: + - "" + resources: + - endpoints + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} +# Patroni needs to watch pods +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - patch + - update + - watch +# to let Patroni create a headless service +- apiGroups: + - "" + resources: + - services + verbs: + - create +{{- if toString .Values.configKubernetes.spilo_privileged | eq "true" }} +# to run privileged pods +- apiGroups: + - extensions + resources: + - podsecuritypolicies + resourceNames: + - privileged + verbs: + - use +{{- end }} +{{ end }} diff --git a/charts/postgres-operator/templates/clusterrole.yaml b/charts/postgres-operator/templates/clusterrole.yaml new file mode 100644 index 0000000..199086a --- /dev/null +++ b/charts/postgres-operator/templates/clusterrole.yaml @@ -0,0 +1,254 @@ +{{ if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "postgres-operator.serviceAccountName" . }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +rules: +# all verbs allowed for custom operator resources +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + - postgresqls/status + - operatorconfigurations + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +# operator only reads PostgresTeams +- apiGroups: + - acid.zalan.do + resources: + - postgresteams + verbs: + - get + - list + - watch +# all verbs allowed for event streams +{{- if .Values.enableStreams }} +- apiGroups: + - zalando.org + resources: + - fabriceventstreams + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} +# to create or get/update CRDs when starting up +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get +{{- if toString .Values.configGeneral.enable_crd_registration | eq "true" }} + - create + - patch + - update +{{- end }} +# to send events to the CRs +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update + - watch +# to manage endpoints/configmaps which are also used by Patroni +{{- if toString .Values.configGeneral.kubernetes_use_configmaps | eq "true" }} +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- else }} +# to read configuration from ConfigMaps +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resources: + - endpoints + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} +# to CRUD secrets for database access +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - update +# to check nodes for node readiness label +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +# to read or delete existing PVCs. Creation via StatefulSet +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - delete + - get + - list +{{- if toString .Values.configKubernetes.storage_resize_mode | eq "pvc" }} + - patch + - update +{{- end }} + # to read existing PVs. Creation should be done via dynamic provisioning +- apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list +{{- if toString .Values.configKubernetes.storage_resize_mode | eq "ebs" }} + - update # only for resizing AWS volumes +{{- end }} +# to watch Spilo pods and do rolling updates. Creation via StatefulSet +- apiGroups: + - "" + resources: + - pods + verbs: + - delete + - get + - list + - patch + - update + - watch +# to resize the filesystem in Spilo pods when increasing volume size +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create +# to CRUD services to point to Postgres cluster instances +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - patch + - update +# to CRUD the StatefulSet which controls the Postgres cluster instances +- apiGroups: + - apps + resources: + - statefulsets + - deployments + verbs: + - create + - delete + - get + - list + - patch +# to CRUD cron jobs for logical backups +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update +# to get namespaces operator resources can run in +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +# to define PDBs. Update happens via delete/create +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get +# to create ServiceAccounts in each namespace the operator watches +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - create +# to create role bindings to the postgres-pod service account +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - get + - create +{{- if toString .Values.configKubernetes.spilo_privileged | eq "true" }} +# to run privileged pods +- apiGroups: + - extensions + resources: + - podsecuritypolicies + resourceNames: + - privileged + verbs: + - use +{{- end }} +{{ end }} diff --git a/charts/postgres-operator/templates/clusterrolebinding.yaml b/charts/postgres-operator/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..dbf65d0 --- /dev/null +++ b/charts/postgres-operator/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{ if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "postgres-operator.serviceAccountName" . }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "postgres-operator.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "postgres-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/charts/postgres-operator/templates/configmap.yaml b/charts/postgres-operator/templates/configmap.yaml new file mode 100644 index 0000000..9ea5741 --- /dev/null +++ b/charts/postgres-operator/templates/configmap.yaml @@ -0,0 +1,30 @@ +{{- if eq .Values.configTarget "ConfigMap" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgres-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +data: +{{- if or .Values.podPriorityClassName.create .Values.podPriorityClassName.name }} + pod_priority_class_name: {{ include "postgres-pod.priorityClassName" . }} +{{- end }} + pod_service_account_name: {{ include "postgres-pod.serviceAccountName" . }} +{{- include "flattenValuesForConfigMap" .Values.configGeneral | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configUsers | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configMajorVersionUpgrade | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configKubernetes | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configTimeouts | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configLoadBalancer | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configAwsOrGcp | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configLogicalBackup | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configDebug | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configLoggingRestApi | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configTeamsApi | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configConnectionPooler | indent 2 }} +{{- include "flattenValuesForConfigMap" .Values.configPatroni | indent 2 }} +{{- end }} diff --git a/charts/postgres-operator/templates/deployment.yaml b/charts/postgres-operator/templates/deployment.yaml new file mode 100644 index 0000000..1752cb3 --- /dev/null +++ b/charts/postgres-operator/templates/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + annotations: + {{- if eq .Values.configTarget "ConfigMap" }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- else }} + checksum/config: {{ include (print $.Template.BasePath "/operatorconfiguration.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "postgres-operator.serviceAccountName" . }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + {{- if .Values.enableJsonLogging }} + - name: ENABLE_JSON_LOGGING + value: "true" + {{- end }} + {{- if eq .Values.configTarget "ConfigMap" }} + - name: CONFIG_MAP_NAME + value: {{ template "postgres-operator.fullname" . }} + {{- else }} + - name: POSTGRES_OPERATOR_CONFIGURATION_OBJECT + value: {{ template "postgres-operator.fullname" . }} + {{- end }} + {{- if .Values.controllerID.create }} + - name: CONTROLLER_ID + value: {{ template "postgres-operator.controllerID" . }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + securityContext: +{{ toYaml .Values.securityContext | indent 10 }} + {{- if .Values.readinessProbe }} + readinessProbe: + httpGet: + path: /readyz + port: {{ .Values.configLoggingRestApi.api_port }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} diff --git a/charts/postgres-operator/templates/operatorconfiguration.yaml b/charts/postgres-operator/templates/operatorconfiguration.yaml new file mode 100644 index 0000000..b72bfb8 --- /dev/null +++ b/charts/postgres-operator/templates/operatorconfiguration.yaml @@ -0,0 +1,45 @@ +{{- if eq .Values.configTarget "OperatorConfigurationCRD" }} +apiVersion: "acid.zalan.do/v1" +kind: OperatorConfiguration +metadata: + name: {{ template "postgres-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +configuration: +{{ tpl (toYaml .Values.configGeneral) . | indent 2 }} + users: +{{ tpl (toYaml .Values.configUsers) . | indent 4 }} + major_version_upgrade: +{{ tpl (toYaml .Values.configMajorVersionUpgrade) . | indent 4 }} + kubernetes: + {{- if .Values.podPriorityClassName.name }} + pod_priority_class_name: {{ .Values.podPriorityClassName.name }} + {{- end }} + pod_service_account_name: {{ include "postgres-pod.serviceAccountName" . }} + oauth_token_secret_name: {{ template "postgres-operator.fullname" . }} +{{ tpl (toYaml .Values.configKubernetes) . | indent 4 }} + postgres_pod_resources: +{{ tpl (toYaml .Values.configPostgresPodResources) . | indent 4 }} + timeouts: +{{ tpl (toYaml .Values.configTimeouts) . | indent 4 }} + load_balancer: +{{ tpl (toYaml .Values.configLoadBalancer) . | indent 4 }} + aws_or_gcp: +{{ tpl (toYaml .Values.configAwsOrGcp) . | indent 4 }} + logical_backup: +{{ tpl (toYaml .Values.configLogicalBackup) . | indent 4 }} + debug: +{{ tpl (toYaml .Values.configDebug) . | indent 4 }} + teams_api: +{{ tpl (toYaml .Values.configTeamsApi) . | indent 4 }} + logging_rest_api: +{{ tpl (toYaml .Values.configLoggingRestApi) . | indent 4 }} + connection_pooler: +{{ tpl (toYaml .Values.configConnectionPooler) . | indent 4 }} + patroni: +{{ tpl (toYaml .Values.configPatroni) . | indent 4 }} +{{- end }} diff --git a/charts/postgres-operator/templates/postgres-pod-priority-class.yaml b/charts/postgres-operator/templates/postgres-pod-priority-class.yaml new file mode 100644 index 0000000..de78b50 --- /dev/null +++ b/charts/postgres-operator/templates/postgres-pod-priority-class.yaml @@ -0,0 +1,16 @@ +{{- if .Values.podPriorityClassName.create }} +apiVersion: scheduling.k8s.io/v1 +description: 'Use only for databases controlled by Postgres operator' +kind: PriorityClass +metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ include "postgres-pod.priorityClassName" . }} + namespace: {{ .Release.Namespace }} +preemptionPolicy: PreemptLowerPriority +globalDefault: false +value: {{ .Values.podPriorityClassName.priority }} +{{- end }} diff --git a/charts/postgres-operator/templates/service.yaml b/charts/postgres-operator/templates/service.yaml new file mode 100644 index 0000000..c1b5274 --- /dev/null +++ b/charts/postgres-operator/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + ports: + - port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} diff --git a/charts/postgres-operator/templates/serviceaccount.yaml b/charts/postgres-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..4f42559 --- /dev/null +++ b/charts/postgres-operator/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "postgres-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +{{ end }} diff --git a/charts/postgres-operator/templates/user-facing-clusterroles.yaml b/charts/postgres-operator/templates/user-facing-clusterroles.yaml new file mode 100644 index 0000000..d7db347 --- /dev/null +++ b/charts/postgres-operator/templates/user-facing-clusterroles.yaml @@ -0,0 +1,71 @@ +{{ if .Values.rbac.createAggregateClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:admin +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + - postgresqls/status + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:edit +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + verbs: + - create + - update + - patch + - delete + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:view +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + - postgresqls/status + verbs: + - get + - list + - watch +{{ end }} diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml new file mode 100644 index 0000000..5700ff7 --- /dev/null +++ b/charts/postgres-operator/values.yaml @@ -0,0 +1,526 @@ +image: + registry: ghcr.io + repository: zalando/postgres-operator + tag: v1.12.2 + pullPolicy: "IfNotPresent" + +# Optionally specify an array of imagePullSecrets. +# Secrets must be manually created in the namespace. +# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod +# imagePullSecrets: +# - name: myRegistryKeySecretName + +podAnnotations: {} +podLabels: {} + +configTarget: "OperatorConfigurationCRD" + +# JSON logging format +enableJsonLogging: false + +# general configuration parameters +configGeneral: + # the deployment should create/update the CRDs + enable_crd_registration: true + # specify categories under which crds should be listed + crd_categories: + - "all" + # update only the statefulsets without immediately doing the rolling update + enable_lazy_spilo_upgrade: false + # set the PGVERSION env var instead of providing the version via postgresql.bin_dir in SPILO_CONFIGURATION + enable_pgversion_env_var: true + # start any new database pod without limitations on shm memory + enable_shm_volume: true + # enables backwards compatible path between Spilo 12 and Spilo 13+ images + enable_spilo_wal_path_compat: false + # operator will sync only clusters where name starts with teamId prefix + enable_team_id_clustername_prefix: false + # etcd connection string for Patroni. Empty uses K8s-native DCS. + etcd_host: "" + # Spilo docker image + docker_image: ghcr.io/zalando/spilo-16:3.2-p3 + + # key name for annotation to ignore globally configured instance limits + # ignore_instance_limits_annotation_key: "" + + # Select if setup uses endpoints (default), or configmaps to manage leader (DCS=k8s) + # kubernetes_use_configmaps: false + + # min number of instances in Postgres cluster. -1 = no limit + min_instances: -1 + # max number of instances in Postgres cluster. -1 = no limit + max_instances: -1 + # period between consecutive repair requests + repair_period: 5m + # period between consecutive sync requests + resync_period: 30m + # can prevent certain cases of memory overcommitment + # set_memory_request_to_limit: false + + # map of sidecar names to docker images + # sidecar_docker_images: + # example: "exampleimage:exampletag" + + # number of routines the operator spawns to process requests concurrently + workers: 8 + +# parameters describing Postgres users +configUsers: + # roles to be granted to database owners + # additional_owner_roles: + # - cron_admin + + # enable password rotation for app users that are not database owners + enable_password_rotation: false + # rotation interval for updating credentials in K8s secrets of app users + password_rotation_interval: 90 + # retention interval to keep rotation users + password_rotation_user_retention: 180 + # postgres username used for replication between instances + replication_username: standby + # postgres superuser name to be created by initdb + super_username: postgres + +configMajorVersionUpgrade: + # "off": no upgrade, "manual": manifest triggers action, "full": minimal version violation triggers too + major_version_upgrade_mode: "off" + # upgrades will only be carried out for clusters of listed teams when mode is "off" + # major_version_upgrade_team_allow_list: + # - acid + + # minimal Postgres major version that will not automatically be upgraded + minimal_major_version: "12" + # target Postgres major version when upgrading clusters automatically + target_major_version: "16" + +configKubernetes: + # list of additional capabilities for postgres container + # additional_pod_capabilities: + # - "SYS_NICE" + + # default DNS domain of K8s cluster where operator is running + cluster_domain: cluster.local + # additional labels assigned to the cluster objects + cluster_labels: + application: spilo + # label assigned to Kubernetes objects created by the operator + cluster_name_label: cluster-name + # additional annotations to add to every database pod + # custom_pod_annotations: + # keya: valuea + # keyb: valueb + + # key name for annotation that compares manifest value with current date + # delete_annotation_date_key: "delete-date" + + # key name for annotation that compares manifest value with cluster name + # delete_annotation_name_key: "delete-clustername" + + # list of annotations propagated from cluster manifest to statefulset and deployment + # downscaler_annotations: + # - deployment-time + # - downscaler/* + + # allow user secrets in other namespaces than the Postgres cluster + enable_cross_namespace_secret: false + # use finalizers to ensure all managed resources are deleted prior to the postgresql CR + # this avoids stale resources in case the operator misses a delete event or is not running + # during deletion + enable_finalizers: false + # enables initContainers to run actions before Spilo is started + enable_init_containers: true + # toggles if operator should delete secrets on cluster deletion + enable_secrets_deletion: true + # toggles if operator should delete PVCs on cluster deletion + enable_persistent_volume_claim_deletion: true + # toggles pod anti affinity on the Postgres pods + enable_pod_antiaffinity: false + # toggles PDB to set to MinAvailabe 0 or 1 + enable_pod_disruption_budget: true + # toogles readiness probe for database pods + enable_readiness_probe: false + # enables sidecar containers to run alongside Spilo in the same pod + enable_sidecars: true + + # annotations to be ignored when comparing statefulsets, services etc. + # ignored_annotations: + # - k8s.v1.cni.cncf.io/network-status + + # namespaced name of the secret containing infrastructure roles names and passwords + # infrastructure_roles_secret_name: postgresql-infrastructure-roles + + # list of annotation keys that can be inherited from the cluster manifest + # inherited_annotations: + # - owned-by + + # list of label keys that can be inherited from the cluster manifest + # inherited_labels: + # - application + # - environment + + # timeout for successful migration of master pods from unschedulable node + # master_pod_move_timeout: 20m + + # set of labels that a running and active node should possess to be considered ready + # node_readiness_label: + # status: ready + + # defines how nodeAffinity from manifest should be merged with node_readiness_label + # node_readiness_label_merge: "OR" + + # namespaced name of the secret containing the OAuth2 token to pass to the teams API + # oauth_token_secret_name: postgresql-operator + + # toggle if `spilo-role=master` selector should be added to the PDB (Pod Disruption Budget) + pdb_master_label_selector: true + # defines the template for PDB names + pdb_name_format: "postgres-{cluster}-pdb" + # specify the PVC retention policy when scaling down and/or deleting + persistent_volume_claim_retention_policy: + when_deleted: "retain" + when_scaled: "retain" + # switches pod anti affinity type to `preferredDuringSchedulingIgnoredDuringExecution` + pod_antiaffinity_preferred_during_scheduling: false + # override topology key for pod anti affinity + pod_antiaffinity_topology_key: "kubernetes.io/hostname" + # namespaced name of the ConfigMap with environment variables to populate on every pod + # pod_environment_configmap: "default/my-custom-config" + # name of the Secret (in cluster namespace) with environment variables to populate on every pod + # pod_environment_secret: "my-custom-secret" + + # specify the pod management policy of stateful sets of Postgres clusters + pod_management_policy: "ordered_ready" + # label assigned to the Postgres pods (and services/endpoints) + pod_role_label: spilo-role + # service account definition as JSON/YAML string to be used by postgres cluster pods + # pod_service_account_definition: "" + + # role binding definition as JSON/YAML string to be used by pod service account + # pod_service_account_role_binding_definition: "" + + # Postgres pods are terminated forcefully after this timeout + pod_terminate_grace_period: 5m + # template for database user secrets generated by the operator, + # here username contains the namespace in the format namespace.username + # if the user is in different namespace than cluster and cross namespace secrets + # are enabled via `enable_cross_namespace_secret` flag in the configuration. + secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" + # sharing unix socket of PostgreSQL (`pg_socket`) with the sidecars + share_pgsocket_with_sidecars: false + # set user and group for the spilo container (required to run Spilo as non-root process) + # spilo_runasuser: 101 + # spilo_runasgroup: 103 + + # group ID with write-access to volumes (required to run Spilo as non-root process) + # spilo_fsgroup: 103 + + # whether the Spilo container should run in privileged mode + spilo_privileged: false + # whether the Spilo container should run with additional permissions other than parent. + # required by cron which needs setuid + spilo_allow_privilege_escalation: true + # storage resize strategy, available options are: ebs, pvc, off or mixed + storage_resize_mode: pvc + # pod toleration assigned to instances of every Postgres cluster + # toleration: + # key: db-only + # operator: Exists + # effect: NoSchedule + + # operator watches for postgres objects in the given namespace + watched_namespace: "*" # listen to all namespaces + +# configure resource requests for the Postgres pods +configPostgresPodResources: + # CPU limits for the postgres containers + default_cpu_limit: "1" + # CPU request value for the postgres containers + default_cpu_request: 100m + # memory limits for the postgres containers + default_memory_limit: 500Mi + # memory request value for the postgres containers + default_memory_request: 100Mi + # optional upper boundary for CPU request + # max_cpu_request: "1" + + # optional upper boundary for memory request + # max_memory_request: 4Gi + + # hard CPU minimum required to properly run a Postgres cluster + min_cpu_limit: 250m + # hard memory minimum required to properly run a Postgres cluster + min_memory_limit: 250Mi + +# timeouts related to some operator actions +configTimeouts: + # interval between consecutive attempts of operator calling the Patroni API + patroni_api_check_interval: 1s + # timeout when waiting for successful response from Patroni API + patroni_api_check_timeout: 5s + # timeout when waiting for the Postgres pods to be deleted + pod_deletion_wait_timeout: 10m + # timeout when waiting for pod role and cluster labels + pod_label_wait_timeout: 10m + # interval between consecutive attempts waiting for postgresql CRD to be created + ready_wait_interval: 3s + # timeout for the complete postgres CRD creation + ready_wait_timeout: 30s + # interval to wait between consecutive attempts to check for some K8s resources + resource_check_interval: 3s + # timeout when waiting for the presence of a certain K8s resource (e.g. Sts, PDB) + resource_check_timeout: 10m + +# configure behavior of load balancers +configLoadBalancer: + # DNS zone for cluster DNS name when load balancer is configured for cluster + db_hosted_zone: db.example.com + # annotations to apply to service when load balancing is enabled + # custom_service_annotations: + # keyx: valuez + # keya: valuea + + # toggles service type load balancer pointing to the master pod of the cluster + enable_master_load_balancer: false + # toggles service type load balancer pointing to the master pooler pod of the cluster + enable_master_pooler_load_balancer: false + # toggles service type load balancer pointing to the replica pod of the cluster + enable_replica_load_balancer: false + # toggles service type load balancer pointing to the replica pooler pod of the cluster + enable_replica_pooler_load_balancer: false + # define external traffic policy for the load balancer + external_traffic_policy: "Cluster" + # defines the DNS name string template for the master load balancer cluster + master_dns_name_format: "{cluster}.{namespace}.{hostedzone}" + # deprecated DNS template for master load balancer using team name + master_legacy_dns_name_format: "{cluster}.{team}.{hostedzone}" + # defines the DNS name string template for the replica load balancer cluster + replica_dns_name_format: "{cluster}-repl.{namespace}.{hostedzone}" + # deprecated DNS template for replica load balancer using team name + replica_legacy_dns_name_format: "{cluster}-repl.{team}.{hostedzone}" + +# options to aid debugging of the operator itself +configDebug: + # toggles verbose debug logs from the operator + debug_logging: true + # toggles operator functionality that require access to the postgres database + enable_database_access: true + +# parameters affecting logging and REST API listener +configLoggingRestApi: + # REST API listener listens to this port + api_port: 8080 + # number of entries in the cluster history ring buffer + cluster_history_entries: 1000 + # number of lines in the ring buffer used to store cluster logs + ring_log_lines: 100 + +# configure interaction with non-Kubernetes objects from AWS or GCP +configAwsOrGcp: + # Additional Secret (aws or gcp credentials) to mount in the pod + # additional_secret_mount: "some-secret-name" + + # Path to mount the above Secret in the filesystem of the container(s) + # additional_secret_mount_path: "/some/dir" + + # AWS region used to store EBS volumes + aws_region: eu-central-1 + + # enable automatic migration on AWS from gp2 to gp3 volumes + enable_ebs_gp3_migration: false + # defines maximum volume size in GB until which auto migration happens + # enable_ebs_gp3_migration_max_size: 1000 + + # GCP credentials that will be used by the operator / pods + # gcp_credentials: "" + + # AWS IAM role to supply in the iam.amazonaws.com/role annotation of Postgres pods + # kube_iam_role: "" + + # S3 bucket to use for shipping postgres daily logs + # log_s3_bucket: "" + + # S3 bucket to use for shipping WAL segments with WAL-E + # wal_s3_bucket: "" + + # GCS bucket to use for shipping WAL segments with WAL-E + # wal_gs_bucket: "" + + # Azure Storage Account to use for shipping WAL segments with WAL-G + # wal_az_storage_account: "" + +# configure K8s cron job managed by the operator +configLogicalBackup: + # Azure Storage Account specs to store backup results + # logical_backup_azure_storage_account_name: "" + # logical_backup_azure_storage_container: "" + # logical_backup_azure_storage_account_key: "" + + # resources for logical backup pod, if empty configPostgresPodResources will be used + # logical_backup_cpu_limit: "" + # logical_backup_cpu_request: "" + # logical_backup_memory_limit: "" + # logical_backup_memory_request: "" + + # image for pods of the logical backup job (example runs pg_dumpall) + logical_backup_docker_image: "ghcr.io/zalando/postgres-operator/logical-backup:v1.12.2" + # path of google cloud service account json file + # logical_backup_google_application_credentials: "" + + # prefix for the backup job name + logical_backup_job_prefix: "logical-backup-" + # storage provider - either "s3", "gcs" or "az" + logical_backup_provider: "s3" + # S3 Access Key ID + logical_backup_s3_access_key_id: "" + # S3 bucket to store backup results + logical_backup_s3_bucket: "my-bucket-url" + # S3 bucket prefix to use + logical_backup_s3_bucket_prefix: "spilo" + # S3 region of bucket + logical_backup_s3_region: "" + # S3 endpoint url when not using AWS + logical_backup_s3_endpoint: "" + # S3 Secret Access Key + logical_backup_s3_secret_access_key: "" + # S3 server side encryption + logical_backup_s3_sse: "AES256" + # S3 retention time for stored backups for example "2 week" or "7 days" + logical_backup_s3_retention_time: "" + # backup schedule in the cron format + logical_backup_schedule: "30 00 * * *" + # secret to be used as reference for env variables in cronjob + logical_backup_cronjob_environment_secret: "" + +# automate creation of human users with teams API service +configTeamsApi: + # team_admin_role will have the rights to grant roles coming from PG manifests + enable_admin_role_for_users: true + # operator watches for PostgresTeam CRs to assign additional teams and members to clusters + enable_postgres_team_crd: false + # toogle to create additional superuser teams from PostgresTeam CRs + enable_postgres_team_crd_superusers: false + # toggle to automatically rename roles of former team members and deny LOGIN + enable_team_member_deprecation: false + # toggle to grant superuser to team members created from the Teams API + enable_team_superuser: false + # toggles usage of the Teams API by the operator + enable_teams_api: false + # should contain a URL to use for authentication (username and token) + # pam_configuration: https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees + + # operator will add all team member roles to this group and add a pg_hba line + pam_role_name: zalandos + # List of teams which members need the superuser role in each Postgres cluster + postgres_superuser_teams: + - postgres_superusers + # List of roles that cannot be overwritten by an application, team or infrastructure role + protected_role_names: + - admin + - cron_admin + # Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD + role_deletion_suffix: "_deleted" + # role name to grant to team members created from the Teams API + team_admin_role: admin + # postgres config parameters to apply to each team member role + team_api_role_configuration: + log_statement: all + # URL of the Teams API service + # teams_api_url: http://fake-teams-api.default.svc.cluster.local + +# configure connection pooler deployment created by the operator +configConnectionPooler: + # db schema to install lookup function into + connection_pooler_schema: "pooler" + # db user for pooler to use + connection_pooler_user: "pooler" + # docker image + connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-32" + # max db connections the pooler should hold + connection_pooler_max_db_connections: 60 + # default pooling mode + connection_pooler_mode: "transaction" + # number of pooler instances + connection_pooler_number_of_instances: 2 + # default resources + connection_pooler_default_cpu_request: 500m + connection_pooler_default_memory_request: 100Mi + connection_pooler_default_cpu_limit: "1" + connection_pooler_default_memory_limit: 100Mi + +configPatroni: + # enable Patroni DCS failsafe_mode feature + enable_patroni_failsafe_mode: false + +# Zalando's internal CDC stream feature +enableStreams: false + +rbac: + # Specifies whether RBAC resources should be created + create: true + # Specifies whether ClusterRoles that are aggregated into the K8s default roles should be created. (https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings) + createAggregateClusterRoles: false + +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: + +podServiceAccount: + # The name of the ServiceAccount to be used by postgres cluster pods + # If not set a name is generated using the fullname template and "-pod" suffix + name: "postgres-pod" + +# priority class for operator pod +priorityClassName: "" + +# priority class for database pods +podPriorityClassName: + # If create is false with no name set, no podPriorityClassName is specified. + # Hence, the pod priorityClass is the one with globalDefault set. + # If there is no PriorityClass with globalDefault set, the priority of Pods with no priorityClassName is zero. + create: true + # If not set a name is generated using the fullname template and "-pod" suffix + name: "" + priority: 1000000 + +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 100m + memory: 250Mi + +securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + +# Allow to setup operator Deployment readiness probe +readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + +# Affinity for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +controllerID: + # Specifies whether a controller ID should be defined for the operator + # Note, all postgres manifest must then contain the following annotation to be found by this operator + # "acid.zalan.do/controller": + create: false + # The name of the controller ID to use. + # If not set and create is true, a name is generated using the fullname template + name: