commit 6f7d6afacbea54b1fbc99d1bb5e80ae15c50d17f
parent 1d0ebc86f4adb81db6e6997742ad6ae34f83a05d
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Thu, 7 Aug 2025 14:31:06 +0200
Migrate to barman cloud cnpg plugin
Diffstat:
3 files changed, 196 insertions(+), 40 deletions(-)
diff --git a/apps/talos_cluster/monitoring-stack/release.yaml b/apps/talos_cluster/monitoring-stack/release.yaml
@@ -159,7 +159,9 @@ spec:
annotations:
__dashboardUid__: tbO9LAiZK
__panelId__: "7"
- description: One or more OSDs have reached the NEARFULL threshold. Use 'ceph health detail' and 'ceph osd df' to identify the problem. To resolve, add capacity to the affected OSD's failure domain, restore down/out OSDs, or delete unwanted data.
+ description: One or more OSDs have reached the NEARFULL threshold. Use 'ceph health detail'
+ and 'ceph osd df' to identify the problem. To resolve, add capacity to the affected OSD's
+ failure domain, restore down/out OSDs, or delete unwanted data.
runbook_url: https://docs.ceph.com/en/latest/rados/operations/health-checks#osd-nearfull
summary: OSD(s) running low on free space (NEARFULL)
isPaused: false
@@ -220,7 +222,8 @@ spec:
execErrState: Error
for: 5m
annotations:
- description: Depending on the rate limit, cert-manager may be unable to generate certificates for up to a week.
+ description: Depending on the rate limit, cert-manager may be unable to generate certificates
+ for up to a week.
summary: Cert manager hitting LetsEncrypt rate limits.
labels: {}
isPaused: false
@@ -1010,7 +1013,8 @@ spec:
auth_url: https://auth.midnightthoughts.space/application/o/authorize/
token_url: https://auth.midnightthoughts.space/application/o/token/
api_url: https://auth.midnightthoughts.space/application/o/userinfo/
- role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'
+ role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors')
+ && 'Editor' || 'Viewer'
imageRenderer:
enabled: true
kubeProxy:
diff --git a/infrastructure_talos/configs/cnpg-cluster-barmancloud-ext.yaml b/infrastructure_talos/configs/cnpg-cluster-barmancloud-ext.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.16.2
+ controller-gen.kubebuilder.io/version: v0.18.0
name: objectstores.barmancloud.cnpg.io
spec:
group: barmancloud.cnpg.io
@@ -36,12 +36,12 @@ spec:
metadata:
type: object
spec:
- description: ObjectStoreSpec defines the desired state of ObjectStore.
+ description: |-
+ Specification of the desired behavior of the ObjectStore.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
properties:
configuration:
- description: |-
- BarmanObjectStoreConfiguration contains the backup configuration
- using Barman against an S3-compatible object storage
+ description: The configuration for the barman-cloud tool suite
properties:
azureCredentials:
description: The credentials to use to upload data to Azure Blob Storage
@@ -137,10 +137,10 @@ spec:
description: |-
Compress a backup file (a tar file per tablespace) while streaming it
to the object store. Available options are empty string (no
- compression, default), `gzip`, `bzip2` or `snappy`.
+ compression, default), `gzip`, `bzip2`, and `snappy`.
enum:
- - gzip
- bzip2
+ - gzip
- snappy
type: string
encryption:
@@ -326,11 +326,15 @@ spec:
compression:
description: |-
Compress a WAL file before sending it to the object store. Available
- options are empty string (no compression, default), `gzip`, `bzip2` or `snappy`.
+ options are empty string (no compression, default), `gzip`, `bzip2`,
+ `lz4`, `snappy`, `xz`, and `zstd`.
enum:
- - gzip
- bzip2
+ - gzip
+ - lz4
- snappy
+ - xz
+ - zstd
type: string
encryption:
description: |-
@@ -374,9 +378,13 @@ spec:
required:
- destinationPath
type: object
+ x-kubernetes-validations:
+ - fieldPath: .serverName
+ message: use the 'serverName' plugin parameter in the Cluster resource
+ reason: FieldValueForbidden
+ rule: "!has(self.serverName)"
instanceSidecarConfiguration:
- description: InstanceSidecarConfiguration defines the configuration for the sidecar that runs
- in the instance pods.
+ description: The configuration for the sidecar that runs in the instance pods
properties:
env:
description: The environment to be explicitly passed to the sidecar
@@ -495,12 +503,111 @@ spec:
- name
type: object
type: array
+ resources:
+ description: Resources define cpu/memory requests and limits for the sidecar that
+ runs in the instance pods.
+ properties:
+ claims:
+ description: |-
+ Claims lists the names of resources, defined in spec.resourceClaims,
+ that are used by this container.
+
+ This is an alpha field and requires enabling the
+ DynamicResourceAllocation feature gate.
+
+ This field is immutable. It can only be set for containers.
+ items:
+ description: ResourceClaim references one entry in PodSpec.ResourceClaims.
+ properties:
+ name:
+ description: |-
+ Name must match the name of one entry in pod.spec.resourceClaims of
+ the Pod where this field is used. It makes that resource available
+ inside a container.
+ type: string
+ request:
+ description: |-
+ Request is the name chosen for a request in the referenced claim.
+ If empty, everything from the claim is made available, otherwise
+ only the result of this request.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: |-
+ Limits describes the maximum amount of compute resources allowed.
+ More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: |-
+ Requests describes the minimum amount of compute resources required.
+ If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
+ otherwise to an implementation-defined value. Requests cannot exceed Limits.
+ More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ type: object
+ type: object
+ retentionPolicyIntervalSeconds:
+ default: 1800
+ description: |-
+ The retentionCheckInterval defines the frequency at which the
+ system checks and enforces retention policies.
+ type: integer
type: object
+ retentionPolicy:
+ description: |-
+ RetentionPolicy is the retention policy to be used for backups
+ and WALs (i.e. '60d'). The retention policy is expressed in the form
+ of `XXu` where `XX` is a positive integer and `u` is in `[dwm]` -
+ days, weeks, months.
+ pattern: ^[1-9][0-9]*[dwm]$
+ type: string
required:
- configuration
type: object
status:
- description: ObjectStoreStatus defines the observed state of ObjectStore.
+ description: |-
+ Most recently observed status of the ObjectStore. This data may not be up to
+ date. Populated by the system. Read-only.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
+ properties:
+ serverRecoveryWindow:
+ additionalProperties:
+ description: |-
+ RecoveryWindow represents the time span between the first
+ recoverability point and the last successful backup of a PostgreSQL
+ server, defining the period during which data can be restored.
+ properties:
+ firstRecoverabilityPoint:
+ description: |-
+ The first recoverability point in a PostgreSQL server refers to
+ the earliest point in time to which the database can be
+ restored.
+ format: date-time
+ type: string
+ lastSuccussfulBackupTime:
+ description: The last successful backup time
+ format: date-time
+ type: string
+ type: object
+ description: ServerRecoveryWindow maps each server to its recovery window
+ type: object
type: object
required:
- metadata
@@ -751,10 +858,10 @@ apiVersion: v1
data:
SIDECAR_IMAGE: |
Z2hjci5pby9jbG91ZG5hdGl2ZS1wZy9wbHVnaW4tYmFybWFuLWNsb3VkLXNpZGVjYXI6dj
- AuMS4w
+ AuNS4w
kind: Secret
metadata:
- name: plugin-barman-cloud-498t9gthct
+ name: plugin-barman-cloud-gt85cmh99d
namespace: postgres-cluster
type: Opaque
---
@@ -811,8 +918,8 @@ spec:
valueFrom:
secretKeyRef:
key: SIDECAR_IMAGE
- name: plugin-barman-cloud-498t9gthct
- image: ghcr.io/cloudnative-pg/plugin-barman-cloud:v0.1.0
+ name: plugin-barman-cloud-gt85cmh99d
+ image: ghcr.io/cloudnative-pg/plugin-barman-cloud:v0.5.0
name: barman-cloud
ports:
- containerPort: 9090
@@ -823,11 +930,25 @@ spec:
tcpSocket:
port: 9090
resources: {}
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ runAsGroup: 10001
+ runAsUser: 10001
+ seccompProfile:
+ type: RuntimeDefault
volumeMounts:
- mountPath: /server
name: server
- mountPath: /client
name: client
+ securityContext:
+ runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
serviceAccountName: plugin-barman-cloud
volumes:
- name: server
diff --git a/infrastructure_talos/configs/cnpg-cluster.yaml b/infrastructure_talos/configs/cnpg-cluster.yaml
@@ -1,4 +1,28 @@
---
+apiVersion: barmancloud.cnpg.io/v1
+kind: ObjectStore
+metadata:
+ name: hetzner-base-backup
+spec:
+ retentionPolicy: "30d"
+ configuration:
+ destinationPath: s3://mtrnord-talos-pg-backup/pg-base-backup
+ endpointURL: https://hel1.your-objectstorage.com
+ s3Credentials:
+ accessKeyId:
+ name: pg-s3-credentials
+ key: ACCESS_KEY_ID
+ secretAccessKey:
+ name: pg-s3-credentials
+ key: ACCESS_SECRET_KEY
+ wal:
+ compression: gzip
+ maxParallel: 2
+ data:
+ compression: gzip
+ immediateCheckpoint: true
+ jobs: 2
+---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
@@ -64,26 +88,31 @@ spec:
wal_recycle: "on"
# #pg_hba:
# # - host all bugzilla all md5
- backup:
- target: prefer-standby
- retentionPolicy: 30d
- barmanObjectStore:
- destinationPath: s3://mtrnord-talos-pg-backup/pg-base-backup
- endpointURL: https://hel1.your-objectstorage.com
- s3Credentials:
- accessKeyId:
- name: pg-s3-credentials
- key: ACCESS_KEY_ID
- secretAccessKey:
- name: pg-s3-credentials
- key: ACCESS_SECRET_KEY
- wal:
- compression: gzip
- maxParallel: 2
- data:
- compression: gzip
- immediateCheckpoint: true
- jobs: 2
+ # backup:
+ # target: prefer-standby
+ # retentionPolicy: 30d
+ # barmanObjectStore:
+ # destinationPath: s3://mtrnord-talos-pg-backup/pg-base-backup
+ # endpointURL: https://hel1.your-objectstorage.com
+ # s3Credentials:
+ # accessKeyId:
+ # name: pg-s3-credentials
+ # key: ACCESS_KEY_ID
+ # secretAccessKey:
+ # name: pg-s3-credentials
+ # key: ACCESS_SECRET_KEY
+ # wal:
+ # compression: gzip
+ # maxParallel: 2
+ # data:
+ # compression: gzip
+ # immediateCheckpoint: true
+ # jobs: 2
+ plugins:
+ - name: barman-cloud.cloudnative-pg.io
+ isWALArchiver: true
+ parameters:
+ barmanObjectName: hetzner-base-backup
managed:
roles:
- name: freshrss
@@ -225,10 +254,12 @@ metadata:
spec:
schedule: 0 5 4 * * */3
backupOwnerReference: self
- method: barmanObjectStore
immediate: true
cluster:
name: pg-cluster-v2
+ method: plugin
+ pluginConfiguration:
+ name: barman-cloud.cloudnative-pg.io
---
apiVersion: postgresql.cnpg.io/v1
kind: Database