From 0e09b91db0431c213829cb20921cc6b27fe51ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20R=2E=20de=20Miranda?= Date: Fri, 15 Jan 2021 08:21:04 -0300 Subject: [PATCH 1/3] Changes from repository https://github.com/helm/charts/tree/master/stable/stolon --- stolon/Chart.yaml | 10 +- stolon/templates/NOTES.txt | 9 +- stolon/templates/_helpers.tpl | 47 ++- stolon/templates/certs.yaml | 19 ++ stolon/templates/cluster-create-job.yaml | 51 --- stolon/templates/configmap.yaml | 35 ++ .../templates/hooks/create-cluster-job.yaml | 50 +++ stolon/templates/hooks/init-db-job.yaml | 76 +++++ .../hooks/update-cluster-spec-job.yaml | 50 +++ stolon/templates/keeper-headless-service.yaml | 24 ++ stolon/templates/keeper-pdb.yaml | 18 + stolon/templates/keeper-ro-service.yaml | 24 -- stolon/templates/keeper-statefulset.yaml | 293 +++++++++++----- stolon/templates/metrics-service.yaml | 19 ++ stolon/templates/metrics-servicemonitor.yaml | 35 ++ stolon/templates/proxy-deploy.yaml | 76 ----- stolon/templates/proxy-deployment.yaml | 94 ++++++ stolon/templates/proxy-pdb.yaml | 18 + stolon/templates/proxy-service.yaml | 44 ++- stolon/templates/psp-role.yaml | 16 + stolon/templates/psp-rolebinding.yaml | 18 + stolon/templates/psp.yaml | 35 ++ .../templates/{stolon-role.yaml => role.yaml} | 8 +- stolon/templates/rolebinding.yaml | 18 + stolon/templates/secret.yaml | 24 +- stolon/templates/sentinel-deploy.yaml | 68 ---- stolon/templates/sentinel-deployment.yaml | 88 +++++ stolon/templates/sentinel-pdb.yaml | 18 + ...erviceaccount.yaml => serviceaccount.yaml} | 7 +- stolon/values.yaml | 316 ++++++++++-------- 30 files changed, 1094 insertions(+), 514 deletions(-) mode change 100755 => 100644 stolon/Chart.yaml create mode 100644 stolon/templates/certs.yaml delete mode 100644 stolon/templates/cluster-create-job.yaml create mode 100644 stolon/templates/configmap.yaml create mode 100644 stolon/templates/hooks/create-cluster-job.yaml create mode 100644 stolon/templates/hooks/init-db-job.yaml create mode 100644 stolon/templates/hooks/update-cluster-spec-job.yaml create mode 100644 stolon/templates/keeper-headless-service.yaml create mode 100644 stolon/templates/keeper-pdb.yaml delete mode 100644 stolon/templates/keeper-ro-service.yaml create mode 100644 stolon/templates/metrics-service.yaml create mode 100644 stolon/templates/metrics-servicemonitor.yaml delete mode 100644 stolon/templates/proxy-deploy.yaml create mode 100644 stolon/templates/proxy-deployment.yaml create mode 100644 stolon/templates/proxy-pdb.yaml create mode 100644 stolon/templates/psp-role.yaml create mode 100644 stolon/templates/psp-rolebinding.yaml create mode 100644 stolon/templates/psp.yaml rename stolon/templates/{stolon-role.yaml => role.yaml} (71%) create mode 100644 stolon/templates/rolebinding.yaml delete mode 100644 stolon/templates/sentinel-deploy.yaml create mode 100644 stolon/templates/sentinel-deployment.yaml create mode 100644 stolon/templates/sentinel-pdb.yaml rename stolon/templates/{stolon-serviceaccount.yaml => serviceaccount.yaml} (63%) diff --git a/stolon/Chart.yaml b/stolon/Chart.yaml old mode 100755 new mode 100644 index a5f444a..29907a5 --- a/stolon/Chart.yaml +++ b/stolon/Chart.yaml @@ -1,9 +1,9 @@ apiVersion: v1 name: stolon -version: 0.8.1 -appVersion: 0.13.0 +version: 1.6.5 +appVersion: 0.16.0 +description: Stolon - PostgreSQL cloud native High Availability. home: https://github.com/sorintlab/stolon -description: Stolon Helm Chart for Kubernetes. icon: https://i.imgur.com/tIW8sAW.png sources: - https://github.com/sorintlab/stolon @@ -13,3 +13,7 @@ maintainers: email: ipaq.lw@gmail.com - name: Ryan Luckie email: rluckie@cisco.com +sources: + - https://github.com/sorintlab/stolon + - https://github.com/lwolf/stolon-chart +engine: gotpl diff --git a/stolon/templates/NOTES.txt b/stolon/templates/NOTES.txt index 2070240..0150a49 100644 --- a/stolon/templates/NOTES.txt +++ b/stolon/templates/NOTES.txt @@ -1,5 +1,10 @@ -Helm cluster in installed and initialized. - +Stolon cluster installed and initialized. +{{ if empty .Values.superuserPasswordFile }} To get superuser password run +{{ if not (empty .Values.superuserSecret.name) }} + PGPASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ .Values.superuserSecret.name }} -o jsonpath="{.data.{{.Values.superuserSecret.passwordKey}}}" | base64 --decode; echo) +{{ else }} PGPASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "stolon.fullname" . }} -o jsonpath="{.data.pg_su_password}" | base64 --decode; echo) +{{ end }} +{{ end }} \ No newline at end of file diff --git a/stolon/templates/_helpers.tpl b/stolon/templates/_helpers.tpl index 45f95f6..d230346 100644 --- a/stolon/templates/_helpers.tpl +++ b/stolon/templates/_helpers.tpl @@ -9,43 +9,28 @@ Expand the name of the chart. {{/* 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 "stolon.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 -}} - -{{/* -Create a default fully qualified store name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "stolon.store.fullname" -}} -{{- printf "%s-%s" .Release.Name .Values.store.backend | trunc 63 | trimSuffix "-" -}} {{- end -}} - -{{- define "stolon.clusterName" -}} -{{- $genName := printf "%s-%s" .Release.Name .Chart.Name -}} -{{- $name := default $genName .Values.clusterName -}} -{{- printf $name -}} -{{- end -}} - -{{- define "stolon.keeper.fullname" -}} -{{- $serviceName := default "keeper" .Values.keeper.nameOverride -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s-%s" .Release.Name $name $serviceName | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "stolon.sentinel.fullname" -}} -{{- $serviceName := default "sentinel" .Values.sentinel.nameOverride -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s-%s" .Release.Name $name $serviceName | trunc 63 | trimSuffix "-" -}} +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "stolon.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "stolon.proxy.fullname" -}} -{{- $serviceName := default "proxy" .Values.proxy.nameOverride -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s-%s" .Release.Name $name $serviceName | trunc 63 | trimSuffix "-" -}} -{{- end -}} {{/* Create the name of the service account to use */}} {{- define "stolon.serviceAccountName" -}} @@ -55,3 +40,11 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this {{ default "default" .Values.serviceAccount.name }} {{- end -}} {{- end -}} + +{{- define "stolon.clusterName" -}} +{{- if .Values.clusterName -}} + {{- .Values.clusterName | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- template "stolon.fullname" . -}} +{{- end -}} +{{- end -}} diff --git a/stolon/templates/certs.yaml b/stolon/templates/certs.yaml new file mode 100644 index 0000000..bc1ee71 --- /dev/null +++ b/stolon/templates/certs.yaml @@ -0,0 +1,19 @@ +{{ if and (not .Values.tls.existingSecret) ( .Values.tls.enabled) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "stolon.fullname" . }}-certs + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + rootCa.crt: + {{ .Values.tls.rootCa | b64enc | quote }} + serverCrt.crt: + {{ .Values.tls.serverCrt| b64enc | quote }} + serverKey.key: + {{ .Values.tls.serverKey | b64enc | quote }} +{{- end }} diff --git a/stolon/templates/cluster-create-job.yaml b/stolon/templates/cluster-create-job.yaml deleted file mode 100644 index a3cf76c..0000000 --- a/stolon/templates/cluster-create-job.yaml +++ /dev/null @@ -1,51 +0,0 @@ -{{ if .Release.IsInstall }} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "stolon.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ template "stolon.fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -spec: - template: - metadata: - labels: - app: {{ template "stolon.fullname" . }} - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" - annotations: - {{- if eq .Values.store.backend "etcd" }} - pod.beta.kubernetes.io/init-containers: '[ - { - "name": "create-cluster", - "image": "gcr.io/google_containers/etcd-amd64:3.0.14", - "command": ["/bin/sh", "-c", "while ! etcdctl --endpoints {{ .Values.store.endpoints }} cluster-health; do sleep 1 && echo -n .; done"], - "imagePullPolicy": {{ default "Always" .Values.imagePullPolicy | quote }} - } - ]' - {{- end }} - spec: - serviceAccountName: {{ template "stolon.serviceAccountName" . }} - restartPolicy: Never - containers: - - name: {{ template "stolon.fullname" . }} - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }} - command: ["/usr/local/bin/stolonctl"] - args: - - init - - --cluster-name={{ template "stolon.clusterName" . }} - - --store-backend={{ .Values.store.backend }} - {{- if eq .Values.store.backend "kubernetes" }} - - --kube-resource-kind={{ default "configmap" .Values.store.kubeResourceKind }} - {{- else }} - - --store-endpoints={{ .Values.store.endpoints }} - {{- end }} - - --yes - - '{ "initMode": "new"{{- if or .Values.keeper.client_ssl.enabled .Values.slow_queries.enabled }}, "pgParameters": { {{- if .Values.keeper.client_ssl.enabled }} "ssl": "on", "ssl_cert_file": "/etc/secrets/ssl/server.crt", "ssl_key_file": "/etc/secrets/ssl/server.key"{{- end }}{{- if and .Values.keeper.client_ssl.enabled .Values.slow_queries.enabled }},{{- end }}{{ if .Values.slow_queries.enabled }} "log_min_duration_statement" : "{{ .Values.slow_queries.min_duration }}" {{ end }} }{{- end}} }' -{{ end }} - diff --git a/stolon/templates/configmap.yaml b/stolon/templates/configmap.yaml new file mode 100644 index 0000000..3230be2 --- /dev/null +++ b/stolon/templates/configmap.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "stolon.fullname" . }} + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: +{{- if .Values.keeper.hooks.failKeeper.enabled }} + pre-stop-hook.sh: |- + #!/bin/bash + exec &> >(tee -a "/var/log/stolon-hooks.log") + + NODE_NAME=${HOSTNAME} + IFS='-' read -ra ADDR <<< "$(hostname)" + STKEEPER_UID="{{ .Values.keeper.uid_prefix }}${ADDR[-1]}" + + echo "keeper [${STKEEPER_UID}] is failing" + stolonctl \ + --cluster-name={{ template "stolon.clusterName" . }} \ + --store-backend={{ .Values.store.backend }} \ + {{- if eq .Values.store.backend "kubernetes" }} + --kube-resource-kind={{ .Values.store.kubeResourceKind }} \ + {{- else }} + --store-endpoints={{ .Values.store.endpoints }} \ + {{- end }} + failkeeper ${STKEEPER_UID} || true + + echo "Node ${NODE_NAME} is ready to shutdown" +{{- end }} +{{- with .Values.nodePostStartScript }} +{{ toYaml . | indent 2 }} +{{- end }} diff --git a/stolon/templates/hooks/create-cluster-job.yaml b/stolon/templates/hooks/create-cluster-job.yaml new file mode 100644 index 0000000..b0b71dd --- /dev/null +++ b/stolon/templates/hooks/create-cluster-job.yaml @@ -0,0 +1,50 @@ +{{ if and .Release.IsInstall .Values.job.autoCreateCluster }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "stolon.fullname" . }}-create-cluster + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": before-hook-creation +spec: + template: + metadata: + labels: + app: {{ template "stolon.fullname" . }} + release: {{ .Release.Name }} +{{- if .Values.job.annotations }} + annotations: +{{ toYaml .Values.job.annotations | indent 8 }} +{{- end }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ template "stolon.serviceAccountName" . }} + {{- if eq .Values.store.backend "etcdv2" "etcdv3" }} + initContainers: + - name: {{ .Chart.Name }}-etcd-wait + image: "{{ .Values.etcdImage.repository }}:{{ .Values.etcdImage.tag }}" + imagePullPolicy: {{ .Values.etcdImage.pullPolicy }} + command: ["sh", "-c", "while ! etcdctl --endpoints {{ .Values.store.endpoints }} cluster-health; do sleep 1 && echo -n .; done"] + {{- end }} + containers: + - name: {{ template "stolon.fullname" . }}-create-cluster + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["/usr/local/bin/stolonctl"] + args: + - init + - --cluster-name={{ template "stolon.clusterName" . }} + - --store-backend={{ .Values.store.backend }} + {{- if eq .Values.store.backend "kubernetes" }} + - --kube-resource-kind={{ .Values.store.kubeResourceKind }} + {{- else }} + - --store-endpoints={{ .Values.store.endpoints }} + {{- end }} + - --yes + - '{ "initMode": "new", {{- range $key, $value := .Values.clusterSpec }} {{ $key | quote }}: {{ if typeIs "string" $value }} {{ $value | quote }} {{ else }} {{ $value }} {{ end }}, {{- end }} {{ if .Values.tls.enabled }} "pgParameters": {{- $pgParameters := .Values.pgParameters -}}{{ $all_init := set $pgParameters "ssl" "on" }}{{ $all_init := set $all_init "ssl_cert_file" "/certs/serverCrt.crt" }} {{ $all_init := set $all_init "ssl_key_file" "/certs/serverKey.key" }}{{ $all_init := set $all_init "ssl_ca_file" "/certs/rootCa.crt" }}{{ toJson $all_init }}{{ else }}"pgParameters": {{ toJson .Values.pgParameters }} {{ end}} }' +{{ end }} diff --git a/stolon/templates/hooks/init-db-job.yaml b/stolon/templates/hooks/init-db-job.yaml new file mode 100644 index 0000000..d866799 --- /dev/null +++ b/stolon/templates/hooks/init-db-job.yaml @@ -0,0 +1,76 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "stolon.fullname" . }}-init-scripts +data: +{{- with .Values.initdbScripts }} +{{ toYaml . | indent 2 }} +{{- end }} +--- +{{- if .Values.initdbScripts }} +apiVersion: batch/v1 +kind: Job +metadata: + name: '{{template "stolon.clusterName" .}}-createdb' + labels: + heritage: {{.Release.Service | quote }} + release: {{.Release.Name | quote }} + chart: "{{.Chart.Name}}-{{.Chart.Version}}" + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{.Release.Name}}" + labels: + heritage: {{.Release.Service | quote }} + release: {{.Release.Name | quote }} + chart: "{{.Chart.Name}}-{{.Chart.Version}}" +{{- if .Values.job.annotations }} + annotations: +{{ toYaml .Values.job.annotations | indent 8 }} +{{- end }} + spec: + restartPolicy: Never + containers: + - name: create-database-job + image: 'postgres' + env: + - name: USERNAME +{{- if not (empty .Values.superuserSecret.name) }} + valueFrom: + secretKeyRef: + name: {{ .Values.superuserSecret.name }} + key: {{ .Values.superuserSecret.usernameKey }} +{{- else }} + value: {{ .Values.superuserUsername | quote }} +{{- end }} + - name: PGPASSWORD +{{- if not (empty .Values.superuserSecret.name) }} + valueFrom: + secretKeyRef: + name: {{ .Values.superuserSecret.name }} + key: {{ .Values.superuserSecret.passwordKey }} +{{- else }} + value: {{ .Values.superuserPassword | quote }} +{{- end }} + - name: HOST + value: {{ template "stolon.fullname" . }}-proxy + command: ["/bin/bash", "-e", "/tmp/sql-script/create_script.sh"] + volumeMounts: + - mountPath: "/tmp/sql-script" + readOnly: true + name: sql-script + volumes: + - name: sql-script + configMap: + name: {{ template "stolon.fullname" . }}-init-scripts + defaultMode: 420 + initContainers: + - name: wait-for-database + image: jwilder/dockerize + command: ['dockerize', '-timeout', '30s', '-wait', 'tcp://{{ template "stolon.fullname" . }}-proxy:5432'] +{{- end }} \ No newline at end of file diff --git a/stolon/templates/hooks/update-cluster-spec-job.yaml b/stolon/templates/hooks/update-cluster-spec-job.yaml new file mode 100644 index 0000000..f1fdf49 --- /dev/null +++ b/stolon/templates/hooks/update-cluster-spec-job.yaml @@ -0,0 +1,50 @@ +{{ if .Values.job.autoUpdateClusterSpec }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "stolon.fullname" . }}-update-cluster-spec + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +spec: + template: + metadata: + labels: + app: {{ template "stolon.fullname" . }} + release: {{ .Release.Name }} +{{- if .Values.job.annotations }} + annotations: +{{ toYaml .Values.job.annotations | indent 8 }} +{{- end }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ template "stolon.serviceAccountName" . }} + {{- if eq .Values.store.backend "etcdv2" "etcdv3" }} + initContainers: + - name: {{ .Chart.Name }}-etcd-wait + image: "{{ .Values.etcdImage.repository }}:{{ .Values.etcdImage.tag }}" + imagePullPolicy: {{ .Values.etcdImage.pullPolicy }} + command: ["sh", "-c", "while ! etcdctl --endpoints {{ .Values.store.endpoints }} cluster-health; do sleep 1 && echo -n .; done"] + {{- end }} + containers: + - name: {{ template "stolon.fullname" . }}-update-cluster-spec + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["/usr/local/bin/stolonctl"] + args: + - update + - --cluster-name={{ template "stolon.clusterName" . }} + - --store-backend={{ .Values.store.backend }} + {{- if eq .Values.store.backend "kubernetes" }} + - --kube-resource-kind={{ .Values.store.kubeResourceKind }} + {{- else }} + - --store-endpoints={{ .Values.store.endpoints }} + {{- end }} + - -p + - '{ {{- range $key, $value := .Values.clusterSpec }} {{ $key | quote }}: {{ if typeIs "string" $value }} {{ $value | quote }} {{ else }} {{ $value }} {{ end }}, {{- end }} {{ if .Values.tls.enabled }}"pgParameters": {{- $pgParameters := .Values.pgParameters -}}{{ $all := set $pgParameters "ssl" "on" }}{{ $all := set $all "ssl_cert_file" "/certs/serverCrt.crt" }} {{ $all := set $all "ssl_key_file" "/certs/serverKey.key" }}{{ $all := set $all "ssl_ca_file" "/certs/rootCa.crt" }}{{ toJson $all }} {{ else }}"pgParameters": {{- $pgParameters := .Values.pgParameters -}}{{ $all := set $pgParameters "ssl" "off" }}{{ $all := set $all "ssl_cert_file" nil }} {{ $all := set $all "ssl_key_file" nil }}{{ $all := set $all "ssl_ca_file" nil }}{{ toJson $all }}{{ end}}}' +{{ end }} diff --git a/stolon/templates/keeper-headless-service.yaml b/stolon/templates/keeper-headless-service.yaml new file mode 100644 index 0000000..82f427b --- /dev/null +++ b/stolon/templates/keeper-headless-service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "stolon.fullname" . }}-keeper-headless + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: +{{- with .Values.keeper.service.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: + clusterIP: None + ports: + {{- range $key, $value := .Values.keeper.service.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 6 }} +{{- end }} + selector: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-keeper diff --git a/stolon/templates/keeper-pdb.yaml b/stolon/templates/keeper-pdb.yaml new file mode 100644 index 0000000..8521c10 --- /dev/null +++ b/stolon/templates/keeper-pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.keeper.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "stolon.fullname" . }}-keeper + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-keeper +{{ toYaml .Values.keeper.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/stolon/templates/keeper-ro-service.yaml b/stolon/templates/keeper-ro-service.yaml deleted file mode 100644 index bdd5bf4..0000000 --- a/stolon/templates/keeper-ro-service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ template "stolon.keeper.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ template "stolon.keeper.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-keeper" - heritage: "{{ .Release.Service }}" -spec: - {{ if .Values.keeper.serviceType }} - type: {{ .Values.keeper.serviceType }} - {{ end }} - ports: - - port: {{ .Values.ports.externalPort }} - targetPort: {{ .Values.ports.internalPort }} - selector: - app: {{ template "stolon.keeper.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-keeper" - stolon-cluster: {{ template "stolon.clusterName" . }} diff --git a/stolon/templates/keeper-statefulset.yaml b/stolon/templates/keeper-statefulset.yaml index 8a100e9..b64a262 100644 --- a/stolon/templates/keeper-statefulset.yaml +++ b/stolon/templates/keeper-statefulset.yaml @@ -1,120 +1,243 @@ -apiVersion: apps/v1beta1 +apiVersion: apps/v1 kind: StatefulSet metadata: - name: {{ template "stolon.keeper.fullname" . }} - namespace: {{ .Release.Namespace }} + name: {{ template "stolon.fullname" . }}-keeper labels: - app: {{ template "stolon.keeper.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-keeper" - heritage: "{{ .Release.Service }}" + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} spec: - serviceName: {{ template "stolon.keeper.fullname" . }} - replicas: {{ .Values.keeper.replicas }} + serviceName: {{ template "stolon.fullname" . }}-keeper-headless + replicas: {{ .Values.keeper.replicaCount }} + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-keeper template: metadata: labels: - app: {{ template "stolon.keeper.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-keeper" - stolon-cluster: {{ template "stolon.clusterName" . }} + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-keeper + stolon-cluster: {{ template "stolon.fullname" . }} annotations: - pod.alpha.kubernetes.io/initialized: "true" +{{- with .Values.keeper.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} spec: +{{- if .Values.keeper.priorityClassName }} + priorityClassName: "{{ .Values.keeper.priorityClassName }}" +{{- end }} serviceAccountName: {{ template "stolon.serviceAccountName" . }} terminationGracePeriodSeconds: 10 - -{{- if .Values.keeper.affinity }} - affinity: -{{ toYaml .Values.keeper.affinity | indent 8 }} +{{- if .Values.keeper.fsGroup }} + securityContext: + fsGroup: {{ .Values.keeper.fsGroup }} +{{- end }} +{{- if .Values.image.pullSecrets }} + imagePullSecrets: +{{ toYaml .Values.image.pullSecrets | indent 8 }} +{{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - "/bin/bash" + - "-ec" + - | + # Generate our keeper uid using the pod index + IFS='-' read -ra ADDR <<< "$(hostname)" + export STKEEPER_UID="{{ .Values.keeper.uid_prefix }}${ADDR[-1]}" + export POD_IP=$(hostname -i) + export STKEEPER_PG_ADVERTISE_ADDRESS=$POD_IP + export STKEEPER_PG_LISTEN_ADDRESS=${STKEEPER_PG_LISTEN_ADDRESS:-$POD_IP} + export STOLON_DATA=/stolon-data + chown stolon:stolon $STOLON_DATA + {{- if .Values.shmVolume.enabled }} + chmod -R 777 /dev/shm + {{- end }} + exec gosu stolon stolon-keeper --data-dir $STOLON_DATA + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: STKEEPER_CLUSTER_NAME + value: {{ template "stolon.clusterName" . }} + - name: STKEEPER_STORE_BACKEND + value: {{ .Values.store.backend | quote }} + {{- if eq .Values.store.backend "kubernetes" }} + - name: STKEEPER_KUBE_RESOURCE_KIND + value: {{ .Values.store.kubeResourceKind | quote }} + {{- else }} + - name: STKEEPER_STORE_ENDPOINTS + value: {{ .Values.store.endpoints | quote }} + {{- end }} + - name: STKEEPER_PG_REPL_USERNAME +{{ if not (empty .Values.replicationSecret.name) }} + valueFrom: + secretKeyRef: + name: {{ .Values.replicationSecret.name }} + key: {{ .Values.replicationSecret.usernameKey }} +{{ else }} + value: {{ .Values.replicationUsername | quote}} +{{ end }} + - name: STKEEPER_PG_REPL_PASSWORDFILE +{{ if not (empty .Values.replicationSecret.name) }} + value: /etc/secrets/stolon-{{ .Values.replicationSecret.name }}/{{ .Values.replicationSecret.passwordKey }} +{{ else if not (empty .Values.replicationPasswordFile) }} + value: {{ .Values.replicationPasswordFile }} +{{ else }} + value: "/etc/secrets/stolon/pg_repl_password" +{{ end }} + - name: STKEEPER_PG_SU_USERNAME +{{ if not (empty .Values.superuserSecret.name) }} + valueFrom: + secretKeyRef: + name: {{ .Values.superuserSecret.name }} + key: {{ .Values.superuserSecret.usernameKey }} +{{ else }} + value: {{ .Values.superuserUsername | quote }} +{{ end }} + - name: STKEEPER_PG_SU_PASSWORDFILE +{{ if not (empty .Values.superuserSecret.name) }} + value: /etc/secrets/stolon-{{ .Values.superuserSecret.name }}/{{ .Values.superuserSecret.passwordKey }} +{{ else if not (empty .Values.superuserPasswordFile) }} + value: {{ .Values.superuserPasswordFile }} +{{ else }} + value: "/etc/secrets/stolon/pg_su_password" +{{ end }} + - name: STKEEPER_METRICS_LISTEN_ADDRESS + value: "0.0.0.0:{{ .Values.ports.metrics.containerPort }}" + - name: STKEEPER_DEBUG + value: {{ .Values.debug | quote}} +{{- if .Values.keeper.extraEnv }} +{{ toYaml .Values.keeper.extraEnv | indent 12 }} +{{- end }} + ports: +{{- range $key, $value := .Values.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 14 }} +{{- end }} + resources: +{{ toYaml .Values.keeper.resources | indent 12 }} + volumeMounts: +{{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm +{{- end }} + - name: data + mountPath: /stolon-data +{{- if .Values.tls.enabled }} + - name: certs + mountPath: /certs +{{- end }} +{{ if and (or (empty .Values.superuserSecret.name) (empty .Values.replicationSecret.name)) (or (empty .Values.superuserPasswordFile) (empty .Values.replicationPasswordFile)) }} + - name: stolon-secrets + mountPath: /etc/secrets/stolon +{{ end }} +{{ if not (empty .Values.superuserSecret.name) }} + - name: stolon-secret-{{ .Values.superuserSecret.name }} + mountPath: /etc/secrets/stolon-{{ .Values.superuserSecret.name }} +{{ end }} +{{ if and (not (empty .Values.replicationSecret.name)) (not (eq .Values.superuserSecret.name .Values.replicationSecret.name)) }} + - name: stolon-secret-{{ .Values.replicationSecret.name }} + mountPath: /etc/secrets/stolon-{{ .Values.replicationSecret.name }} +{{ end }} +{{- range $key, $value := .Values.keeper.volumeMounts }} + - name: {{ $key }} +{{ toYaml $value | indent 12 }} +{{- end }} +{{- if .Values.keeper.hooks.failKeeper.enabled }} + - name: config + mountPath: /pre-stop-hook.sh + subPath: pre-stop-hook.sh +{{- end }} +{{- if .Values.nodePostStartScript }} + - name: config + mountPath: /postStartScript.sh + subPath: postStartScript.sh +{{- end }} + lifecycle: +{{- if .Values.keeper.hooks.failKeeper.enabled }} + preStop: + exec: + command: ["/bin/bash", "-e", "/pre-stop-hook.sh"] {{- end }} - -{{- if .Values.keeper.nodeSelector }} +{{- if .Values.nodePostStartScript }} + postStart: + exec: + command: ["/bin/bash", "-e", "/postStartScript.sh"] +{{- end }} +{{- with .Values.keeper.nodeSelector }} nodeSelector: -{{ toYaml .Values.keeper.nodeSelector | indent 8 }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.keeper.affinity }} + affinity: +{{ toYaml . | indent 8 }} {{- end }} - -{{- if .Values.keeper.tolerations }} +{{- with .Values.keeper.tolerations }} tolerations: -{{ toYaml .Values.keeper.tolerations | indent 8 }} +{{ toYaml . | indent 8 }} {{- end }} - - containers: - - name: {{ template "stolon.keeper.fullname" . }} - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }} - command: - - "/bin/bash" - - "-ec" - - | - # Generate our keeper uid using the pod index - IFS='-' read -ra ADDR <<< "$(hostname)" - export STKEEPER_UID="{{ .Values.keeper.uid_prefix }}${ADDR[-1]}" - export POD_IP=$(hostname -i) - export STKEEPER_PG_LISTEN_ADDRESS=$POD_IP - export STOLON_DATA=/stolon-data - chown stolon:stolon $STOLON_DATA - exec gosu stolon stolon-keeper --data-dir $STOLON_DATA - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: STKEEPER_CLUSTER_NAME - value: {{ template "stolon.clusterName" . }} - - name: STKEEPER_STORE_BACKEND - value: {{ .Values.store.backend | quote}} - {{- if eq .Values.store.backend "kubernetes" }} - - name: STKEEPER_KUBE_RESOURCE_KIND - value: {{ default "configmap" .Values.store.kubeResourceKind | quote}} - {{- else }} - - name: STKEEPER_STORE_ENDPOINTS - value: {{ .Values.store.endpoints | quote}} - {{- end }} - - name: STKEEPER_PG_REPL_USERNAME - value: {{ .Values.pgReplUsername | quote}} - - name: STKEEPER_PG_REPL_PASSWORDFILE - value: "/etc/secrets/stolon/pg_repl_password" - - name: STKEEPER_PG_SU_USERNAME - value: {{ .Values.pgSuperuserName | quote}} - - name: STKEEPER_PG_SU_PASSWORDFILE - value: "/etc/secrets/stolon/pg_su_password" - - name: STKEEPER_DEBUG - value: {{ .Values.debug | quote}} - ports: - - containerPort: {{ .Values.ports.internalPort }} - volumeMounts: - - name: stolon-data - mountPath: /stolon-data - - name: stolon-secrets - mountPath: /etc/secrets/stolon - resources: -{{ toYaml .Values.keeper.resources | indent 10 }} volumes: +{{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory +{{- end }} +{{- if .Values.tls.enabled }} + - name: certs + secret: + defaultMode: 0600 + secretName: {{ if .Values.tls.existingSecret }}{{ .Values.tls.existingSecret }}{{ else }}{{ template "stolon.fullname" . }}-certs{{end}} +{{ end }} + - name: config + configMap: + name: {{ template "stolon.fullname" . }} +{{ if or (empty .Values.superuserSecret.name) (empty .Values.replicationSecret.name) }} - name: stolon-secrets secret: secretName: {{ template "stolon.fullname" . }} - +{{ end }} +{{ if not (empty .Values.superuserSecret.name) }} + - name: stolon-secret-{{ .Values.superuserSecret.name }} + secret: + secretName: {{ .Values.superuserSecret.name }} +{{ end }} +{{ if and (not (empty .Values.replicationSecret.name)) (not (eq .Values.superuserSecret.name .Values.replicationSecret.name)) }} + - name: stolon-secret-{{ .Values.replicationSecret.name }} + secret: + secretName: {{ .Values.replicationSecret.name }} +{{ end }} +{{- range $key, $value := .Values.keeper.volumes }} + - name: {{ $key }} +{{ toYaml $value | indent 10 }} +{{- end }} {{- if .Values.persistence.enabled }} volumeClaimTemplates: - metadata: - name: stolon-data + name: data spec: accessModes: - - {{ .Values.persistence.accessMode | quote }} + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} resources: requests: - storage: {{ .Values.persistence.size }} - {{- if .Values.persistence.storageClassName }} + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClassName }} {{- if (eq "-" .Values.persistence.storageClassName) }} storageClassName: "" {{- else }} storageClassName: "{{ .Values.persistence.storageClassName }}" {{- end }} - {{- end }} + {{- end }} {{- else }} - - name: stolon-data + - name: data emptyDir: {} {{- end }} diff --git a/stolon/templates/metrics-service.yaml b/stolon/templates/metrics-service.yaml new file mode 100644 index 0000000..e9870e9 --- /dev/null +++ b/stolon/templates/metrics-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "stolon.fullname" . }}-metrics + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: "all" +spec: + ports: + - name: metrics + port: {{ .Values.ports.metrics.containerPort }} + selector: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/stolon/templates/metrics-servicemonitor.yaml b/stolon/templates/metrics-servicemonitor.yaml new file mode 100644 index 0000000..47a0282 --- /dev/null +++ b/stolon/templates/metrics-servicemonitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "stolon.fullname" . }} + labels: + {{- if .Values.serviceMonitor.labels }} + {{ toYaml .Values.serviceMonitor.labels | nindent 4 }} + {{- else }} + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- end }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- end }} +spec: + endpoints: + - targetPort: "metrics" + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: "all" +{{- end }} diff --git a/stolon/templates/proxy-deploy.yaml b/stolon/templates/proxy-deploy.yaml deleted file mode 100644 index bf3c65c..0000000 --- a/stolon/templates/proxy-deploy.yaml +++ /dev/null @@ -1,76 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ template "stolon.proxy.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ template "stolon.proxy.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-proxy" - heritage: "{{ .Release.Service }}" -spec: - replicas: {{ .Values.proxy.replicas }} - template: - metadata: - labels: - app: {{ template "stolon.proxy.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-proxy" - stolon-cluster: {{ template "stolon.clusterName" . }} - spec: - serviceAccountName: {{ template "stolon.serviceAccountName" . }} -{{- if .Values.proxy.affinity }} - affinity: -{{ toYaml .Values.proxy.affinity | indent 8 }} -{{- end }} - -{{- if .Values.proxy.nodeSelector }} - nodeSelector: -{{ toYaml .Values.proxy.nodeSelector | indent 8 }} -{{- end }} - -{{- if .Values.proxy.tolerations }} - tolerations: -{{ toYaml .Values.proxy.tolerations | indent 8 }} -{{- end }} - - containers: - - name: {{ template "stolon.proxy.fullname" . }} - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }} - command: - - "/bin/bash" - - "-ec" - - | - exec gosu stolon stolon-proxy - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: STPROXY_CLUSTER_NAME - value: {{ template "stolon.clusterName" . }} - - name: STPROXY_STORE_BACKEND - value: {{ .Values.store.backend | quote}} - {{- if eq .Values.store.backend "kubernetes" }} - - name: STPROXY_KUBE_RESOURCE_KIND - value: {{ default "configmap" .Values.store.kubeResourceKind | quote}} - {{- else }} - - name: STPROXY_STORE_ENDPOINTS - value: {{ .Values.store.endpoints | quote}} - {{- end }} - - name: STPROXY_LISTEN_ADDRESS - value: {{ default "0.0.0.0" .Values.proxy.listenAddress | quote }} - - name: STPROXY_DEBUG - value: {{ .Values.debug | quote}} - ports: - - containerPort: {{ .Values.ports.internalPort }} - readinessProbe: - tcpSocket: - port: {{ .Values.ports.internalPort }} - initialDelaySeconds: 10 - timeoutSeconds: 5 - resources: -{{ toYaml .Values.proxy.resources | indent 10 }} diff --git a/stolon/templates/proxy-deployment.yaml b/stolon/templates/proxy-deployment.yaml new file mode 100644 index 0000000..b48a60e --- /dev/null +++ b/stolon/templates/proxy-deployment.yaml @@ -0,0 +1,94 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "stolon.fullname" . }}-proxy + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.proxy.replicaCount }} + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-proxy + template: + metadata: + labels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-proxy + stolon-cluster: {{ template "stolon.fullname" . }} + annotations: +{{- with .Values.proxy.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: +{{- if .Values.proxy.priorityClassName }} + priorityClassName: "{{ .Values.proxy.priorityClassName }}" +{{- end }} + serviceAccountName: {{ template "stolon.serviceAccountName" . }} +{{- if .Values.image.pullSecrets }} + imagePullSecrets: +{{ toYaml .Values.image.pullSecrets | indent 8 }} +{{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - "/bin/bash" + - "-ec" + - | + exec gosu stolon stolon-proxy + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: STPROXY_CLUSTER_NAME + value: {{ template "stolon.clusterName" . }} + - name: STPROXY_STORE_BACKEND + value: {{ .Values.store.backend | quote}} + {{- if eq .Values.store.backend "kubernetes" }} + - name: STPROXY_KUBE_RESOURCE_KIND + value: {{ .Values.store.kubeResourceKind | quote}} + {{- else }} + - name: STPROXY_STORE_ENDPOINTS + value: {{ .Values.store.endpoints | quote}} + {{- end }} + - name: STPROXY_LISTEN_ADDRESS + value: {{ default "0.0.0.0" .Values.proxy.listenAddress | quote }} + - name: STPROXY_METRICS_LISTEN_ADDRESS + value: "0.0.0.0:{{ .Values.ports.metrics.containerPort }}" + - name: STPROXY_DEBUG + value: {{ .Values.debug | quote}} +{{- if .Values.proxy.extraEnv }} +{{ toYaml .Values.proxy.extraEnv | indent 12 }} +{{- end }} + ports: +{{- range $key, $value := .Values.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 14 }} +{{- end }} + resources: +{{ toYaml .Values.proxy.resources | indent 12 }} + readinessProbe: + tcpSocket: + port: {{ .Values.ports.stolon.containerPort }} + initialDelaySeconds: 10 + timeoutSeconds: 5 +{{- with .Values.proxy.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.proxy.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.proxy.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} diff --git a/stolon/templates/proxy-pdb.yaml b/stolon/templates/proxy-pdb.yaml new file mode 100644 index 0000000..51cbdb5 --- /dev/null +++ b/stolon/templates/proxy-pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.proxy.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "stolon.fullname" . }}-proxy + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-proxy +{{ toYaml .Values.proxy.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/stolon/templates/proxy-service.yaml b/stolon/templates/proxy-service.yaml index d0b21b6..b81a606 100644 --- a/stolon/templates/proxy-service.yaml +++ b/stolon/templates/proxy-service.yaml @@ -1,24 +1,34 @@ apiVersion: v1 kind: Service metadata: - name: {{ template "stolon.proxy.fullname" . }} - namespace: {{ .Release.Namespace }} + name: {{ template "stolon.fullname" . }}-proxy labels: - app: {{ template "stolon.proxy.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-proxy" - heritage: "{{ .Release.Service }}" + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: +{{- with .Values.proxy.service.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} spec: - {{ if .Values.proxy.serviceType }} - type: {{ .Values.proxy.serviceType }} - {{ end }} +{{- if (or (eq .Values.proxy.service.type "ClusterIP") (empty .Values.proxy.service.type)) }} + type: ClusterIP + {{- if .Values.proxy.service.clusterIP }} + clusterIP: {{ .Values.proxy.service.clusterIP }} + {{end}} +{{- else if eq .Values.proxy.service.type "LoadBalancer" }} + type: {{ .Values.proxy.service.type }} + loadBalancerIP: {{ .Values.proxy.service.loadBalancerIP }} +{{- else }} + type: {{ .Values.proxy.service.type }} +{{- end }} ports: - - port: {{ .Values.ports.externalPort }} - targetPort: {{ .Values.ports.internalPort }} + {{- range $key, $value := .Values.proxy.service.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 6 }} +{{- end }} selector: - app: {{ template "stolon.proxy.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-proxy" - stolon-cluster: {{ template "stolon.clusterName" . }} + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-proxy diff --git a/stolon/templates/psp-role.yaml b/stolon/templates/psp-role.yaml new file mode 100644 index 0000000..a581047 --- /dev/null +++ b/stolon/templates/psp-role.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.podSecurityPolicy.enabled .Values.rbac.create }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-{{ template "stolon.fullname" . }} + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [psp-{{ template "stolon.fullname" . }}] +{{- end }} diff --git a/stolon/templates/psp-rolebinding.yaml b/stolon/templates/psp-rolebinding.yaml new file mode 100644 index 0000000..f09f7f7 --- /dev/null +++ b/stolon/templates/psp-rolebinding.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.podSecurityPolicy.enabled .Values.rbac.create }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: psp-{{ template "stolon.fullname" . }} + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ template "stolon.serviceAccountName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: psp-{{ template "stolon.fullname" . }} +{{- end }} diff --git a/stolon/templates/psp.yaml b/stolon/templates/psp.yaml new file mode 100644 index 0000000..cbb55e8 --- /dev/null +++ b/stolon/templates/psp.yaml @@ -0,0 +1,35 @@ +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: psp-{{ template "stolon.fullname" . }} + annotations: + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + privileged: false + allowPrivilegeEscalation: true + volumes: + - 'configMap' + - 'downwardAPI' + - 'emptyDir' + - 'persistentVolumeClaim' + - 'secret' + - 'projected' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/stolon/templates/stolon-role.yaml b/stolon/templates/role.yaml similarity index 71% rename from stolon/templates/stolon-role.yaml rename to stolon/templates/role.yaml index 3ffa1f6..3b9fe69 100644 --- a/stolon/templates/stolon-role.yaml +++ b/stolon/templates/role.yaml @@ -3,12 +3,11 @@ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: {{ template "stolon.fullname" . }} - namespace: {{ .Release.Namespace }} labels: - app: {{ template "stolon.fullname" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - heritage: {{ .Release.Service }} + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} release: {{ .Release.Name }} + heritage: {{ .Release.Service }} rules: - apiGroups: - "" @@ -16,6 +15,7 @@ rules: - pods - endpoints - configmaps + - events verbs: - "*" {{- end -}} diff --git a/stolon/templates/rolebinding.yaml b/stolon/templates/rolebinding.yaml new file mode 100644 index 0000000..b7febdb --- /dev/null +++ b/stolon/templates/rolebinding.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "stolon.fullname" . }} + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "stolon.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "stolon.serviceAccountName" . }} +{{- end -}} diff --git a/stolon/templates/secret.yaml b/stolon/templates/secret.yaml index c9b2436..99eff2d 100644 --- a/stolon/templates/secret.yaml +++ b/stolon/templates/secret.yaml @@ -1,23 +1,19 @@ +{{ if or (and (empty .Values.superuserSecret.name) (empty .Values.superuserPasswordFile)) (and (empty .Values.replicationSecret.name) (empty .Values.replicationPasswordFile)) }} apiVersion: v1 kind: Secret metadata: name: {{ template "stolon.fullname" . }} - namespace: {{ .Release.Namespace }} labels: - app: {{ template "stolon.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - heritage: "{{ .Release.Service }}" + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} type: Opaque data: -{{ if .Values.pgSuperuserPassword }} - pg_su_password: {{ .Values.pgSuperuserPassword | b64enc | quote }} - {{ else }} - pg_su_password: {{ randAlphaNum 40 | b64enc | quote }} +{{ if and (empty .Values.superuserSecret.name) (empty .Values.superuserPasswordFile) }} + pg_su_password: {{ required "A valid .Values.superuserPassword entry is required!" .Values.superuserPassword | b64enc | quote }} +{{ end }} +{{ if and (empty .Values.replicationSecret.name) (empty .Values.replicationPasswordFile) }} + pg_repl_password: {{ required "A valid .Values.replicationPassword entry is required!" .Values.replicationPassword | b64enc | quote }} {{ end }} - -{{ if .Values.pgReplPassword }} - pg_repl_password: {{ .Values.pgReplPassword | b64enc | quote }} - {{ else }} - pg_repl_password: {{ randAlphaNum 40 | b64enc | quote }} {{ end }} diff --git a/stolon/templates/sentinel-deploy.yaml b/stolon/templates/sentinel-deploy.yaml deleted file mode 100644 index 68db7bc..0000000 --- a/stolon/templates/sentinel-deploy.yaml +++ /dev/null @@ -1,68 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ template "stolon.sentinel.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ template "stolon.sentinel.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-sentinel" - heritage: "{{ .Release.Service }}" -spec: - replicas: {{ .Values.sentinel.replicas }} - template: - metadata: - labels: - app: {{ template "stolon.sentinel.fullname" . }} - release: "{{ .Release.Name }}" - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - component: "stolon-sentinel" - stolon-cluster: {{ template "stolon.clusterName" . }} - stolon-sentinel: "true" - spec: - serviceAccountName: {{ template "stolon.serviceAccountName" . }} -{{- if .Values.sentinel.affinity }} - affinity: -{{ toYaml .Values.sentinel.affinity | indent 8 }} -{{- end }} - -{{- if .Values.sentinel.nodeSelector }} - nodeSelector: -{{ toYaml .Values.sentinel.nodeSelector | indent 8 }} -{{- end }} - -{{- if .Values.sentinel.tolerations }} - tolerations: -{{ toYaml .Values.sentinel.tolerations | indent 8 }} -{{- end }} - - containers: - - name: {{ template "stolon.sentinel.fullname" . }} - image: "{{ .Values.image }}:{{ .Values.imageTag }}" - imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }} - command: - - "/bin/bash" - - "-ec" - - | - exec gosu stolon stolon-sentinel - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: STSENTINEL_CLUSTER_NAME - value: {{ template "stolon.clusterName" .}} - - name: STSENTINEL_STORE_BACKEND - value: {{ .Values.store.backend | quote}} - {{- if eq .Values.store.backend "kubernetes" }} - - name: STSENTINEL_KUBE_RESOURCE_KIND - value: {{ default "configmap" .Values.store.kubeResourceKind | quote}} - {{- else }} - - name: STSENTINEL_STORE_ENDPOINTS - value: {{ .Values.store.endpoints | quote}} - {{- end }} - - name: STSENTINEL_DEBUG - value: {{ .Values.debug | quote}} - resources: -{{ toYaml .Values.sentinel.resources | indent 10 }} diff --git a/stolon/templates/sentinel-deployment.yaml b/stolon/templates/sentinel-deployment.yaml new file mode 100644 index 0000000..ad20f0c --- /dev/null +++ b/stolon/templates/sentinel-deployment.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "stolon.fullname" . }}-sentinel + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.sentinel.replicaCount }} + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-sentinel + template: + metadata: + labels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-sentinel + stolon-cluster: {{ template "stolon.fullname" . }} + annotations: + checksum/config: {{ include (print .Template.BasePath "/hooks/update-cluster-spec-job.yaml") . | sha256sum }} +{{- with .Values.sentinel.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: +{{- if .Values.sentinel.priorityClassName }} + priorityClassName: "{{ .Values.sentinel.priorityClassName }}" +{{- end }} + serviceAccountName: {{ template "stolon.serviceAccountName" . }} +{{- if .Values.image.pullSecrets }} + imagePullSecrets: +{{ toYaml .Values.image.pullSecrets | indent 8 }} +{{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - "/bin/bash" + - "-ec" + - | + exec gosu stolon stolon-sentinel + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: STSENTINEL_CLUSTER_NAME + value: {{ template "stolon.clusterName" . }} + - name: STSENTINEL_STORE_BACKEND + value: {{ .Values.store.backend | quote}} + {{- if eq .Values.store.backend "kubernetes" }} + - name: STSENTINEL_KUBE_RESOURCE_KIND + value: {{ .Values.store.kubeResourceKind | quote}} + {{- else }} + - name: STSENTINEL_STORE_ENDPOINTS + value: {{ .Values.store.endpoints | quote}} + {{- end }} + - name: STSENTINEL_METRICS_LISTEN_ADDRESS + value: "0.0.0.0:{{ .Values.ports.metrics.containerPort }}" + - name: STSENTINEL_DEBUG + value: {{ .Values.debug | quote}} +{{- if .Values.sentinel.extraEnv }} +{{ toYaml .Values.sentinel.extraEnv | indent 12 }} +{{- end }} + ports: +{{- range $key, $value := .Values.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 14 }} +{{- end }} + resources: +{{ toYaml .Values.sentinel.resources | indent 12 }} +{{- with .Values.sentinel.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.sentinel.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.sentinel.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} diff --git a/stolon/templates/sentinel-pdb.yaml b/stolon/templates/sentinel-pdb.yaml new file mode 100644 index 0000000..ba0f116 --- /dev/null +++ b/stolon/templates/sentinel-pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.sentinel.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "stolon.fullname" . }}-sentinel + labels: + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + matchLabels: + app: {{ template "stolon.name" . }} + release: {{ .Release.Name }} + component: stolon-sentinel +{{ toYaml .Values.sentinel.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/stolon/templates/stolon-serviceaccount.yaml b/stolon/templates/serviceaccount.yaml similarity index 63% rename from stolon/templates/stolon-serviceaccount.yaml rename to stolon/templates/serviceaccount.yaml index 5d795ab..1080859 100644 --- a/stolon/templates/stolon-serviceaccount.yaml +++ b/stolon/templates/serviceaccount.yaml @@ -3,10 +3,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: {{ template "stolon.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} labels: - app: {{ template "stolon.fullname" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - heritage: {{ .Release.Service }} + app: {{ template "stolon.name" . }} + chart: {{ template "stolon.chart" . }} release: {{ .Release.Name }} + heritage: {{ .Release.Service }} {{- end -}} diff --git a/stolon/values.yaml b/stolon/values.yaml index 76ae143..af64860 100644 --- a/stolon/values.yaml +++ b/stolon/values.yaml @@ -1,165 +1,203 @@ -# Default values for Stolon Helm Chart. -# This is a YAML-formatted file. -## Declare variables to be passed into your templates. +# clusterName: +image: + repository: sorintlab/stolon + tag: v0.16.0-pg10 + pullPolicy: IfNotPresent + ## Add secrets manually via kubectl on kubernetes cluster and reference here + # pullSecrets: + # - name: "myKubernetesSecret" + +# used by create-cluster-job when store.backend is etcd +etcdImage: + repository: k8s.gcr.io/etcd-amd64 + tag: 2.3.7 + pullPolicy: IfNotPresent -## Override the name of the Chart. -## -# nameOverride: +debug: false -## Stolon image. -## +# Enable the creation of a shm volume +shmVolume: + enabled: false -image: "sorintlab/stolon" +persistence: + enabled: true + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClassName: "" + accessModes: + - ReadWriteOnce + size: 10Gi -## Stolon image version. -## ref: https://hub.docker.com/r/sorintlab/stolon/tags/ -## -imageTag: "v0.13.0-pg11" +rbac: + create: true -## Specify a imagePullPolicy: 'Always' if imageTag is 'latest', else set to 'IfNotPresent'. -## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images -## -# imagePullPolicy: +serviceAccount: + 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: -## Configuration values for Stolon. +superuserSecret: + name: "" + usernameKey: pg_su_username + passwordKey: pg_su_password -# Set custom stolon cluster name -# clusterName: "kube-stolon" -debug: false +replicationSecret: + name: "" + usernameKey: pg_repl_username + passwordKey: pg_repl_password -## log slow queries -# disabled by default -slow_queries: - enabled: false - min_duration: 300 +superuserPasswordFile: -ports: - internalPort: 5432 - externalPort: 5432 +superuserUsername: "stolon" +## password for the superuser (REQUIRED if superuserSecret and superuserPasswordFile are not set) +superuserPassword: +replicationPasswordFile: + +replicationUsername: "repluser" +## password for the replication user (REQUIRED if replicationSecret and replicationPasswordFile are not set) +replicationPassword: + +## backend could be one of the following: consul, etcdv2, etcdv3 or kubernetes store: - ## Backend could be one of the following: - ## - etcdv2 - ## - etcdv3 - ## - consul (should work, but not tested yet) - ## - kubernetes (should work, but not tested yet) - backend: "kubernetes" - ## store endpoints MUST be set for etcd/consul backends - # endpoints: "http://etcd-etcd-0.etcd-etcd:2379,http://etcd-etcd-1.etcd-etcd:2379,http://etcd-etcd-2.etcd-etcd:2379" - -pgReplUsername: "repluser" -## set password for the repluser -## default is 40 random chars -#pgReplPassword: "replPassword" - -pgSuperuserName: "stolon" - -## set password for the superuser -## default is 40 random chars -# pgSuperuserPassword: "" + backend: kubernetes +# endpoints: "http://stolon-consul:8500" + kubeResourceKind: configmap -sentinel: - replicas: 3 +pgParameters: {} + # max_connections: "1000" - ## Configure resource requests and limits. - ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ - ## +ports: + stolon: + containerPort: 5432 + metrics: + containerPort: 8080 - resources: - requests: - cpu: "100m" - memory: "512Mi" +serviceMonitor: + # When set to true then use a ServiceMonitor to collect metrics + enabled: false + # Custom labels to use in the ServiceMonitor to be matched with a specific Prometheus + labels: {} + # Set the namespace the ServiceMonitor should be deployed to + # namespace: default + # Set how frequently Prometheus should scrape + # interval: 30s + # Set timeout for scrape + # scrapeTimeout: 10s + +job: + autoCreateCluster: true + autoUpdateClusterSpec: true + annotations: {} + +clusterSpec: {} + # sleepInterval: 1s + # maxStandbys: 5 + +## Enable support ssl into postgres, you must specify the certs. +## ref: https://www.postgresql.org/docs/10/ssl-tcp.html +## +tls: + enabled: false + rootCa: |- + serverCrt: |- + serverKey: |- - ## Configure nodeSelector, tolerations and affinity. - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node - ## + # existingSecret: name-of-existing-secret-to-postgresql - affinity: {} +keeper: + uid_prefix: "keeper" + replicaCount: 2 + annotations: {} + resources: {} + priorityClassName: "" + fsGroup: "" + service: + type: ClusterIP + annotations: {} + ports: + keeper: + port: 5432 + targetPort: 5432 + protocol: TCP nodeSelector: {} + affinity: {} tolerations: [] + volumes: [] + volumeMounts: [] + hooks: + failKeeper: + enabled: false + podDisruptionBudget: + # minAvailable: 1 + # maxUnavailable: 1 + extraEnv: [] + # - name: STKEEPER_LOG_LEVEL + # value: "info" proxy: - replicas: 3 - ## Set serviceType to nodePort if needed - ## proxy is used to route RW requests to the master - # serviceType: NodePort - - ## Configure resource requests and limits. - ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ - ## - - resources: - requests: - cpu: "100m" - memory: "512Mi" - - ## Configure nodeSelector, tolerations and affinity. - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node - ## - - affinity: {} + replicaCount: 2 + annotations: {} + resources: {} + priorityClassName: "" + service: + type: ClusterIP +# loadBalancerIP: "" + annotations: {} + ports: + proxy: + port: 5432 + targetPort: 5432 + protocol: TCP nodeSelector: {} + affinity: {} tolerations: [] + podDisruptionBudget: + # minAvailable: 1 + # maxUnavailable: 1 + extraEnv: [] + # - name: STPROXY_LOG_LEVEL + # value: "info" + # - name: STPROXY_TCP_KEEPALIVE_COUNT + # value: "0" + # - name: STPROXY_TCP_KEEPALIVE_IDLE + # value: "0" + # - name: STPROXY_TCP_KEEPALIVE_INTERVAL + # value: "0" -keeper: - replicas: 3 - uid_prefix: "stolon" - ## Set serviceType to nodePort if needed - ## keeper service is used to route RO requests to all nodes - # serviceType: NodePort - - ## configure ssl for client access - # create certificates according to these instructions: https://www.postgresql.org/docs/9.6/static/ssl-tcp.html - # to enable encrypted traffic, servert.crt and server.key are required, by that name. - # the use of ** Client Certificates ** is not supported - client_ssl: - enabled: false - certs_secret_name: pg-cert-secret - - ## Configure resource requests and limits. - ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ - ## - - resources: - requests: - cpu: "100m" - memory: "512Mi" - - ## Configure nodeSelector, tolerations and affinity. - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node - ## - - affinity: {} +sentinel: + replicaCount: 2 + annotations: {} + resources: {} + priorityClassName: "" nodeSelector: {} + affinity: {} tolerations: [] - -## Persistent Volume Storage configuration. -## ref: https://kubernetes.io/docs/user-guide/persistent-volumes + podDisruptionBudget: + # minAvailable: 1 + # maxUnavailable: 1 + extraEnv: [] + # - name: STSENTINEL_LOG_LEVEL + # value: "info" + +## initdb scripts +## Specify dictionary of scripts to be run at first boot, the entry point script is create_script.sh +## i.e. you can use pgsql to run sql script on the cluster. ## - -persistence: - ## Enable persistence using Persistent Volume Claims. - ## - enabled: false - - ## Persistent Volume Access Mode. - ## - accessMode: ReadWriteOnce - - ## Persistant Volume Storage Class Name - # storageClassName: "-" - - ## Persistent Volume Storage Size. - ## - size: 10Gi - -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: my-name +# initdbScripts: +# create_script.sh: | +# #!/bin/sh +# echo "Do something." + +## nodePostStart scripts +## Specify dictionary of scripts to be run at first boot, the entry point script is postStartScript.sh +## i.e. you can create tablespace directory here. +## +# nodePostStartScript: +# postStartScript.sh: | +# #!/bin/bash +# echo "Do something." From 1b99ea7ab773ef29975f18f94c97247d06e18b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20R=2E=20de=20Miranda?= Date: Fri, 15 Jan 2021 08:22:29 -0300 Subject: [PATCH 2/3] Change README.md --- stolon/README.md | 168 +++++++++++++++++++++++++---------------------- 1 file changed, 90 insertions(+), 78 deletions(-) diff --git a/stolon/README.md b/stolon/README.md index 362555d..b9a5460 100644 --- a/stolon/README.md +++ b/stolon/README.md @@ -1,102 +1,114 @@ # Stolon Helm Chart -## Prerequisites Details -* Kubernetes 1.5 (for `StatefulSets` support) -* PV support on the underlying infrastructure +* Installs [Stolon](https://github.com/sorintlab/stolon) (HA PostgreSQL cluster) -## StatefulSet Details -* https://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/ +## TL;DR; -## StatefulSet Caveats -* https://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/#limitations - - -## Chart dependencies -* etcd from http://storage.googleapis.com/kubernetes-charts-incubator - - -## Chart Details -This chart will do the following: - -* Implemented a dynamically scalable Stolon-based PostgreSQL cluster using Kubernetes StatefulSetss +```console +$ helm install stable/stolon +``` ## Installing the Chart To install the chart with the release name `my-release`: -```bash -$ git clone https://github.com/lwolf/stolon-chart -$ cd stolon-chart -$ helm dep build -$ helm install --name my-release . +```console +$ helm install --name my-release stable/stolon ``` -### Experimental kubernetes backend: +## Backend -```bash -# You need to set the backend to type kubernetes -$ helm install --name my-release . --set store.backend=kubernetes -``` -Or change them in your values.yml accordingly. +Kubernetes is the default store backend. `consul`, `etcdv2` or `etcdv3` can also be used as the store backend. ## Configuration -The following tables lists the configurable parameters of the helm chart and their default values. - | Parameter | Description | Default | | --------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------ | -| `image` | `stolon` image repository | `sorintlab/stolon` | -| `imageTag` | `stolon` image tag | `v0.7.0-pg9.6` | -| `imagePullPolicy` | Image pull policy | `Always` if `imageTag` is `latest`, else `IfNotPresent` | -| `clusterName` | Name of the cluster | `kube-stolon` | +| `clusterName` | `stolon` cluster name | `nil` | +| `image.repository` | `stolon` image repository | `sorintlab/stolon` | +| `image.tag` | `stolon` image tag | `v0.13.0-pg10` | +| `image.pullPolicy` | `stolon` image pull policy | `IfNotPresent` | +| `image.pullSecrets` | `stolon` image pull secrets as an array | `[]` (does not add image pull secrets to deployed pods) | +| `etcdImage.repository` | `etcd` image repository | `k8s.gcr.io/etcd-amd64` | +| `etcdImage.tag` | `etcd` image tag | `2.3.7` | +| `etcdImage.pullPolicy` | `etcd` image pull policy | `IfNotPresent` | | `debug` | Debug mode | `false` | -| `store.backend` | Store backend to use (etcd/consul/kubernetes) | `etcd` | -| `store.endpoints` | Store backend endpoints | `http://etcd-0:2379,http://etcd-1:2379,http://etcd-2:2379` | +| `shmVolume.enabled` | Enable emptyDir volume for /dev/shm on keepers pods | `false` | +| `persistence.enabled` | Use a PVC to persist data | `true` | +| `persistence.storageClassName` | Storage class name of backing PVC | `""` | +| `persistence.accessModes` | Persistent volumes access modes | `["ReadWriteOnce"]` | +| `persistence.size` | Size of data volume | `10Gi` | +| `rbac.create` | Specifies if RBAC resources should be created | `true` | +| `serviceAccount.create` | Specifies if ServiceAccount should be created | `true` | +| `serviceAccount.name` | Name of the generated ServiceAccount | Defaults to fullname template | +| `superuserSecret.name` | Postgres superuser credential secret name | `""` | +| `superuserSecret.usernameKey` | Username key of Postgres superuser in secret | `pg_su_username` | +| `superuserSecret.passwordKey` | Password key of Postgres superuser in secret | `pg_su_password` | +| `superuserUsername` | Postgres superuser username | `stolon` | +| `superuserPasswordFile` | File where to read the Postgres superuser password | | +| `superuserPassword` | Postgres superuser password | (Required if `superuserSecret.name` and `superuserPasswordFile` are not set) | +| `replicationSecret.name` | Postgres replication credential secret name | `""` | +| `replicationSecret.usernameKey` | Username key of Postgres replication in secret | `pg_repl_username` | +| `replicationSecret.passwordKey` | Password key of Postgres replication in secret | `pg_repl_password` | +| `replicationUsername` | Replication username | `repluser` | +| `replicationPasswordFile` | File where to read the replication password | | +| `replicationPassword` | Replication password | (Required if `replicationSecret.name` and `replicationPasswordFile` are not set) | +| `store.backend` | Store backend (kubernetes/consul/etcd) | `kubernetes` | +| `store.endpoints` | Store backend endpoints | `nil` | | `store.kubeResourceKind` | Kubernetes resource kind (only for kubernetes) | `configmap` | -| `pgReplUsername` | Repl username | `repluser` | -| `pgReplPassword` | Repl password | random 40 characters | -| `pgSuperuserName` | Postgres Superuser name | `stolon` | -| `pgSuperuserPassword` | Postgres Superuser password | random 40 characters | -| `sentinel.replicas` | Number of sentinel nodes | `2` | -| `sentinel.resources` | Sentinel resource requests/limit | Memory: `256Mi`, CPU: `100m` | -| `sentinel.affinity` | Affinity settings for sentinel pod assignment | `{}` | -| `sentinel.nodeSelector` | Node labels for sentinel pod assignment | `{}` | -| `sentinel.tolerations` | Toleration labels for sentinel pod assignment | `[]` | -| `proxy.replicas` | Number of proxy nodes | `2` | -| `proxy.resources` | Proxy resource requests/limit | Memory: `256Mi`, CPU: `100m` | -| `proxy.affinity` | Affinity settings for proxy pod assignment | `{}` | -| `proxy.nodeSelector` | Node labels for proxy pod assignment | `{}` | -| `proxy.tolerations` | Toleration labels for proxy pod assignment | `[]` | +| `pgParameters` | [`postgresql.conf`][pgconf] options used during cluster creation | `{}` | +| `ports` | Ports to expose on pods | `{"stolon":{"containerPort": 5432},"metrics":{"containerPort": 8080}}`| +| `serviceMonitor.enabled` | Creates a Prometheus serviceMonitor and service object | `false` | +| `serviceMonitor.labels` | Overrides the default labels added by chart to the ServiceMonitor with labels specified. | `{}` | +| `serviceMonitor.namespace` | Set to use a different value than the release namespace for deploying the ServiceMonitor object | `nil` | +| `serviceMonitor.interval` | Set to use a different value than the default Prometheus scrape interval | `nil` | +| `serviceMonitor.scrapeTimeout` | Set to use a different value than the default Prometheus scrape timeout | `nil` | +| `job.autoCreateCluster` | Set to `false` to force-disable auto-cluster-creation which may clear pre-existing postgres db data | `true` | +| `job.autoUpdateClusterSpec` | Set to `false` to force-disable auto-cluster-spec-update | `true` | +| `job.annotations` | Annotations for Jobs, the value is evaluated as a template. | `{}` | +| `clusterSpec` | Stolon cluster spec [reference](https://github.com/sorintlab/stolon/blob/master/doc/cluster_spec.md) | `{}` | +| `tls.enabled` | Enable tls support to postgresql | `false` | +| `tls.rootCa` | Ca certificate | `""` | +| `tls.serverCrt` | Server cerfificate | `""` | +| `tls.serverKey` | Server key | `""` | +| `tls.existingSecret` | Existing secret with certificate content to stolon credentials | `""` | | `keeper.uid_prefix` | Keeper prefix name | `keeper` | -| `keeper.replicas` | Number of keeper nodes | `2` | -| `keeper.resources` | Keeper resource requests/limit | Memory: `256Mi`, CPU: `100m` | -| `keeper.affinity` | Affinity settings for keeper pod assignment | `{}` | +| `keeper.replicaCount` | Number of keeper nodes | `2` | +| `keeper.resources` | Keeper resource requests/limit | `{}` | +| `keeper.priorityClassName` | Keeper priorityClassName | `nil` | +| `keeper.fsGroup` | Keeper securityContext fsGroup, do not set if pg9 or 10 | `` | | `keeper.nodeSelector` | Node labels for keeper pod assignment | `{}` | +| `keeper.affinity` | Affinity settings for keeper pod assignment | `{}` | | `keeper.tolerations` | Toleration labels for keeper pod assignment | `[]` | -| `keeper.client_ssl.enabled` | Enable ssl encryption | `false` | -| `keeper.client_ssl.certs_secret_name` | The secret for server.crt and server.key | `pg-cert-secret` | -| `persistence.enabled` | Use a PVC to persist data | `false` | -| `persistence.storageClassName` | Storage class name of backing PVC | `standard` | -| `persistence.accessMode` | Use volume as ReadOnly or ReadWrite | `ReadWriteOnce` | -| `persistence.size` | Size of data volume | `10Gi` | -| `rbac.create` | Specifies if RBAC resources should be created | `true` | -| `serviceAccount.create` | Specifies if ServiceAccount should be created | `true` | -| `serviceAccount.name ` | Name of the generated serviceAccount | Defaults to fullname template | - -Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. - -Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, - -```bash -$ helm install --name my-release -f values.yaml . -``` - -## Persistence - -The chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning. +| `keeper.volumes` | Additional volumes | `[]` | +| `keeper.volumeMounts` | Mount paths for `keeper.volumes` | `[]` | +| `keeper.hooks.failKeeper.enabled` | Enable failkeeper pre-stop hook | `false` | +| `keeper.podDisruptionBudget.enabled` | If true, create a pod disruption budget for keeper pods. | `false` | +| `keeper.podDisruptionBudget.minAvailable` | Minimum number / percentage of pods that should remain scheduled | `""` | +| `keeper.podDisruptionBudget.maxUnavailable` | Maximum number / percentage of pods that may be made unavailable | `""` | +| `keeper.extraEnv` | Extra [environment variables](https://github.com/sorintlab/stolon/blob/master/doc/commands_invocation.md#commands-invocation) for keeper | `[]` | +| `proxy.replicaCount` | Number of proxy nodes | `2` | +| `proxy.resources` | Proxy resource requests/limit | `{}` | +| `proxy.priorityClassName` | Proxy priorityClassName | `nil` | +| `proxy.nodeSelector` | Node labels for proxy pod assignment | `{}` | +| `proxy.affinity` | Affinity settings for proxy pod assignment | `{}` | +| `proxy.tolerations` | Toleration labels for proxy pod assignment | `[]` | +| `proxy.podDisruptionBudget.enabled` | If true, create a pod disruption budget for proxy pods. | `false` | +| `proxy.podDisruptionBudget.minAvailable` | Minimum number / percentage of pods that should remain scheduled | `""` | +| `proxy.podDisruptionBudget.maxUnavailable` | Maximum number / percentage of pods that may be made unavailable | `""` | +| `proxy.extraEnv` | Extra [environment variables](https://github.com/sorintlab/stolon/blob/master/doc/commands_invocation.md#commands-invocation) for proxy | `[]` | +| `sentinel.replicaCount` | Number of sentinel nodes | `2` | +| `sentinel.resources` | Sentinel resource requests/limit | `{}` | +| `sentinel.priorityClassName` | Sentinel priorityClassName | `nil` | +| `sentinel.nodeSelector` | Node labels for sentinel pod assignment | `{}` | +| `sentinel.affinity` | Affinity settings for sentinel pod assignment | `{}` | +| `sentinel.tolerations` | Toleration labels for sentinel pod assignment | `[]` | +| `sentinel.podDisruptionBudget.enabled` | If true, create a pod disruption budget for sentinel pods. | `false` | +| `sentinel.podDisruptionBudget.minAvailable` | Minimum number / percentage of pods that should remain scheduled | `""` | +| `sentinel.podDisruptionBudget.maxUnavailable` | Maximum number / percentage of pods that may be made unavailable | `""` | +| `sentinel.extraEnv` | Extra [environment variables](https://github.com/sorintlab/stolon/blob/master/doc/commands_invocation.md#commands-invocation) for sentinel | `[]` | +| `initdbScripts` | Dictionary of scripts. Executed after cluster startup | `nil` | +| `nodePostStartScript` | Dictionary of scripts. Executed after the node startup | `nil` | -## SSL -To enable encrypted traffic, create certificates according to these instructions: https://www.postgresql.org/docs/9.6/static/ssl-tcp.html -The secret should hold servert.crt and server.key are required, by that name. For your convenience a [script](/scripts/create_pg_secret.sh) is included to create the secret in the cluster. -The use of **Client Certificates** is not supported +[pgconf]: https://github.com/postgres/postgres/blob/master/src/backend/utils/misc/postgresql.conf.sample From 0f62b14e6a685273090d412806286e19976865c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20R=2E=20de=20Miranda?= Date: Fri, 15 Jan 2021 08:30:16 -0300 Subject: [PATCH 3/3] Removed rolebinding repeated --- stolon/templates/stolon-rolebinding.yaml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 stolon/templates/stolon-rolebinding.yaml diff --git a/stolon/templates/stolon-rolebinding.yaml b/stolon/templates/stolon-rolebinding.yaml deleted file mode 100644 index 5b31ecb..0000000 --- a/stolon/templates/stolon-rolebinding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: {{ template "stolon.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ template "stolon.fullname" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "stolon.fullname" . }} -subjects: -- kind: ServiceAccount - name: {{ template "stolon.serviceAccountName" . }} -{{- end -}}