Files
italiadatacenter/add-on/postgresql.sh
alessandro 20d506407a primo
2026-07-17 09:42:52 +02:00

315 lines
7.3 KiB
Bash

kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml--force-conflicts
curl -sSfL https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | sudo sh -s -- -b /usr/local/bin
kubectl create namespace database
database.yaml:
---
apiVersion: v1
kind: Secret
metadata:
name: pg-app-user
namespace: demo-apps
type: kubernetes.io/basic-auth
stringData:
username: admin
password: admin
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-test
namespace: demo-apps
spec:
instances: 3
storage:
size: 1Gi
storageClass: csi-rbdfs-sc
walStorage:
storageClass: csi-rbdfs-sc
size: 1Gi
bootstrap:
initdb:
database: testdb
owner: admin
secret:
name: pg-app-user
postgresql:
parameters:
max_connections: "300"
shared_buffers: "1GB"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
#test
kubectl run psql-client -n database --rm -it --image=postgres:16 --env="PGPASSWORD=admin" -- psql -h pg-test-rw.demo-apps.svc -U admin -d appdb
kubectl patch pvc pg-test-1-wal -n demo_apps -p '{"spec":{"resources":{"requests":{"storage":"32Gi"}}}}'
backup:
barmanObjectStore:
destinationPath: s3://pg-backups/prod
endpointURL: http://minio.minio.svc:9000
s3Credentials:
accessKeyId:
name: s3-creds
key: ACCESS_KEY
secretAccessKey:
name: s3-creds
key: SECRET_KEY
--- pgadmin -------------------
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgadmin-deployment
spec:
replicas: 1
selector:
matchLabels:
app: pgadmin
template:
metadata:
labels:
app: pgadmin
spec:
containers:
- name: pgadmin
image: dpage/pgadmin4
ports:
- containerPort: 80
env:
- name: PGADMIN_DEFAULT_EMAIL
value: pgadmin@italiadatacenter.com
- name: PGADMIN_DEFAULT_PASSWORD
value: KAYQE1QA7uwUZ8uI
---
apiVersion: v1
kind: Service
metadata:
name: pgadmin-service
spec:
selector:
app: pgadmin
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: demo-route
namespace: demo-apps
spec:
hostnames:
- poc3.italiadatacenter.com
parentRefs:
- name: main-gateway
namespace: nginx-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: pgadmin-service
port: 80
--------------------------------------------------------------------------------
cat <<EOF | kubectl -n database apply -f -
# This StorageClass is optimized for use with CloudNativePG.
# It disables storage-level replication and ensures data is local to the pod.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-cnpg-strict-local
provisioner: driver.longhorn.io
# allowVolumeExpansion is crucial for scaling database storage without downtime.
allowVolumeExpansion: true
# reclaimPolicy: Delete ensures that when a PVC is deleted, the underlying
# Longhorn volume is also removed, preventing orphaned storage.
reclaimPolicy: Delete
parameters:
# This is the most important setting. We rely on CloudNativePG for replication,
# so we only need one copy at the storage layer to avoid write amplification.
numberOfReplicas: "1"
# dataLocality: strict-local guarantees that the volume data will be stored
# on the same node as the pod that uses it. This is essential for performance
# and for aligning with a true shared-nothing architecture.
dataLocality: "strict-local"
# A longer timeout for stale replicas is suitable for database workloads.
staleReplicaTimeout: "2880" # 48 hours in minutes
# Default filesystem.
fsType: "ext4"
EOF
kubectl cnpg psql pg-devops -n devops
CREATE DATABASE giteadb;
CREATE USER gitea WITH PASSWORD 'KAYQE1QA7uwUZ8uI';
GRANT ALL PRIVILEGES ON DATABASE giteadb TO gitea;
ALTER DATABASE giteadb OWNER TO gitea;
cluster production ready:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: mycluster
namespace: database
spec:
instances: 3 # → 3 nodi per HA reale
primaryUpdateStrategy: unsupervised
failover: # → Failover automatico
promoteTimeout: 5m
targetPromotionRule: "prefer-high-promotion-score"
# ---------------------------
# STORAGE (PRODUCTION)
# ---------------------------
storage:
size: 200Gi
storageClass: fast-rbd # Ceph, SSD, GP3 ecc.
resizeInUse: true
walStorage: # Consigliato in produzione
size: 50Gi
storageClass: fast-rbd
# ---------------------------
# WAL ARCHIVING (S3/MINIO)
# ---------------------------
walArchive:
enabled: true
destinationPath: "s3://mybucket/wal/"
s3Credentials:
accessKeyId:
name: cnpg-s3-creds
key: ACCESS_KEY_ID
secretAccessKey:
name: cnpg-s3-creds
key: SECRET_ACCESS_KEY
endpointURL: "https://s3.myregion.amazonaws.com"
region: "myregion"
encryption: AES256
# ---------------------------
# BACKUP AUTOMATICI
# ---------------------------
backup:
barmanObjectStore:
destinationPath: "s3://mybucket/basebackup/"
endpointURL: "https://s3.myregion.amazonaws.com"
s3Credentials:
accessKeyId:
name: cnpg-s3-creds
key: ACCESS_KEY_ID
secretAccessKey:
name: cnpg-s3-creds
key: SECRET_ACCESS_KEY
wal:
compression: bzip2
encryption: AES256
retentionPolicy: "30d" # → 30 giorni di retention
monitoring:
enablePodMonitor: true
# ---------------------------
# TLS INTERNO (RACCOMANDATO)
# ---------------------------
certificates:
serverTLSSecret: cnpg-server-tls
clientTLSSecret: cnpg-client-tls
# ---------------------------
# RESOURCE MANAGEMENT
# ---------------------------
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "4"
memory: "8Gi"
# ---------------------------
# ANTI-AFFINITY & PDB
# ---------------------------
affinity:
enablePodAntiAffinity: true
topologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
minAvailable: 2
# ---------------------------
# STARTUP & HEALTH
# ---------------------------
postgresql:
shared_preload_libraries:
- "pg_stat_statements"
- "auto_explain"
parameters:
max_connections: "300"
shared_buffers: "2GB"
effective_cache_size: "6GB"
maintenance_work_mem: "512MB"
wal_compression: "on"
wal_level: "replica"
max_wal_size: "4GB"
checkpoint_timeout: "15min"
synchronous_commit: "remote_apply"
# ---------------------------
# SYNCHRONOUS REPLICATION
# ---------------------------
replication:
synchronous:
mode: " quorum "
number: 1 # One sync replica; others async
# ---------------------------
# SERVICE & NETWORKING
# ---------------------------
service:
type: ClusterIP
primary:
type: ClusterIP
replicas:
type: ClusterIP
# ---------------------------
# ENCRYPTION AT REST (OPZIONALE)
# ---------------------------
encryption:
enabled: true
mode: aes256-gcm