106 lines
3.1 KiB
Bash
Executable File
106 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# PostgreSQL — the cluster half of the postgres cabinet: plain manifests, one replica on a PVC.
|
|
# Notes: docs/notes/addons.md
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
source ./lib/config.sh
|
|
load_config
|
|
|
|
K="kubectl --context ${KUBECONTEXT}"
|
|
NS="${DATA_NAMESPACE:-data}"
|
|
|
|
$K get namespace "$NS" >/dev/null 2>&1 || $K create namespace "$NS"
|
|
|
|
# The password is generated once and then left alone, so re-running this does
|
|
# not rotate the credential out from under whatever is already connected.
|
|
if $K get secret -n "$NS" postgres >/dev/null 2>&1; then
|
|
echo " secret exists, keeping the current password"
|
|
else
|
|
password=$(head -c 18 /dev/urandom | base64 | tr -d '/+=' | head -c 24)
|
|
$K create secret generic postgres -n "$NS" \
|
|
--from-literal=POSTGRES_DB="${POSTGRES_DB:-postgres}" \
|
|
--from-literal=POSTGRES_USER="${POSTGRES_USER:-postgres}" \
|
|
--from-literal=POSTGRES_PASSWORD="$password" >/dev/null
|
|
echo " generated a password (read it back with the command printed below)"
|
|
fi
|
|
|
|
echo " applying manifests"
|
|
$K apply -n "$NS" -f - >/dev/null <<YAML
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: postgres-data
|
|
spec:
|
|
accessModes: [ReadWriteOnce]
|
|
resources:
|
|
requests:
|
|
storage: ${POSTGRES_STORAGE:-2Gi}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: postgres
|
|
spec:
|
|
selector:
|
|
app: postgres
|
|
ports:
|
|
- port: 5432
|
|
targetPort: 5432
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: postgres
|
|
spec:
|
|
replicas: 1
|
|
# One volume, one writer. Rolling would start a second pod against the same
|
|
# PVC before the first exits, and Postgres refuses to share a data directory.
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: postgres
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: postgres
|
|
spec:
|
|
containers:
|
|
- name: postgres
|
|
image: ${POSTGRES_IMAGE}
|
|
envFrom:
|
|
- secretRef:
|
|
name: postgres
|
|
env:
|
|
# The image initialises into the volume root otherwise, and a
|
|
# lost+found from the PVC makes it refuse to initdb.
|
|
- name: PGDATA
|
|
value: /var/lib/postgresql/data/pgdata
|
|
ports:
|
|
- containerPort: 5432
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /var/lib/postgresql/data
|
|
readinessProbe:
|
|
exec:
|
|
command: ["sh", "-c", "pg_isready -U \$POSTGRES_USER -d \$POSTGRES_DB"]
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
livenessProbe:
|
|
exec:
|
|
command: ["sh", "-c", "pg_isready -U \$POSTGRES_USER -d \$POSTGRES_DB"]
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: postgres-data
|
|
YAML
|
|
|
|
echo " waiting for postgres..."
|
|
$K rollout status deployment/postgres -n "$NS" --timeout=240s
|
|
|
|
echo " in-cluster: postgres.${NS}.svc.cluster.local:5432"
|
|
echo " password: kubectl --context ${KUBECONTEXT} -n ${NS} get secret postgres -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d"
|