Patroni exclusion for Postgres
This PS removes the previously put in place HA clustering support Patroni provided. Change-Id: I03ed11282413a454062ab34b8594ba60ac2175aa
This commit is contained in:
parent
303d5e3108
commit
96369491cb
@ -1,121 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
{{/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
# This script creates the patroni replication user if it doesn't exist.
|
||||
# This is only needed for brownfield upgrade scenarios, on top of sites that
|
||||
# were greenfield-deployed with a pre-patroni version of postgres.
|
||||
#
|
||||
# For greenfield deployments, the patroni-enabled postgresql chart will
|
||||
# create this user automatically.
|
||||
#
|
||||
# If any additional conversion steps are found to be needed, they can go here.
|
||||
|
||||
set -ex
|
||||
|
||||
function patroni_started() {
|
||||
HOST=$1
|
||||
PORT=$2
|
||||
STATUS=$(timeout 10 bash -c "exec 3<>/dev/tcp/${HOST}/${PORT};
|
||||
echo -e \"GET / HTTP/1.1\r\nConnection: close\r\n\" >&3;
|
||||
cat <&3 | tail -n1 | grep -o \"running\"")
|
||||
|
||||
[[ x${STATUS} == "xrunning" ]]
|
||||
}
|
||||
|
||||
PGDATABASE=${PGDATABASE:-'postgres'}
|
||||
PGHOST=${PGHOST:-'127.0.0.1'}
|
||||
PGPORT={{- tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
PSQL="psql -h ${PGHOST} -p ${PGPORT} -d ${PGDATABASE}"
|
||||
|
||||
PVC_MNT={{- .Values.storage.mount.path }}
|
||||
FILE_MADE_BY_POSTGRES=${PVC_MNT}/pgdata/pg_xlog
|
||||
FILE_MADE_BY_PATRONI=${PVC_MNT}/pgdata/patroni.dynamic.json
|
||||
|
||||
TIMEOUT=0
|
||||
|
||||
# Only need to add the user once, on the first replica
|
||||
if [ "x${POD_NAME}" != "xpostgresql-0" ]; then
|
||||
echo "Nothing to do on ${POD_NAME}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Look for a file-based clue that we're migrating from vanilla pg to patroni.
|
||||
# This is lighter-weight than checking in the database for the user, since
|
||||
# we have to fire up the database at this point to do the check.
|
||||
if [[ -e "${FILE_MADE_BY_POSTGRES}" && ! -e "${FILE_MADE_BY_PATRONI}" ]]
|
||||
then
|
||||
echo "We are upgrading to Patroni -- checking for replication user"
|
||||
|
||||
# Fire up a temporary postgres
|
||||
/docker-entrypoint.sh postgres &
|
||||
while ! $PSQL -c "select 1;"; do
|
||||
sleep 1
|
||||
if [[ $TIMEOUT -gt 120 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
TIMEOUT=$((TIMEOUT+1))
|
||||
done
|
||||
TIMEOUT=0
|
||||
|
||||
# Add the replication user if it doesn't exist
|
||||
USER_COUNT=$(${PSQL} -qt -c \
|
||||
"SELECT COUNT(*) FROM pg_roles \
|
||||
WHERE rolname='${PATRONI_REPLICATION_USERNAME}'")
|
||||
|
||||
if [ ${USER_COUNT} -eq 0 ]; then
|
||||
echo "The patroni replication user ${PATRONI_REPLICATION_USERNAME} doesn't exist yet; creating:"
|
||||
# CREATE ROLE defaults to NOLOGIN not to allow password based login.
|
||||
# Replication user uses SSL Cert to connect.
|
||||
${PSQL} -c "CREATE ROLE ${PATRONI_REPLICATION_USERNAME} \
|
||||
WITH REPLICATION;"
|
||||
echo "done."
|
||||
else
|
||||
echo "The patroni replication user ${PATRONI_REPLICATION_USERNAME} already exists: nothing to do."
|
||||
fi
|
||||
|
||||
# Start Patroni to assimilate the postgres
|
||||
sed "s/POD_IP_PATTERN/${PATRONI_KUBERNETES_POD_IP}/g" \
|
||||
/tmp/patroni-templated.yaml > /tmp/patroni.yaml
|
||||
|
||||
READY_FLAG="i am the leader with the lock"
|
||||
PATRONI_LOG=/tmp/patroni_conversion.log
|
||||
/usr/bin/python3 /usr/local/bin/patroni /tmp/patroni-templated.yaml &> ${PATRONI_LOG} &
|
||||
|
||||
# Sleep until patroni is running
|
||||
while ! grep -q "${READY_FLAG}" ${PATRONI_LOG}; do
|
||||
sleep 5
|
||||
if [[ $TIMEOUT -gt 24 ]]; then
|
||||
echo "A timeout occurred. Patroni logs:"
|
||||
cat ${PATRONI_LOG}
|
||||
exit 1
|
||||
fi
|
||||
TIMEOUT=$((TIMEOUT+1))
|
||||
done
|
||||
TIMEOUT=0
|
||||
|
||||
# Gracefully stop postgres and patroni
|
||||
while pkill INT --uid postgres; do
|
||||
sleep 5
|
||||
if [[ $TIMEOUT -gt 24 ]]; then
|
||||
echo "A timeout occurred. Patroni logs:"
|
||||
cat ${PATRONI_LOG}
|
||||
exit 1
|
||||
fi
|
||||
TIMEOUT=$((TIMEOUT+1))
|
||||
done
|
||||
else
|
||||
echo "Patroni is already in place: nothing to do."
|
||||
fi
|
@ -16,8 +16,4 @@ limitations under the License.
|
||||
|
||||
set -ex
|
||||
|
||||
if [ -f /tmp/postgres-disable-liveness-probe ]; then
|
||||
exit 0
|
||||
else
|
||||
pg_isready -U ${PATRONI_SUPERUSER_USERNAME}
|
||||
fi
|
||||
pg_isready -U ${POSTGRES_USER}
|
||||
|
@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
{{/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
PGDATABASE=${PGDATABASE:-'postgres'}
|
||||
PGHOST=${PGHOST:-'127.0.0.1'}
|
||||
PGPORT={{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
|
||||
# These are passed in via the Patroni callback interface
|
||||
action="$1"
|
||||
role="$2"
|
||||
cluster="$3"
|
||||
|
||||
# Note: this script when rendered is stored in a secret and encrypted to disk.
|
||||
PATRONI_SUPERUSER_USERNAME={{ .Values.endpoints.postgresql.auth.admin.username }}
|
||||
PATRONI_SUPERUSER_PASSWORD={{ .Values.endpoints.postgresql.auth.admin.password }}
|
||||
PATRONI_REPLICATION_USERNAME={{ .Values.endpoints.postgresql.auth.replica.username }}
|
||||
|
||||
if [[ x${role} == "xmaster" ]]; then
|
||||
echo "I have become the patroni master: updating superuser and replication passwords"
|
||||
|
||||
# It can take a few seconds for a freshly promoted leader to become read/write.
|
||||
sleep 10
|
||||
if [[ ! -z "$PATRONI_SUPERUSER_PASSWORD" && ! -z "$PATRONI_SUPERUSER_USERNAME" ]]; then
|
||||
psql -U $PATRONI_SUPERUSER_USERNAME -p "$PGPORT" -d "$PGDATABASE" -c "ALTER ROLE $PATRONI_SUPERUSER_USERNAME WITH PASSWORD '$PATRONI_SUPERUSER_PASSWORD';"
|
||||
else
|
||||
echo "WARNING: Did not set superuser password!!!"
|
||||
fi
|
||||
|
||||
echo "password update complete"
|
||||
fi
|
@ -14,62 +14,25 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
set -ex
|
||||
# Disable echo mode while setting the password
|
||||
# unless we are in debug mode
|
||||
{{- if .Values.conf.debug }}
|
||||
set -x
|
||||
{{- end }}
|
||||
set -e
|
||||
|
||||
function patroni_started() {
|
||||
HOST=$1
|
||||
PORT=$2
|
||||
STATUS=$(timeout 10 bash -c "exec 3<>/dev/tcp/${HOST}/${PORT};
|
||||
echo -e \"GET / HTTP/1.1\r\nConnection: close\r\n\" >&3;
|
||||
cat <&3 | tail -n1 | grep -o \"running\"")
|
||||
POSTGRES_DB=${POSTGRES_DB:-"postgres"}
|
||||
|
||||
[[ x${STATUS} == "xrunning" ]]
|
||||
}
|
||||
SVC_FQDN='{{ tuple "postgresql-restapi" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}'
|
||||
SVC_PORT='{{ tuple "postgresql-restapi" "internal" "restapi" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}'
|
||||
# Check if the Postgres data directory exists before attempting to
|
||||
# set the password
|
||||
if [[ -d "$PGDATA" && -s "$PGDATA/PG_VERSION" ]]
|
||||
then
|
||||
postgres --single -D "$PGDATA" "$POSTGRES_DB" <<EOF
|
||||
ALTER ROLE $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD'
|
||||
EOF
|
||||
|
||||
# This is required because the declarative values.yaml config doesn't
|
||||
# know the dynamic podIP. TODO: something more elegant.
|
||||
sed "s/POD_IP_PATTERN/${PATRONI_KUBERNETES_POD_IP}/g" \
|
||||
/tmp/patroni-templated.yaml > \
|
||||
/tmp/patroni.yaml
|
||||
|
||||
FILE_MADE_BY_PATRONI=${PGDATA}/patroni.dynamic.json
|
||||
if [[ ! $POD_NAME -eq "postgresql-0" ]]; then
|
||||
|
||||
echo "I am not postgresql pod zero: disabling liveness probe temporarily"
|
||||
# disable liveness probe as it may take some time for the pod to come online
|
||||
touch /tmp/postgres-disable-liveness-probe
|
||||
|
||||
# During normal upgrades, we just need to turn liveness probes off temporarily
|
||||
# for the sake of password rotation - need to bounce all pods at once
|
||||
# (overriding RollingUpdate) to avoid deadlock. This accounts for that.
|
||||
sleep 60
|
||||
|
||||
# During initial bootstrapping, we need to sequence 0,1,2
|
||||
if [[ ! -e "${FILE_MADE_BY_PATRONI}" ]]; then
|
||||
echo "patroni has not been initialized on this node"
|
||||
# NOTE: this boolean forces a second check after a delay. This accounts for a
|
||||
# scenario during initial vanilla postgres -> patroni conversion, where
|
||||
# a temporary master is brought up, killed off, and then restarted.
|
||||
# This can be safely removed in the future, once all clusters are converted.
|
||||
WAITED_EXTRA="false"
|
||||
|
||||
while [ ${WAITED_EXTRA} = "false" ]; do
|
||||
while ! patroni_started "${SVC_FQDN}" "${SVC_PORT}"; do
|
||||
echo "Waiting until a Leader is elected..."
|
||||
sleep 5
|
||||
done
|
||||
# See note above: this code can be removed once all clusters are Patroni.
|
||||
if [ ${WAITED_EXTRA} = "false" ]; then
|
||||
echo "Leader is up; sleeping to ensure it gets through restarts..."
|
||||
sleep 10
|
||||
WAITED_EXTRA="true"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -fv /tmp/postgres-disable-liveness-probe
|
||||
fi
|
||||
|
||||
exec /usr/bin/python3 /usr/local/bin/patroni /tmp/patroni.yaml
|
||||
set -x
|
||||
|
||||
exec /docker-entrypoint.sh postgres -c config_file=/tmp/postgresql.conf
|
||||
|
@ -38,6 +38,4 @@ data:
|
||||
{{- if .Values.manifests.job_ks_user }}
|
||||
ks-user.sh: {{ include "helm-toolkit.scripts.keystone_user" . | b64enc }}
|
||||
{{- end }}
|
||||
set_password.sh: {{ tuple "bin/_set_password.sh.tpl" . | include "helm-toolkit.utils.template" | b64enc }}
|
||||
patroni_conversion.sh: {{ tuple "bin/_patroni_conversion.sh.tpl" . | include "helm-toolkit.utils.template" | b64enc }}
|
||||
{{- end }}
|
||||
|
@ -17,10 +17,14 @@ limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: postgresql-etc
|
||||
type: Opaque
|
||||
data:
|
||||
{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.patroni "key" "patroni.yaml" "format" "Secret") | indent 2 }}
|
||||
postgresql.conf: |
|
||||
{{- range $key, $value := default dict .Values.conf.postgresql }}
|
||||
{{ $key | snakecase }} = '{{ $value }}'
|
||||
{{- end }}
|
||||
pg_hba.conf: |
|
||||
{{ .Values.conf.pg_hba | indent 4 }}
|
||||
{{- end }}
|
||||
|
@ -1,25 +0,0 @@
|
||||
{{/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.manifests.secret_replica }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Values.secrets.postgresql.replica }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{ include "helm-toolkit.utils.tls_generate_certs" (dict "params" .Values.secrets.pki.replication "encode" true) | indent 2 }}
|
||||
...
|
||||
{{- end }}
|
@ -1,25 +0,0 @@
|
||||
{{/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.manifests.secret_server }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Values.secrets.postgresql.server }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{ include "helm-toolkit.utils.tls_generate_certs" (dict "params" .Values.secrets.pki.server "encode" true) | indent 2 }}
|
||||
...
|
||||
{{- end }}
|
@ -21,6 +21,8 @@ metadata:
|
||||
name: {{ tuple "postgresql" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
|
||||
spec:
|
||||
ports:
|
||||
- name: postgresql
|
||||
- name: db
|
||||
port: {{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
selector:
|
||||
{{ tuple $envAll "postgresql" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
|
||||
{{- end }}
|
||||
|
@ -35,9 +35,6 @@ rules:
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
# delete and deletecollection are required only for 'patronictl remove'
|
||||
- delete
|
||||
- deletecollection
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@ -50,9 +47,6 @@ rules:
|
||||
- create
|
||||
- list
|
||||
- watch
|
||||
# delete and deletecollection are required only for 'patronictl remove'
|
||||
- delete
|
||||
- deletecollection
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@ -122,7 +116,6 @@ spec:
|
||||
configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||
{{ dict "envAll" $envAll "podName" "postgresql" "containerNames" (list "postgresql" "set-volume-perms" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }}
|
||||
configmap-admin-hash: {{ tuple "secret-admin.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||
configmap-replica-hash: {{ tuple "secret-replica.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||
configmap-secrets-etc-hash: {{ tuple "secrets-etc.yaml" . | include "helm-toolkit.utils.hash" }}
|
||||
spec:
|
||||
serviceAccountName: {{ $serviceAccountName }}
|
||||
@ -144,132 +137,13 @@ spec:
|
||||
/bin/chown {{ .Values.pod.security_context.server.pod.runAsUser }} {{ .Values.storage.mount.path }};
|
||||
/bin/chmod 700 {{ .Values.storage.mount.path }};
|
||||
/bin/chmod 700 {{ .Values.storage.mount.path }}/*;
|
||||
/bin/cp {{ .Values.secrets.pki.client_cert_path }}_temp/* {{ .Values.secrets.pki.client_cert_path }}/.;
|
||||
/bin/cp {{ .Values.secrets.pki.server_cert_path }}_temp/* {{ .Values.secrets.pki.server_cert_path }}/.;
|
||||
/bin/chown {{ .Values.pod.security_context.server.pod.runAsUser }} {{ .Values.secrets.pki.client_cert_path }};
|
||||
/bin/chown {{ .Values.pod.security_context.server.pod.runAsUser }} {{ .Values.secrets.pki.client_cert_path }}/*;
|
||||
/bin/chown {{ .Values.pod.security_context.server.pod.runAsUser }} {{ .Values.secrets.pki.server_cert_path }};
|
||||
/bin/chown {{ .Values.pod.security_context.server.pod.runAsUser }} {{ .Values.secrets.pki.server_cert_path }}/*;
|
||||
/bin/chmod 700 {{ .Values.secrets.pki.client_cert_path }};
|
||||
/bin/chmod 600 {{ .Values.secrets.pki.client_cert_path }}/*;
|
||||
/bin/chmod 700 {{ .Values.secrets.pki.server_cert_path }};
|
||||
/bin/chmod 600 {{ .Values.secrets.pki.server_cert_path }}/*;
|
||||
{{ dict "envAll" $envAll "application" "server" "container" "set_volume_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
|
||||
volumeMounts:
|
||||
- name: pod-tmp
|
||||
mountPath: /tmp
|
||||
- name: postgresql-data
|
||||
mountPath: {{ .Values.storage.mount.path }}
|
||||
- name: server-certs
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}
|
||||
# server-cert-temp mountpoint is temp storage for secrets. We copy the
|
||||
# secrets to server-certs folder and set owner and permissions.
|
||||
# This is needed because the secrets are always created readonly.
|
||||
- name: server-certs-temp
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}_temp
|
||||
- name: postgresql-pki
|
||||
subPath: crt
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}_temp/server.crt
|
||||
- name: postgresql-pki
|
||||
subPath: key
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}_temp/server.key
|
||||
- name: replication-pki
|
||||
subPath: ca
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}_temp/ca.crt
|
||||
- name: replication-pki
|
||||
subPath: caKey
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}_temp/ca.key
|
||||
# client-certs is the permanent folder for the client secrets
|
||||
- name: client-certs
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}
|
||||
# client-certs-temp is temporary folder for the client secrets, before they a copied to their permanent folder
|
||||
- name: client-certs-temp
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}_temp
|
||||
- name: replication-pki
|
||||
subPath: crt
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}_temp/client.crt
|
||||
- name: replication-pki
|
||||
subPath: key
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}_temp/client.key
|
||||
- name: postgresql-pki
|
||||
subPath: ca
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}_temp/ca.crt
|
||||
- name: postgresql-pki
|
||||
subPath: caKey
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}_temp/ca.key
|
||||
# This is for non-HA -> Patroni conversion and can be removed in the future
|
||||
- name: patroni-conversion
|
||||
{{ tuple $envAll "postgresql" | include "helm-toolkit.snippets.image" | indent 10 }}
|
||||
{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: "{{ .Values.storage.mount.path }}/pgdata"
|
||||
- name: PATRONI_KUBERNETES_POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: PATRONI_KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: PATRONI_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: PATRONI_KUBERNETES_POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: PATRONI_SUPERUSER_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secrets.postgresql.admin }}
|
||||
key: 'POSTGRES_USER'
|
||||
- name: PATRONI_SUPERUSER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secrets.postgresql.admin }}
|
||||
key: 'POSTGRES_PASSWORD'
|
||||
- name: PATRONI_REPLICATION_USERNAME
|
||||
value: {{ index .Values.secrets.pki.replication.hosts.names 0 | quote }}
|
||||
- name: PATRONI_RESTAPI_CONNECT_ADDRESS
|
||||
value: $(PATRONI_KUBERNETES_POD_IP):{{ tuple "postgresql-restapi" "internal" "restapi" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_RESTAPI_LISTEN
|
||||
value: 0.0.0.0:{{ tuple "postgresql-restapi" "internal" "restapi" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_POSTGRESQL_CONNECT_ADDRESS
|
||||
value: $(PATRONI_KUBERNETES_POD_IP):{{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_POSTGRESQL_LISTEN
|
||||
value: 0.0.0.0:{{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_admin_PASSWORD
|
||||
value: $(PATRONI_SUPERUSER_PASSWORD)
|
||||
- name: PATRONI_admin_OPTIONS
|
||||
value: 'createrole,createdb'
|
||||
command:
|
||||
- /tmp/patroni_conversion.sh
|
||||
{{ dict "envAll" $envAll "application" "server" "container" "patroni_conversion" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
|
||||
volumeMounts:
|
||||
- name: pod-tmp
|
||||
mountPath: /tmp
|
||||
- name: patroni-conversion-tmp
|
||||
mountPath: /var/run/postgresql
|
||||
- name: postgresql-bin
|
||||
mountPath: /tmp/patroni_conversion.sh
|
||||
subPath: patroni_conversion.sh
|
||||
readOnly: true
|
||||
- name: postgresql-data
|
||||
mountPath: {{ .Values.storage.mount.path }}
|
||||
- name: postgresql-etc
|
||||
mountPath: /tmp/patroni-templated.yaml
|
||||
subPath: patroni.yaml
|
||||
readOnly: true
|
||||
subPath: {{ .Values.storage.mount.subpath }}
|
||||
containers:
|
||||
- name: postgresql
|
||||
{{ tuple $envAll "postgresql" | include "helm-toolkit.snippets.image" | indent 10 }}
|
||||
@ -283,72 +157,24 @@ spec:
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: "{{ .Values.storage.mount.path }}/pgdata"
|
||||
- name: PATRONI_KUBERNETES_POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: PATRONI_KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: PATRONI_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: PATRONI_KUBERNETES_POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: PATRONI_SUPERUSER_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secrets.postgresql.admin }}
|
||||
key: 'POSTGRES_USER'
|
||||
- name: PATRONI_SUPERUSER_PASSWORD
|
||||
- name: 'POSTGRES_PASSWORD'
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secrets.postgresql.admin }}
|
||||
key: 'POSTGRES_PASSWORD'
|
||||
- name: PATRONI_REPLICATION_USERNAME
|
||||
value: {{ index .Values.secrets.pki.replication.hosts.names 0 | quote }}
|
||||
- name: PATRONI_RESTAPI_CONNECT_ADDRESS
|
||||
value: $(PATRONI_KUBERNETES_POD_IP):{{ tuple "postgresql-restapi" "internal" "restapi" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_RESTAPI_LISTEN
|
||||
value: 0.0.0.0:{{ tuple "postgresql-restapi" "internal" "restapi" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_POSTGRESQL_CONNECT_ADDRESS
|
||||
value: $(PATRONI_KUBERNETES_POD_IP):{{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_POSTGRESQL_LISTEN
|
||||
value: 0.0.0.0:{{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
- name: PATRONI_{{ .Values.endpoints.postgresql.auth.admin.username }}_PASSWORD
|
||||
value: $(PATRONI_SUPERUSER_PASSWORD)
|
||||
- name: PATRONI_{{ .Values.endpoints.postgresql.auth.admin.username }}_OPTIONS
|
||||
value: 'createrole,createdb'
|
||||
{{- if .Values.manifests.secret_audit }}
|
||||
- name: AUDIT_PASSWORD
|
||||
- name: 'POSTGRES_USER'
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secrets.postgresql.audit }}
|
||||
key: AUDIT_PASSWORD
|
||||
# Adding the audit user with no options just adds the user without
|
||||
# any GRANTs. This means the user gets to do only what default
|
||||
# PUBLIC permissions allow, which is only to SELECT from tables.
|
||||
- name: PATRONI_{{ .Values.endpoints.postgresql.auth.audit.username }}_PASSWORD
|
||||
value: $(AUDIT_PASSWORD)
|
||||
{{- end }}
|
||||
- name: PGSSLROOTCERT
|
||||
value: {{ .Values.secrets.pki.client_cert_path }}/ca.crt
|
||||
- name: PGSSLCERT
|
||||
value: "/home/postgres/.postgresql/postgresql.crt"
|
||||
- name: PGSSLKEY
|
||||
value: "/home/postgres/.postgresql/postgresql.key"
|
||||
name: {{ .Values.secrets.postgresql.admin }}
|
||||
key: 'POSTGRES_USER'
|
||||
command:
|
||||
- /tmp/start.sh
|
||||
livenessProbe:
|
||||
@ -370,10 +196,6 @@ spec:
|
||||
mountPath: /tmp
|
||||
- name: pg-run
|
||||
mountPath: /var/run/postgresql
|
||||
- name: postgresql-bin
|
||||
mountPath: /tmp/set_password.sh
|
||||
subPath: set_password.sh
|
||||
readOnly: true
|
||||
- name: postgresql-bin
|
||||
mountPath: /tmp/start.sh
|
||||
subPath: start.sh
|
||||
@ -383,25 +205,16 @@ spec:
|
||||
subPath: readiness.sh
|
||||
readOnly: true
|
||||
- name: postgresql-etc
|
||||
mountPath: /tmp/patroni-templated.yaml
|
||||
subPath: patroni.yaml
|
||||
mountPath: /tmp/postgresql.conf
|
||||
subPath: postgresql.conf
|
||||
readOnly: true
|
||||
- name: postgresql-etc
|
||||
mountPath: /tmp/pg_hba.conf
|
||||
subPath: pg_hba.conf
|
||||
readOnly: true
|
||||
- name: postgresql-data
|
||||
mountPath: {{ .Values.storage.mount.path }}
|
||||
- name: server-certs
|
||||
mountPath: {{ .Values.secrets.pki.server_cert_path }}
|
||||
- name: client-certs
|
||||
mountPath: {{ .Values.secrets.pki.client_cert_path }}
|
||||
- name: postgres-home-config
|
||||
mountPath: "/home/postgres/.postgresql"
|
||||
- name: client-certs
|
||||
subPath: "client.crt"
|
||||
mountPath: "/home/postgres/.postgresql/postgresql.crt"
|
||||
readOnly: true
|
||||
- name: client-certs
|
||||
subPath: "client.key"
|
||||
mountPath: "/home/postgres/.postgresql/postgresql.key"
|
||||
readOnly: true
|
||||
subPath: {{ .Values.storage.mount.subpath }}
|
||||
volumes:
|
||||
- name: pod-tmp
|
||||
emptyDir: {}
|
||||
@ -410,32 +223,13 @@ spec:
|
||||
- name: pg-run
|
||||
emptyDir:
|
||||
medium: "Memory"
|
||||
# This is for non-HA -> Patroni conversion and can be removed in the future
|
||||
- name: patroni-conversion-tmp
|
||||
emptyDir: {}
|
||||
- name: postgresql-bin
|
||||
secret:
|
||||
secretName: postgresql-bin
|
||||
defaultMode: 0555
|
||||
- name: client-certs-temp
|
||||
emptyDir: {}
|
||||
- name: server-certs-temp
|
||||
emptyDir: {}
|
||||
- name: client-certs
|
||||
emptyDir: {}
|
||||
- name: server-certs
|
||||
emptyDir: {}
|
||||
- name: replication-pki
|
||||
secret:
|
||||
secretName: {{ .Values.secrets.postgresql.replica }}
|
||||
defaultMode: 0640
|
||||
- name: postgresql-pki
|
||||
secret:
|
||||
secretName: {{ .Values.secrets.postgresql.server }}
|
||||
defaultMode: 0640
|
||||
- name: postgresql-etc
|
||||
secret:
|
||||
secretName: postgresql-etc
|
||||
configMap:
|
||||
name: postgresql-etc
|
||||
defaultMode: 0444
|
||||
{{- if not .Values.storage.pvc.enabled }}
|
||||
- name: postgresql-data
|
||||
|
@ -40,10 +40,6 @@ pod:
|
||||
postgresql:
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
patroni_conversion:
|
||||
runAsUser: 999
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
postgresql_backup:
|
||||
pod:
|
||||
runAsUser: 65534
|
||||
@ -73,7 +69,8 @@ pod:
|
||||
weight:
|
||||
default: 10
|
||||
replicas:
|
||||
server: 3
|
||||
# only 1 replica currently supported
|
||||
server: 1
|
||||
prometheus_postgresql_exporter: 1
|
||||
lifecycle:
|
||||
upgrades:
|
||||
@ -144,10 +141,10 @@ pod:
|
||||
memory: "1024Mi"
|
||||
cpu: "2000m"
|
||||
|
||||
# using dockerhub patroni: https://hub.docker.com/r/openstackhelm/patroni/tags/
|
||||
# using dockerhub postgresql: https://hub.docker.com/r/library/postgres/tags/
|
||||
images:
|
||||
tags:
|
||||
postgresql: "docker.io/openstackhelm/patroni:latest-ubuntu_xenial"
|
||||
postgresql: "docker.io/postgres:9.6"
|
||||
dep_check: quay.io/airshipit/kubernetes-entrypoint:v1.0.0
|
||||
image_repo_sync: docker.io/docker:17.07.0
|
||||
ks_user: docker.io/openstackhelm/heat:stein-ubuntu_bionic
|
||||
@ -257,133 +254,42 @@ network_policy:
|
||||
|
||||
conf:
|
||||
debug: false
|
||||
pg_hba: |
|
||||
host all all 127.0.0.1/32 trust
|
||||
host all all 0.0.0.0/0 md5
|
||||
local all all trust
|
||||
|
||||
postgresql:
|
||||
shared_buffers: 128MB
|
||||
max_connections: 100
|
||||
patroni: |
|
||||
scope: {{ tuple "postgresql" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
|
||||
kubernetes:
|
||||
labels:
|
||||
application: {{ tuple "postgresql" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
|
||||
component: server
|
||||
use_endpoints: true
|
||||
ports:
|
||||
- name: {{ tuple "postgresql" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
|
||||
port: {{ tuple "postgresql" "internal" "postgresql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
|
||||
bootstrap:
|
||||
users:
|
||||
{{ .Values.endpoints.postgresql.auth.admin.username }}:
|
||||
password: {{ .Values.endpoints.postgresql.auth.admin.password }}
|
||||
options:
|
||||
- createrole
|
||||
- createdb
|
||||
dcs:
|
||||
ttl: 30
|
||||
loop_wait: 10
|
||||
retry_timeout: 10
|
||||
maximum_lag_on_failover: 1048576
|
||||
postgresql:
|
||||
data_dir: '{{ .Values.storage.mount.path }}/pgdata'
|
||||
pgpass: '{{ .Values.storage.mount.path }}/pgpass'
|
||||
use_pg_rewind: true
|
||||
parameters:
|
||||
archive_mode: 'off'
|
||||
cluster_name: 'postgresql'
|
||||
datestyle: 'iso, mdy'
|
||||
external_pid_file: '/tmp/postgres.pid'
|
||||
hot_standby: 'on'
|
||||
fsync: 'on'
|
||||
listen_addresses: '0.0.0.0'
|
||||
log_checkpoints: 'on'
|
||||
log_connections: 'on'
|
||||
log_disconnections: 'on'
|
||||
log_line_prefix: 'postgresql: %t [%p]: [%l-1] %c %x %d %u %a %h %m '
|
||||
log_lock_waits: 'on'
|
||||
log_temp_files: 0
|
||||
log_temp_files: '0'
|
||||
log_timezone: 'UTC'
|
||||
max_connections: {{ .Values.conf.postgresql.max_connections }}
|
||||
max_replication_slots: 10
|
||||
max_wal_senders: 10
|
||||
max_worker_processes: 10
|
||||
ssl: 'on'
|
||||
# These relative paths are relative to data_dir
|
||||
ssl_cert_file: {{ .Values.secrets.pki.server_cert_path }}/server.crt
|
||||
ssl_ca_file: {{ .Values.secrets.pki.server_cert_path }}/ca.crt
|
||||
ssl_key_file: {{ .Values.secrets.pki.server_cert_path }}/server.key
|
||||
ssl_ciphers: 'HIGH:+3DES:!aNULL'
|
||||
tcp_keepalives_idle: 900
|
||||
tcp_keepalives_interval: 100
|
||||
max_connections: '1000'
|
||||
max_locks_per_transaction: '64'
|
||||
max_prepared_transactions: '0'
|
||||
max_wal_senders: '16'
|
||||
max_worker_processes: '10'
|
||||
port: '5432'
|
||||
shared_buffers: '2GB'
|
||||
tcp_keepalives_idle: '900'
|
||||
tcp_keepalives_interval: '100'
|
||||
timezone: 'UTC'
|
||||
track_commit_timestamp: 'on'
|
||||
track_functions: all
|
||||
wal_keep_segments: 8
|
||||
wal_level: hot_standby
|
||||
track_functions: 'all'
|
||||
wal_keep_segments: '16'
|
||||
wal_level: 'hot_standby'
|
||||
wal_log_hints: 'on'
|
||||
initdb:
|
||||
- auth-host: md5
|
||||
- auth-local: trust
|
||||
- encoding: UTF8
|
||||
- locale: en_US.UTF-8
|
||||
- data-checksums
|
||||
pg_hba:
|
||||
- host all all 127.0.0.1/32 trust
|
||||
- host all all 0.0.0.0/0 md5
|
||||
- hostssl replication {{ .Values.endpoints.postgresql.auth.replica.username }} {{ .Values.secrets.pki.pod_cidr }} cert clientcert=1
|
||||
- hostssl replication {{ .Values.endpoints.postgresql.auth.replica.username }} 127.0.0.1/32 cert clientcert=1
|
||||
- local all all trust
|
||||
postgresql:
|
||||
{{/* Note: the postgres pod mounts a volume at /var/lib/postgresql/data,
|
||||
so let's just avoid it and use /var/lib/postgresql/pgdata instead.
|
||||
Patroni moves this directory to a backup under the parent directory
|
||||
(/var/lib/postgresql) under certain failure recovery scenarios, so
|
||||
/var/lib/postgres itself must be exposed to the pod as a pvc mount.*/}}
|
||||
authentication:
|
||||
superuser:
|
||||
username: {{ .Values.endpoints.postgresql.auth.admin.username }}
|
||||
password: {{ .Values.endpoints.postgresql.auth.admin.password }}
|
||||
data_dir: '{{ .Values.storage.mount.path }}/pgdata'
|
||||
pgpass: '{{ .Values.storage.mount.path }}/pgpass'
|
||||
callbacks:
|
||||
on_role_change: /tmp/set_password.sh
|
||||
on_start: /tmp/set_password.sh
|
||||
use_pg_rewind: true
|
||||
remove_data_directory_on_rewind_failure: true
|
||||
remove_data_directory_on_diverged_timelines: true
|
||||
parameters:
|
||||
archive_mode: 'off'
|
||||
datestyle: 'iso, mdy'
|
||||
external_pid_file: '/tmp/postgres.pid'
|
||||
hot_standby: 'on'
|
||||
log_checkpoints: 'on'
|
||||
log_connections: 'on'
|
||||
log_disconnections: 'on'
|
||||
log_line_prefix: 'postgresql: %t [%p]: [%l-1] %c %x %d %u %a %h %m '
|
||||
log_lock_waits: 'on'
|
||||
log_temp_files: 0
|
||||
log_timezone: 'UTC'
|
||||
max_connections: {{ .Values.conf.postgresql.max_connections }}
|
||||
max_replication_slots: 10
|
||||
max_wal_senders: 10
|
||||
max_worker_processes: 10
|
||||
ssl: 'on'
|
||||
# These relative paths are relative to data_dir
|
||||
ssl_cert_file: {{ .Values.secrets.pki.server_cert_path }}/server.crt
|
||||
ssl_ca_file: {{ .Values.secrets.pki.server_cert_path }}/ca.crt
|
||||
ssl_key_file: {{ .Values.secrets.pki.server_cert_path }}/server.key
|
||||
ssl_ciphers: 'HIGH:+3DES:!aNULL'
|
||||
tcp_keepalives_idle: 900
|
||||
tcp_keepalives_interval: 100
|
||||
timezone: 'UTC'
|
||||
track_commit_timestamp: 'on'
|
||||
track_functions: all
|
||||
wal_keep_segments: 8
|
||||
wal_level: hot_standby
|
||||
wal_log_hints: 'on'
|
||||
pg_hba:
|
||||
- host all all 127.0.0.1/32 trust
|
||||
- host all all 0.0.0.0/0 md5
|
||||
- hostssl replication {{ .Values.endpoints.postgresql.auth.replica.username }} {{ .Values.secrets.pki.pod_cidr }} cert clientcert=1
|
||||
- hostssl replication {{ .Values.endpoints.postgresql.auth.replica.username }} 127.0.0.1/32 cert clientcert=1
|
||||
- local all all trust
|
||||
watchdog:
|
||||
mode: off # Allowed values: off, automatic, required
|
||||
hba_file: '/tmp/pg_hba.conf'
|
||||
ident_file: '/tmp/pg_ident.conf'
|
||||
backup:
|
||||
enabled: false
|
||||
base_path: /var/backup
|
||||
@ -397,16 +303,6 @@ conf:
|
||||
|
||||
exporter:
|
||||
queries:
|
||||
pg_replication:
|
||||
query: "SELECT EXTRACT(epoch FROM (now() - pg_last_xact_replay_timestamp()))::int AS lag, CASE WHEN pg_is_in_recovery() THEN 1 ELSE 0 END AS is_replica"
|
||||
master: true
|
||||
metrics:
|
||||
- lag:
|
||||
usage: "GAUGE"
|
||||
description: "Replication lag behind master in seconds"
|
||||
- is_replica:
|
||||
usage: "GAUGE"
|
||||
description: "Indicates if this host is a replica"
|
||||
pg_postmaster:
|
||||
query: "SELECT pg_postmaster_start_time as start_time_seconds from pg_postmaster_start_time()"
|
||||
master: true
|
||||
@ -416,26 +312,8 @@ conf:
|
||||
description: "Time at which postmaster started"
|
||||
|
||||
secrets:
|
||||
pki:
|
||||
client_cert_path: /client_certs
|
||||
server_cert_path: /server_certs
|
||||
pod_cidr: 0.0.0.0/0
|
||||
server:
|
||||
hosts:
|
||||
names:
|
||||
# this name should be the service name for postgresql
|
||||
- postgresql.ucp.svc.cluster.local
|
||||
life: 365
|
||||
replication:
|
||||
hosts:
|
||||
names:
|
||||
# this name needs to be the same as endpoints.postgres.auth.replica.username
|
||||
- standby
|
||||
life: 365
|
||||
postgresql:
|
||||
admin: postgresql-admin
|
||||
replica: postgresql-replication-pki
|
||||
server: postgresql-server-pki
|
||||
exporter: postgresql-exporter
|
||||
audit: postgresql-audit
|
||||
backup_restore: postgresql-backup-restore
|
||||
@ -462,8 +340,6 @@ endpoints:
|
||||
admin:
|
||||
username: postgres
|
||||
password: password
|
||||
replica:
|
||||
username: standby
|
||||
exporter:
|
||||
username: psql_exporter
|
||||
password: psql_exp_pass
|
||||
@ -548,8 +424,6 @@ manifests:
|
||||
network_policy: false
|
||||
job_ks_user: false
|
||||
secret_admin: true
|
||||
secret_replica: true
|
||||
secret_server: true
|
||||
secret_etc: true
|
||||
secret_audit: true
|
||||
secret_backup_restore: false
|
||||
|
@ -26,7 +26,7 @@ helm upgrade --install postgresql ./postgresql \
|
||||
--set monitoring.prometheus.enabled=true \
|
||||
--set storage.pvc.size=1Gi \
|
||||
--set storage.pvc.enabled=true \
|
||||
--set pod.replicas.server=3 \
|
||||
--set pod.replicas.server=1 \
|
||||
${OSH_INFRA_EXTRA_HELM_ARGS} \
|
||||
${OSH_INFRA_EXTRA_HELM_ARGS_POSTGRESQL}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user