weitere implementierung
This commit is contained in:
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Recovery
|
||||
|
||||
⚠️ Restore NICHT über Argo deployen
|
||||
|
||||
Use:
|
||||
|
||||
kubectl apply -f restore-latest.yaml
|
||||
@@ -1,9 +1,10 @@
|
||||
# 1. App für den CloudNativePG Operator
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: cnpg-operator
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
@@ -19,10 +20,11 @@ spec:
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeel: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
- SkipDryRunOnMissingResource=true
|
||||
automated:
|
||||
allowEmpty: true
|
||||
ignoreDifferences:
|
||||
@@ -30,5 +32,3 @@ spec:
|
||||
kind: CustomResourceDefinition
|
||||
jqPathExpressions:
|
||||
- .spec.conversion.webhook.clientConfig.caBundle
|
||||
dependsOn:
|
||||
- name: timescaledb-crds
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeel: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
|
||||
@@ -3,6 +3,8 @@ kind: Application
|
||||
metadata:
|
||||
name: timescaledb-crds
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
@@ -15,4 +17,4 @@ spec:
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeel: true
|
||||
selfHeal: true
|
||||
|
||||
@@ -3,6 +3,8 @@ kind: Application
|
||||
metadata:
|
||||
name: timescaledb
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "2"
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
@@ -15,14 +17,13 @@ spec:
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeel: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
- SkipDryRunOnMissingResource=true
|
||||
ignoreDifferences:
|
||||
- group: postgresql.cnpg.io
|
||||
kind: Cluster
|
||||
jqPathExpressions:
|
||||
- .status
|
||||
dependsOn:
|
||||
- name: cnpg-operator
|
||||
18
argocd/root.yaml
Normal file
18
argocd/root.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: root-apps
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://gitea.vhn-demo.duckdns.org/hoang/timescaledb.git
|
||||
path: argocd/applications
|
||||
targetRevision: main
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
11
k8s/base/database/backup-daily.yaml
Normal file
11
k8s/base/database/backup-daily.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: timescale-backup-daily
|
||||
namespace: database
|
||||
spec:
|
||||
schedule: "0 2 * * *" # täglich 02:00
|
||||
backupOwnerReference: self
|
||||
cluster:
|
||||
name: timescale-cluster
|
||||
method: barmanObjectStore
|
||||
12
k8s/base/database/backup-hourly.yaml
Normal file
12
k8s/base/database/backup-hourly.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: timescale-backup-hourly
|
||||
namespace: database
|
||||
spec:
|
||||
schedule: "0 * * * *" # jede Stunden
|
||||
backupOwnerReference: self
|
||||
cluster:
|
||||
name: timescale-cluster
|
||||
method: barmanObjectStore
|
||||
|
||||
17
k8s/base/database/backup-monitor.yaml
Normal file
17
k8s/base/database/backup-monitor.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PrometheusRule
|
||||
metadata:
|
||||
name: cnpg-backup-alert
|
||||
namespace: database
|
||||
spec:
|
||||
groups:
|
||||
- name: cnpg.rules
|
||||
rules:
|
||||
- alert: CNPGBackupMissing
|
||||
expr: time() - cnpg_last_backup_time_seconds > 86400
|
||||
for: 10m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "CNPG Backup missing"
|
||||
description: "No backup in last 24h"
|
||||
@@ -4,10 +4,51 @@ metadata:
|
||||
name: timescale-cluster
|
||||
spec:
|
||||
instances: 3
|
||||
|
||||
imageName: timescale/timescaledb:2.15.3-pg15
|
||||
|
||||
# ✅ Initiales Setup
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: app
|
||||
owner: app
|
||||
|
||||
# ✅ Storage
|
||||
storage:
|
||||
size: 50Gi
|
||||
|
||||
# ✅ Ressourcen (wichtig!)
|
||||
resources:
|
||||
requests:
|
||||
memory: "2Gi"
|
||||
cpu: "500m"
|
||||
limits:
|
||||
memory: "4Gi"
|
||||
cpu: "2"
|
||||
|
||||
# ✅ High Availability
|
||||
affinity:
|
||||
enablePodAntiAffinity: true
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
# ✅ Monitoring
|
||||
monitoring:
|
||||
enablePodMonitor: true
|
||||
|
||||
# ✅ PostgreSQL / Timescale Tuning
|
||||
postgresql:
|
||||
parameters:
|
||||
max_connections: "100" # mehr Verbindungen 200
|
||||
shared_buffers: "256MB" # Cache im RAM 1GB
|
||||
effective_cache_size: "3GB" # Optimizer hint
|
||||
work_mem: "16MB" # pro Query
|
||||
maintenance_work_mem: "256MB" # für VACUUM/REINDEX
|
||||
wal_buffers: "16MB"
|
||||
checkpoint_completion_target: "0.9"
|
||||
random_page_cost: "1.1" # SSD optimiert
|
||||
effective_io_concurrency: "200"
|
||||
backup:
|
||||
retentionPolicy: "7d" # Backup älter als 7 Tage -> automatisch gelöscht
|
||||
barmanObjectStore:
|
||||
destinationPath: "s3://backups/"
|
||||
endpointURL: "http://minio.minio-system.svc.cluster.local:9000"
|
||||
@@ -18,3 +59,5 @@ spec:
|
||||
secretAccessKey:
|
||||
name: s3-creds
|
||||
key: SECRET_ACCESS_KEY
|
||||
wal:
|
||||
compression: gzip
|
||||
@@ -1,2 +1,9 @@
|
||||
resources:
|
||||
- cluster.yaml
|
||||
- s3-secret.yaml
|
||||
- backup-hourly.yaml
|
||||
- backup-daily.yaml
|
||||
- restore-cronjob.yaml
|
||||
- restore-configmap.yaml
|
||||
|
||||
|
||||
|
||||
33
k8s/base/database/restore-configmap.yaml
Normal file
33
k8s/base/database/restore-configmap.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: restore-test-manifest
|
||||
namespace: database
|
||||
data:
|
||||
restore-test.yaml: |
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: timescale-restore-test
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: timescale/timescaledb:2.15.3-pg15
|
||||
bootstrap:
|
||||
recovery:
|
||||
source: timescale-cluster
|
||||
recoveryTarget:
|
||||
targetImmediate: true
|
||||
storage:
|
||||
size: 10Gi
|
||||
externalClusters:
|
||||
- name: timescale-cluster
|
||||
barmanObjectStore:
|
||||
destinationPath: "s3://backups/"
|
||||
endpointURL: "http://minio.minio-system.svc.cluster.local:9000"
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: s3-creds
|
||||
key: S3_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: s3-creds
|
||||
key: S3_SECRET_ACCESS_KEY
|
||||
34
k8s/base/database/restore-cronjob.yaml
Normal file
34
k8s/base/database/restore-cronjob.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: timescale-restore-test
|
||||
namespace: database
|
||||
spec:
|
||||
schedule: "0 4 * * *" # täglich 04:00
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: restore-test
|
||||
image: bitnami/kubectl:latest
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
kubectl apply -f /manifests/restore-test.yaml
|
||||
sleep 300
|
||||
|
||||
kubectl get pods -n database
|
||||
|
||||
echo "✅ Restore Test executed"
|
||||
|
||||
kubectl delete cluster timescale-restore-test -n database || true
|
||||
volumeMounts:
|
||||
- name: manifests
|
||||
mountPath: /manifests
|
||||
volumes:
|
||||
- name: manifests
|
||||
configMap:
|
||||
name: restore-test-manifest
|
||||
9
k8s/base/database/s3-secret.yaml
Normal file
9
k8s/base/database/s3-secret.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: s3-creds
|
||||
namespace: database
|
||||
type: Opaque
|
||||
stringData:
|
||||
S3_ACCESS_KEY_ID: admin
|
||||
S3_SECRET_ACCESS_KEY: password123
|
||||
25
k8s/recovery/restore-latest.yaml
Normal file
25
k8s/recovery/restore-latest.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: timescale-restore-latest
|
||||
namespace: database
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: timescale/timescaledb:2.15.3-pg15
|
||||
bootstrap:
|
||||
recovery:
|
||||
source: timescale-cluster
|
||||
storage:
|
||||
size: 50Gi
|
||||
externalClusters:
|
||||
- name: timescale-cluster
|
||||
barmanObjectStore:
|
||||
destinationPath: "s3://backups/"
|
||||
endpointURL: "http://minio.minio-system.svc.cluster.local:9000"
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: s3-creds
|
||||
key: S3_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: s3-creds
|
||||
key: S3_SECRET_ACCESS_KEY
|
||||
34
k8s/recovery/restore-test.yaml
Normal file
34
k8s/recovery/restore-test.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: timescale-restore-test
|
||||
namespace: database
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: timescale/timescaledb:2.15.3-pg15
|
||||
bootstrap:
|
||||
recovery:
|
||||
source: timescale-cluster
|
||||
recoveryTarget:
|
||||
targetImmediate: true # sofort letzter WAL Stand
|
||||
storage:
|
||||
size: 10Gi # kleiner für Tests
|
||||
resources:
|
||||
requests:
|
||||
memory: "512Mi"
|
||||
cpu: "200m"
|
||||
limits:
|
||||
memory: "1Gi"
|
||||
cpu: "500m"
|
||||
externalClusters:
|
||||
- name: timescale-cluster
|
||||
barmanObjectStore:
|
||||
destinationPath: "s3://backups/"
|
||||
endpointURL: "http://minio.minio-system.svc.cluster.local:9000"
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: s3-creds
|
||||
key: S3_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: s3-creds
|
||||
key: S3_SECRET_ACCESS_KEY
|
||||
27
k8s/recovery/restore-timestamp.yaml
Normal file
27
k8s/recovery/restore-timestamp.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: timescale-restore-pitr
|
||||
namespace: database
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: timescale/timescaledb:2.15.3-pg15
|
||||
bootstrap:
|
||||
recovery:
|
||||
source: timescale-cluster
|
||||
recoveryTarget:
|
||||
targetTime: "2026-05-06 02:30:00" # ANPASSEN
|
||||
storage:
|
||||
size: 50Gi
|
||||
externalClusters:
|
||||
- name: timescale-cluster
|
||||
barmanObjectStore:
|
||||
destinationPath: "s3://backups/"
|
||||
endpointURL: "http://minio.minio-system.svc.cluster.local:9000"
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: s3-creds
|
||||
key: S3_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: s3-creds
|
||||
key: S3_SECRET_ACCESS_KEY
|
||||
32
scripts/restore.sh
Normal file
32
scripts/restore.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
MODE=$1
|
||||
TIMESTAMP=$2
|
||||
|
||||
echo "🚀 Starting restore..."
|
||||
|
||||
if [ "$MODE" == "latest" ]; then
|
||||
kubectl apply -f restore-latest.yaml
|
||||
|
||||
elif [ "$MODE" == "pitr" ]; then
|
||||
if [ -z "$TIMESTAMP" ]; then
|
||||
echo "❌ Please provide timestamp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed "s/TIMESTAMP/$TIMESTAMP/" restore-timestamp.yaml | kubectl apply -f -
|
||||
|
||||
elif [ "$MODE" == "test" ]; then
|
||||
kubectl apply -f restore-test.yaml
|
||||
|
||||
else
|
||||
echo "Usage:"
|
||||
echo " ./restore.sh latest"
|
||||
echo " ./restore.sh pitr '2026-05-06 02:30:00'"
|
||||
echo " ./restore.sh test"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Restore triggered"
|
||||
Reference in New Issue
Block a user