refactor: Replace CNPG external DB with rancher-backup operator
All checks were successful
Deploy Cluster / Terraform (push) Successful in 48s
Deploy Cluster / Ansible (push) Successful in 6m5s

Rancher 2.x uses embedded etcd, not an external PostgreSQL database.
The CATTLE_DB_CATTLE_* env vars are Rancher v1 only and were ignored.

- Remove all CNPG (CloudNativePG) cluster, operator, and related configs
- Remove external DB env vars from Rancher HelmRelease
- Remove rancher-db-password ExternalSecret
- Add rancher-backup operator HelmRelease (v106.0.2+up8.1.0)
- Add B2 credentials ExternalSecret for backup storage
- Add recurring Backup CR (daily at 03:00, 7 day retention)
- Add commented-out Restore CR for rebuild recovery
- Update Flux dependency graph accordingly
This commit is contained in:
2026-03-29 21:53:16 +00:00
parent efdf13976a
commit f2c506b350
22 changed files with 66 additions and 245 deletions

View File

@@ -1,5 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- helmrepository-cnpg.yaml
- helmrelease-cnpg.yaml

View File

@@ -1,19 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: cnpg-cluster-rw
namespace: cnpg-cluster
labels:
app.kubernetes.io/name: rancher-db
cnpg.io/cluster: rancher-db
spec:
type: ClusterIP
clusterIP: None
ports:
- port: 5432
targetPort: 5432
protocol: TCP
selector:
app.kubernetes.io/name: postgresql
cnpg.io/cluster: rancher-db
role: primary

View File

@@ -1,11 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- b2-credentials-externalsecret.yaml
- rancher-db-password-externalsecret.yaml
- postgres-cluster.yaml
- cnpg-cluster-rw-svc.yaml
- role-b2-reader.yaml
- rolebinding-b2-reader.yaml
- scheduled-backup-rancher.yaml

View File

@@ -1,79 +0,0 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: rancher-db
namespace: cnpg-cluster
annotations:
cnpg.io/skipEmptyWalArchiveCheck: "enabled"
spec:
description: "Rancher external database cluster"
imageName: ghcr.io/cloudnative-pg/postgresql:17.4
imagePullPolicy: IfNotPresent
instances: 1
primaryUpdateStrategy: unsupervised
storage:
storageClass: local-path
size: 50Gi
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
serviceAccountTemplate:
metadata:
labels:
app.kubernetes.io/name: rancher-db
superuserSecret:
name: rancher-db-password
bootstrap:
recovery:
source: b2-backup
externalClusters:
- name: b2-backup
barmanObjectStore:
destinationPath: "s3://HetznerTerra/rancher-backups/"
endpointURL: "https://s3.us-east-005.backblazeb2.com"
serverName: rancher-db
s3Credentials:
accessKeyId:
name: b2-credentials
key: B2_ACCOUNT_ID
secretAccessKey:
name: b2-credentials
key: B2_APPLICATION_KEY
monitoring:
enablePodMonitor: false
affinity:
nodeSelector:
kubernetes.io/hostname: k8s-cluster-cp-1
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
backup:
barmanObjectStore:
destinationPath: "s3://HetznerTerra/rancher-backups/"
endpointURL: "https://s3.us-east-005.backblazeb2.com"
s3Credentials:
accessKeyId:
name: b2-credentials
key: B2_ACCOUNT_ID
secretAccessKey:
name: b2-credentials
key: B2_APPLICATION_KEY
wal:
compression: gzip
data:
compression: gzip

View File

@@ -1,21 +0,0 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: rancher-db-password
namespace: cnpg-cluster
spec:
refreshInterval: 1h
secretStoreRef:
name: doppler-hetznerterra
kind: ClusterSecretStore
target:
name: rancher-db-password
creationPolicy: Owner
template:
type: Opaque
data:
password: "{{ .RANCHER_DB_PASSWORD }}"
data:
- secretKey: RANCHER_DB_PASSWORD
remoteRef:
key: RANCHER_DB_PASSWORD

View File

@@ -1,10 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: rancher-db-b2-reader
namespace: cnpg-cluster
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["b2-credentials"]
verbs: ["get", "list"]

View File

@@ -1,13 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rancher-db-b2-reader
namespace: cnpg-cluster
subjects:
- kind: ServiceAccount
name: rancher-db
namespace: cnpg-cluster
roleRef:
kind: Role
name: rancher-db-b2-reader
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,11 +0,0 @@
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: rancher-db-weekly
namespace: cnpg-cluster
spec:
schedule: "0 0 2 * * 0"
backupOwnerReference: self
cluster:
name: rancher-db
target: primary

View File

@@ -1,15 +0,0 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: addon-cnpg-operator
namespace: flux-system
spec:
interval: 10m
prune: true
sourceRef:
kind: GitRepository
name: platform
path: ./infrastructure/addons/cnpg-operator
wait: true
timeout: 10m
suspend: false

View File

@@ -1,7 +1,7 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: addon-cnpg
name: addon-rancher-backup
namespace: flux-system
spec:
interval: 10m
@@ -9,15 +9,10 @@ spec:
sourceRef:
kind: GitRepository
name: platform
path: ./infrastructure/addons/cnpg
path: ./infrastructure/addons/rancher-backup
wait: true
timeout: 10m
suspend: false
dependsOn:
- name: addon-cnpg-operator
- name: addon-external-secrets
healthChecks:
- apiVersion: v1
kind: Secret
name: b2-credentials
namespace: cnpg-cluster
- name: addon-rancher

View File

@@ -17,4 +17,3 @@ spec:
- name: addon-tailscale-operator
- name: addon-tailscale-proxyclass
- name: addon-external-secrets
- name: addon-cnpg

View File

@@ -10,7 +10,6 @@ resources:
- kustomization-flux-ui.yaml
- kustomization-observability.yaml
- kustomization-observability-content.yaml
- kustomization-cnpg-operator.yaml
- kustomization-cnpg.yaml
- kustomization-rancher.yaml
- kustomization-rancher-config.yaml
- kustomization-rancher-backup.yaml

View File

@@ -1,25 +1,25 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: b2-credentials
namespace: cnpg-cluster
name: rancher-b2-creds
namespace: cattle-resources-system
spec:
refreshInterval: 1h
secretStoreRef:
name: doppler-hetznerterra
kind: ClusterSecretStore
target:
name: b2-credentials
name: rancher-b2-creds
creationPolicy: Owner
template:
type: Opaque
data:
B2_ACCOUNT_ID: "{{ .B2_ACCOUNT_ID }}"
B2_APPLICATION_KEY: "{{ .B2_APPLICATION_KEY }}"
aws_access_key_id: "{{ .B2_ACCOUNT_ID }}"
aws_secret_access_key: "{{ .B2_APPLICATION_KEY }}"
data:
- secretKey: B2_ACCOUNT_ID
remoteRef:
key: B2_ACCOUNT_ID
- secretKey: B2_APPLICATION_KEY
remoteRef:
key: B2_APPLICATION_KEY
key: B2_APPLICATION_KEY

View File

@@ -0,0 +1,17 @@
apiVersion: resources.cattle.io/v1
kind: Backup
metadata:
name: rancher-b2-recurring
namespace: cattle-resources-system
spec:
resourceSetName: rancher-resource-set-full
storageLocation:
s3:
credentialSecretName: rancher-b2-creds
credentialSecretNamespace: cattle-resources-system
bucketName: HetznerTerra
folder: rancher-backups
endpoint: s3.us-east-005.backblazeb2.com
region: us-east-005
schedule: "0 3 * * *"
retentionCount: 7

View File

@@ -1,18 +1,18 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: cnpg
name: rancher-backup
namespace: flux-system
spec:
interval: 10m
targetNamespace: cnpg-system
targetNamespace: cattle-resources-system
chart:
spec:
chart: cloudnative-pg
version: 0.27.1
chart: rancher-backup
version: "106.0.2+up8.1.0"
sourceRef:
kind: HelmRepository
name: cnpg
name: rancher-charts
namespace: flux-system
install:
createNamespace: true
@@ -23,4 +23,6 @@ spec:
retries: 3
values:
image:
repository: ghcr.io/cloudnative-pg/cloudnative-pg
repository: rancher/backup-restore-operator
s3:
enabled: true

View File

@@ -1,8 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: cnpg
name: rancher-charts
namespace: flux-system
spec:
interval: 1h
url: https://cloudnative-pg.github.io/charts
url: https://charts.rancher.io

View File

@@ -0,0 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- helmrepository-rancher-backup.yaml
- helmrelease-rancher-backup.yaml
- b2-credentials-externalsecret.yaml
- backup-recurring.yaml
- restore-from-b2.yaml

View File

@@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: cnpg-cluster
name: cattle-resources-system

View File

@@ -0,0 +1,19 @@
# Uncomment and set backupFilename to restore from a specific backup on rebuild.
# Find the latest backup filename in B2: rancher-backups/ folder.
# After restore succeeds, Rancher will have all users/settings from the backup.
#
# apiVersion: resources.cattle.io/v1
# kind: Restore
# metadata:
# name: restore-from-b2
# namespace: cattle-resources-system
# spec:
# backupFilename: <backup-filename-from-b2>
# storageLocation:
# s3:
# credentialSecretName: rancher-b2-creds
# credentialSecretNamespace: cattle-resources-system
# bucketName: HetznerTerra
# folder: rancher-backups
# endpoint: s3.us-east-005.backblazeb2.com
# region: us-east-005

View File

@@ -26,19 +26,6 @@ spec:
tls: external
replicas: 1
extraEnv:
- name: CATTLE_DB_CATTLE_HOST
value: cnpg-cluster-rw.cnpg-cluster.svc
- name: CATTLE_DB_CATTLE_PORT
value: "5432"
- name: CATTLE_DB_CATTLE_DATABASE
value: postgres
- name: CATTLE_DB_CATTLE_USERNAME
value: postgres
- name: CATTLE_DB_CATTLE_PASSWORD
valueFrom:
secretKeyRef:
name: rancher-db-password
key: password
- name: CATTLE_PROMETHEUS_METRICS
value: "true"
resources:

View File

@@ -6,5 +6,4 @@ resources:
- helmrelease-rancher.yaml
- rancher-bootstrap-password-flux-externalsecret.yaml
- rancher-bootstrap-password-externalsecret.yaml
- rancher-db-password-externalsecret.yaml
- rancher-tailscale-service.yaml

View File

@@ -1,21 +0,0 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: rancher-db-password
namespace: cattle-system
spec:
refreshInterval: 1h
secretStoreRef:
name: doppler-hetznerterra
kind: ClusterSecretStore
target:
name: rancher-db-password
creationPolicy: Owner
template:
type: Opaque
data:
password: "{{ .RANCHER_DB_PASSWORD }}"
data:
- secretKey: RANCHER_DB_PASSWORD
remoteRef:
key: RANCHER_DB_PASSWORD