Skip to content

Commit e4140b8

Browse files
authored
feat(drycc-addons): add postgresql-cluster (#14)
1 parent b599cc9 commit e4140b8

48 files changed

Lines changed: 2203 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
annotations:
2+
category: Database
3+
apiVersion: v2
4+
appVersion: "15"
5+
dependencies:
6+
- name: common
7+
repository: oci://registry.drycc.cc/charts
8+
version: ~1.1.1
9+
description: PostgreSQL (Postgres) is an open source object-relational database known for reliability and data integrity. ACID-compliant, it supports foreign keys, joins, views, triggers and stored procedures.
10+
engine: gotpl
11+
home: https://github.com/bitnami/charts/tree/master/bitnami/postgresql
12+
icon: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png
13+
keywords:
14+
- postgresql
15+
- postgres
16+
- database
17+
- sql
18+
- replication
19+
- cluster
20+
- patroni
21+
maintainers:
22+
- email: zhang.eamon@hotmail.com
23+
name: zhangeamon
24+
name: postgresql
25+
sources:
26+
- https://github.com/drycc-addons/
27+
- https://www.postgresql.org/
28+
version: 15.3.1
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# ⚠️ Repo Archive Notice
2+
3+
As of Nov 13, 2020, charts in this repo will no longer be updated.
4+
For more information, see the Helm Charts [Deprecation and Archive Notice](https://github.com/helm/charts#%EF%B8%8F-deprecation-and-archive-notice), and [Update](https://helm.sh/blog/charts-repo-deprecation/).
5+
6+
# Patroni Helm Chart
7+
8+
This directory contains a Kubernetes chart to deploy a five node [Patroni](https://github.com/zalando/patroni/) cluster using a [Spilo](https://github.com/zalando/spilo) and a StatefulSet.
9+
10+
11+
## Prerequisites Details
12+
* Kubernetes 1.9+
13+
* PV support on the underlying infrastructure
14+
15+
## StatefulSet Details
16+
* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
17+
18+
## StatefulSet Caveats
19+
* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations
20+
21+
22+
## Chart Details
23+
This chart will do the following:
24+
25+
* Implement a HA scalable PostgreSQL 10 cluster using a Kubernetes StatefulSet.
26+
27+
## Installing the Chart
28+
29+
To install the chart with the release name `my-release`:
30+
31+
```console
32+
$ helm repo add
33+
$ helm dependency update
34+
$ helm install --name my-release postgresql-cluster
35+
```
36+
37+
To install the chart with randomly generated passwords:
38+
39+
```console
40+
$ helm install --name my-release postgresql-cluster \
41+
--set credentials.superuser="$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32)",credentials.admin="$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32)",credentials.standby="$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32)"
42+
```
43+
44+
## Connecting to PostgreSQL
45+
46+
Your access point is a cluster IP. In order to access it spin up another pod:
47+
48+
```console
49+
$ kubectl run -i --tty --rm psql --image=postgres --restart=Never -- bash -il
50+
```
51+
52+
Then, from inside the pod, connect to PostgreSQL:
53+
54+
```console
55+
$ psql -U admin -h my-release-patroni.default.svc.cluster.local postgres
56+
<admin password from values.yaml>
57+
postgres=>
58+
```
59+
60+
## Configuration
61+
62+
The following table lists the configurable parameters of the patroni chart and their default values.
63+
64+
| Parameter | Description | Default |
65+
|-----------------------------------|---------------------------------------------|-----------------------------------------------------|
66+
| `nameOverride` | Override the name of the chart | `nil` |
67+
| `fullnameOverride` | Override the fullname of the chart | `nil` |
68+
| `replicaCount` | Amount of pods to spawn | `5` |
69+
| `image.repository` | The image to pull | `registry.opensource.zalan.do/acid/spilo-10` |
70+
| `image.tag` | The version of the image to pull | `1.5-p5` |
71+
| `image.pullPolicy` | The pull policy | `IfNotPresent` |
72+
| `credentials.superuser` | Password of the superuser | `tea` |
73+
| `credentials.admin` | Password of the admin | `cola` |
74+
| `credentials.standby` | Password of the replication user | `pinacolada` |
75+
| `kubernetes.dcs.enable` | Using Kubernetes as DCS | `true` |
76+
| `kubernetes.configmaps.enable` | Using Kubernetes configmaps instead of endpoints | `false` |
77+
| `etcd.enable` | Using etcd as DCS | `false` |
78+
| `etcd.deployChart` | Deploy etcd chart | `false` |
79+
| `etcd.host` | Host name of etcd cluster | `nil` |
80+
| `etcd.discovery` | Domain name of etcd cluster | `nil` |
81+
| `zookeeper.enable` | Using ZooKeeper as DCS | `false` |
82+
| `zookeeper.deployChart` | Deploy ZooKeeper chart | `false` |
83+
| `zookeeper.hosts` | List of ZooKeeper cluster members | `host1:port1,host2:port,etc...` |
84+
| `consul.enable` | Using Consul as DCS | `false` |
85+
| `consul.deployChart` | Deploy Consul chart | `false` |
86+
| `consul.host` | Host name of consul cluster | `nil` |
87+
| `env` | Extra custom environment variables | `{}` |
88+
| `walE.enable` | Use of Wal-E tool for base backup/restore | `false` |
89+
| `walE.scheduleCronJob` | Schedule of Wal-E backups | `00 01 * * *` |
90+
| `walE.retainBackups` | Number of base backups to retain | `2` |
91+
| `walE.s3Bucket:` | Amazon S3 bucket used for wal-e backups | `nil` |
92+
| `walE.gcsBucket` | GCS storage used for Wal-E backups | `nil` |
93+
| `walE.kubernetesSecret` | K8s secret name for provider bucket | `nil` |
94+
| `walE.backupThresholdMegabytes` | Maximum size of the WAL segments accumulated after the base backup to consider WAL-E restore instead of pg_basebackup | `1024` |
95+
| `walE.backupThresholdPercentage` | Maximum ratio (in percents) of the accumulated WAL files to the base backup to consider WAL-E restore instead of pg_basebackup | `30` |
96+
| `resources` | Any resources you wish to assign to the pod | `{}` |
97+
| `nodeSelector` | Node label to use for scheduling | `{}` |
98+
| `tolerations` | List of node taints to tolerate | `[]` |
99+
| `affinityTemplate` | A template string to use to generate the affinity settings | Anti-affinity preferred on hostname |
100+
| `affinity` | Affinity settings. Overrides `affinityTemplate` if set. | `{}` |
101+
| `schedulerName` | Alternate scheduler name | `nil` |
102+
| `persistentVolume.accessModes` | Persistent Volume access modes | `[ReadWriteOnce]` |
103+
| `persistentVolume.annotations` | Annotations for Persistent Volume Claim` | `{}` |
104+
| `persistentVolume.mountPath` | Persistent Volume mount root path | `/home/postgres/pgdata` |
105+
| `persistentVolume.size` | Persistent Volume size | `2Gi` |
106+
| `persistentVolume.storageClass` | Persistent Volume Storage Class | `volume.alpha.kubernetes.io/storage-class: default` |
107+
| `persistentVolume.subPath` | Subdirectory of Persistent Volume to mount | `""` |
108+
| `rbac.create` | Create required role and rolebindings | `true` |
109+
| `serviceAccount.create` | If true, create a new service account | `true` |
110+
| `serviceAccount.name` | Service account to be used. If not set and `serviceAccount.create` is `true`, a name is generated using the fullname template | `nil` |
111+
112+
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.
113+
114+
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
115+
116+
```console
117+
$ helm install --name my-release -f values.yaml incubator/patroni
118+
```
119+
120+
> **Tip**: You can use the default [values.yaml](values.yaml)
121+
122+
## Cleanup
123+
124+
To remove the spawned pods you can run a simple `helm delete <release-name>`.
125+
126+
Helm will however preserve created persistent volume claims,
127+
to also remove them execute the commands below.
128+
129+
```console
130+
$ release=<release-name>
131+
$ helm delete $release
132+
$ kubectl delete pvc -l release=$release
133+
```
134+
135+
## Internals
136+
137+
Patroni is responsible for electing a PostgreSQL master pod by leveraging the
138+
DCS of your choice. After election it adds a `spilo-role=master` label to the
139+
elected master and set the label to `spilo-role=replica` for all replicas.
140+
Simultaneously it will update the `<release-name>-patroni` endpoint to let the
141+
service route traffic to the elected master.
142+
143+
```console
144+
$ kubectl get pods -l spilo-role -L spilo-role
145+
NAME READY STATUS RESTARTS AGE SPILO-ROLE
146+
my-release-patroni-0 1/1 Running 0 9m replica
147+
my-release-patroni-1 1/1 Running 0 9m master
148+
my-release-patroni-2 1/1 Running 0 8m replica
149+
my-release-patroni-3 1/1 Running 0 8m replica
150+
my-release-patroni-4 1/1 Running 0 8m replica
151+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Patroni can be accessed via port 5432 on the following DNS name from within your cluster:
2+
{{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
3+
4+
To get your password for superuser run:
5+
6+
# superuser password
7+
PGPASSWORD_SUPERUSER=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "patroni.fullname" . }} -o jsonpath="{.data.password-superuser}" | base64 --decode)
8+
9+
# admin password
10+
PGPASSWORD_ADMIN=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "patroni.fullname" . }} -o jsonpath="{.data.password-admin}" | base64 --decode)
11+
12+
To connect to your database:
13+
14+
1. Run a postgres pod and connect using the psql cli:
15+
# login as superuser
16+
kubectl run -i --tty --rm psql --image=postgres \
17+
--env "PGPASSWORD=$PGPASSWORD_SUPERUSER" \
18+
--command -- psql -U postgres \
19+
-h {{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres
20+
21+
# login as admin
22+
kubectl run -i -tty --rm psql --image=postgres \
23+
--env "PGPASSWORD=$PGPASSWORD_ADMIN" \
24+
--command -- psql -U admin \
25+
-h {{ template "patroni.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
{{/* vim: set filetype=mustache: */}}
2+
{{/*
3+
Expand the name of the chart.
4+
*/}}
5+
{{- define "patroni.name" -}}
6+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7+
{{- end -}}
8+
9+
{{/*
10+
Create a default fully qualified app name.
11+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12+
If release name contains chart name it will be used as a full name.
13+
*/}}
14+
{{- define "patroni.fullname" -}}
15+
{{- if .Values.fullnameOverride -}}
16+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
17+
{{- else -}}
18+
{{- $name := default .Chart.Name .Values.nameOverride -}}
19+
{{- if contains $name .Release.Name -}}
20+
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
21+
{{- else -}}
22+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
23+
{{- end -}}
24+
{{- end -}}
25+
{{- end -}}
26+
27+
{{/*
28+
Create chart name and version as used by the chart label.
29+
*/}}
30+
{{- define "patroni.chart" -}}
31+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
32+
{{- end -}}
33+
34+
{{/*
35+
Create the name of the service account to use.
36+
*/}}
37+
{{- define "patroni.serviceAccountName" -}}
38+
{{- if .Values.serviceAccount.create -}}
39+
{{ default (include "patroni.fullname" .) .Values.serviceAccount.name }}
40+
{{- else -}}
41+
{{ default "default" .Values.serviceAccount.name }}
42+
{{- end -}}
43+
{{- end -}}
44+
45+
{{/*
46+
Return true if a cronjob object should be created for Postgresql HA patroni ## TODO feature
47+
*/}}
48+
{{- define "patroni.createCronJob" -}}
49+
{{- if and .Values.walG.enabled }}
50+
{{- true -}}
51+
{{- else -}}
52+
{{- end -}}
53+
{{- end -}}
54+
55+
{{/*
56+
Return true if a configmap object should be created for Postgresql HA patroni
57+
*/}}
58+
{{- define "patroni.createConfigmap" -}}
59+
{{- if and .Values.preInitScript }}
60+
{{- true -}}
61+
{{- else -}}
62+
{{- end -}}
63+
{{- end -}}
64+
65+
{{/*
66+
Create patroni envs.
67+
*/}}
68+
{{- define "patroni.envs" }}
69+
{{- if .Values.kubernetes.configmaps.enable }}
70+
- name: KUBERNETES_USE_CONFIGMAPS
71+
value: "true"
72+
{{- end }}
73+
{{- if .Values.kubernetes.endpoints.enable }}
74+
- name: PATRONI_KUBERNETES_USE_ENDPOINTS
75+
value: 'true'
76+
{{- end }}
77+
- name: PATRONI_KUBERNETES_POD_IP
78+
valueFrom:
79+
fieldRef:
80+
fieldPath: status.podIP
81+
- name: PATRONI_KUBERNETES_NAMESPACE
82+
valueFrom:
83+
fieldRef:
84+
fieldPath: metadata.namespace
85+
- name: PATRONI_KUBERNETES_BYPASS_API_SERVICE
86+
value: 'true'
87+
- name: PATRONI_KUBERNETES_LABELS
88+
value: '{application: {{ template "patroni.fullname" . }},release: {{ .Release.Name }},cluster-name: {{ template "patroni.fullname" . }}}'
89+
- name: PATRONI_SUPERUSER_USERNAME
90+
value: postgres
91+
- name: PATRONI_SUPERUSER_PASSWORD
92+
valueFrom:
93+
secretKeyRef:
94+
name: {{ template "patroni.fullname" . }}
95+
key: password-superuser
96+
- name: PATRONI_REPLICATION_USERNAME
97+
value: standby
98+
- name: PATRONI_REPLICATION_PASSWORD
99+
valueFrom:
100+
secretKeyRef:
101+
name: {{ template "patroni.fullname" . }}
102+
key: password-replication
103+
- name: PATRONI_REWIND_USERNAME
104+
value: rewinder
105+
- name: PATRONI_REWIND_PASSWORD
106+
valueFrom:
107+
secretKeyRef:
108+
name: {{ template "patroni.fullname" . }}
109+
key: password-rewind
110+
- name: PATRONI_SCOPE
111+
value: {{ template "patroni.fullname" . }}
112+
- name: PATRONI_NAME
113+
valueFrom:
114+
fieldRef:
115+
fieldPath: metadata.name
116+
- name: PATRONI_POSTGRESQL_DATA_DIR
117+
value: "{{ .Values.persistentVolume.mountPath }}/data"
118+
- name: PGDATA
119+
value: "{{ .Values.persistentVolume.mountPath }}/data"
120+
- name: PATRONI_POSTGRESQL_PGPASS
121+
value: /tmp/pgpass
122+
- name: PATRONI_POSTGRESQL_LISTEN
123+
value: '0.0.0.0:5432'
124+
- name: PATRONI_RESTAPI_LISTEN
125+
value: '0.0.0.0:8008'
126+
- name: DATABASE_NAME
127+
valueFrom:
128+
secretKeyRef:
129+
name: {{ template "patroni.fullname" . }}
130+
key: data-name
131+
- name: DATABASE_USER
132+
valueFrom:
133+
secretKeyRef:
134+
name: {{ template "patroni.fullname" . }}
135+
key: data-user
136+
- name: DATABASE_PASSWORD
137+
valueFrom:
138+
secretKeyRef:
139+
name: {{ template "patroni.fullname" . }}
140+
key: data-password
141+
{{- end -}}
142+
143+
{{/*
144+
Create walg envs.
145+
*/}}
146+
{{- define "walg.envs" }}
147+
{{- if .Values.walG.enabled }}
148+
- name: USE_WALG
149+
value: {{ .Values.walG.enabled | quote }}
150+
{{- if .Values.walG.retainBackups }}
151+
- name: BACKUP_NUM_TO_RETAIN
152+
value: {{ .Values.walG.retainBackups | quote}}
153+
{{- end }}
154+
{{- if .Values.walG.backupThresholdMegabytes }}
155+
- name: WALG_BACKUP_THRESHOLD_MEGABYTES
156+
value: {{ .Values.walG.backupThresholdMegabytes | quote }}
157+
{{- end }}
158+
{{- if .Values.walG.backupThresholdPercentage }}
159+
- name: WALE_BACKUP_THRESHOLD_PERCENTAGE
160+
value: {{ .Values.walG.backupThresholdPercentage | quote }}
161+
{{- end }}
162+
{{- if .Values.walG.s3.used }}
163+
- name: AWS_ACCESS_KEY_ID
164+
value: {{ .Values.walG.s3.awsAccessKeyID | quote }}
165+
- name: AWS_SECRET_ACCESS_KEY
166+
value: {{ .Values.walG.s3.awsSecretAccessKey | quote }}
167+
- name: WALG_S3_PREFIX
168+
value: {{ .Values.walG.s3.walGS3Prefix | quote }}
169+
- name: AWS_ENDPOINT
170+
value: {{ .Values.walG.s3.awsEndpoint | quote }}
171+
- name: AWS_S3_FORCE_PATH_STYLE
172+
value: {{ .Values.walG.s3.awsS3ForcePathStyle | quote }}
173+
- name: AWS_REGION
174+
value: {{ .Values.walG.s3.awsRegion | quote }}
175+
{{- end }}
176+
{{- else }}
177+
- name: USE_WALG
178+
value: ""
179+
{{- end }}
180+
{{- end }}

0 commit comments

Comments
 (0)