Files
Andrey KolkovandClaude Opus 4.8 dff56aa998 feat(backups): add a native MongoDB (psmdb) backup-strategy driver
Adds a MongoDB (Percona Server for MongoDB / psmdb) backup-strategy driver so
`apps.cozystack.io/MongoDB` reaches feature parity with the CNPG, MariaDB and
ClickHouse native drivers — logical backups, restore-to-differently-named
instances, and point-in-time recovery through the unified
BackupJob/RestoreJob/BackupClass/Plan interface (closes #3545).

The driver orchestrates the operator's PerconaServerMongoDBBackup /
PerconaServerMongoDBRestore CRDs:

- BackupJob: creates a one-shot PerconaServerMongoDBBackup, polls
  status.state, and persists the S3 destination + storage descriptor
  (by-reference, no credentials) onto the Cozystack Backup artifact.
- RestoreJob: drives PerconaServerMongoDBRestore via backupSource (read back
  from the source backup status, snapshot fallback) so the same artifact
  restores in-place or into a differently-named instance; PITR via
  spec.options.pitr (date/latest).

Because psmdb resolves the backup storage by name against the cluster's
spec.backup.storages, the driver names the chart's storage (s3-storage) via the
cozy-default-mongodb Strategy rather than injecting it, and surfaces a clear
Ready=False precondition when a target has backups disabled.

Wiring:
- api/backups/strategy/v1alpha1: MongoDB strategy type + generated CRD/deepcopy.
- internal/backupcontroller: psmdbstrategy_controller + psmdbtypes/mongodbapp
  partial-schema mirrors; dispatch, supported-kinds and scheme registration.
- backupstrategy-controller: cozy-default MongoDB route, cozy-default-mongodb
  Strategy CR, and psmdb.percona.com RBAC.
- apps/mongodb: backup.insecureSkipTLSVerify knob (psmdb s3 storage has no
  CA-bundle field) so backups can target Cozystack's self-signed seaweedfs.

Tests + e2e:
- unit tests for the driver (validation, ensure-idempotency, precondition,
  backupSource resolution, snapshot round-trip, PITR option parsing).
- examples/backups/mongodb + a mongodb-2-backup-roundtrip Chainsaw suite that
  drives run-all.sh end-to-end (sentinel document round-trips through S3 into a
  restored copy while the source stays untouched), per docs/agents/e2e-testing.md.
- docs/operations/backup-classes.md updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
2026-08-12 12:00:33 +04:00
..
2026-02-10 21:17:50 +01:00

Managed MongoDB Service

MongoDB is a popular document-oriented NoSQL database known for its flexibility and scalability. The Managed MongoDB Service provides a self-healing replicated cluster managed by the Percona Operator for MongoDB.

Deployment Details

This managed service is controlled by the Percona Operator for MongoDB, ensuring efficient management and seamless operation.

Deployment Modes

Replica Set Mode (default)

By default, MongoDB deploys as a replica set with the specified number of replicas. This mode is suitable for most use cases requiring high availability.

Sharded Cluster Mode

Enable sharding: true for horizontal scaling across multiple shards. Each shard is a replica set, and mongos routers handle query routing.

Notes

External Access

When external: true is enabled:

  • Replica Set mode: Traffic is load-balanced across all replica set members. This works well for read operations, but write operations require connecting to the primary. MongoDB drivers handle primary discovery automatically using the replica set connection string.
  • Sharded mode: Traffic is routed through mongos routers, which handle both reads and writes correctly.

Credentials

On first install, the credentials secret will be empty until the Percona operator initializes the cluster. Run helm upgrade after MongoDB is ready to populate the credentials secret with the actual password.

Data lifecycle

When the MongoDB release is uninstalled, the operator finalizers reclaim release-scoped resources:

Reclaimed by the percona.com/delete-psmdb-pvc finalizer:

  • All PVCs backing the replica set storage. Whether the underlying PersistentVolume and on-disk data are actually deleted depends on the StorageClass reclaimPolicy (Delete removes them, Retain leaves them for manual cleanup).
  • Operator-managed secrets:
    • <release>-percona-server-mongodb-users — operator users credentials
    • internal-<release> — internal operator state
    • internal-<release>-users — operator-internal users data
    • <release>-mongodb-encryption-key — at-rest encryption key

Reclaimed by helm uninstall:

  • <release>-credentials — connection string for application code
  • <release>-user-<username> — per-user passwords
  • <release>-s3-creds — backup destination credentials (if backups are configured)

Not reclaimed automatically:

  • TLS secrets <release>-ssl and <release>-ssl-internal (issued by cert-manager) remain in the namespace after uninstall. Delete them manually if no longer needed.

Recovery from a stuck deletion:

If the psmdb-operator is uninstalled before MongoDB CRs are deleted, the finalizers cannot run and the PerconaServerMongoDB CR hangs in Terminating. To recover, clear the finalizers manually:

kubectl --namespace <namespace> patch psmdb <release> --type merge --patch '{"metadata":{"finalizers":[]}}'

Note that this skips the operator-driven cleanup — PVCs and operator-managed secrets will remain orphaned and must be removed manually.

If you need to retain data, take a backup before deletion. Refer to the Percona Operator for MongoDB documentation for backup/restore workflows.

Upgrading from earlier versions

Earlier versions of this chart referenced a namespace-shared system users secret (percona-server-mongodb-users). Upgrading to a release that scopes this secret per CR (<release>-percona-server-mongodb-users) triggers a password rotation for the operator-managed system users. The rotation is performed in place by the Percona operator via db.changeUserPassword() against the running mongod (operator log: Secret data changed. Updating users...); pods are not restarted and the cluster stays available.

Rotated automatically on upgrade:

  • The five operator-managed system accounts: databaseAdmin, userAdmin, backup, clusterAdmin, clusterMonitor.
  • Secret <release>-percona-server-mongodb-users (newly created, per-CR) and internal-<release>-users receive the new values.
  • Secret <release>-credentials is regenerated; its password and uri keys reflect the new databaseAdmin password.

Not affected:

  • Custom users defined under users: in chart values. Their <release>-user-<name> secrets are not touched.
  • The at-rest encryption key (<release>-mongodb-encryption-key) and replica set keyfile (<release>-mongodb-keyfile) are unchanged, so on-disk data remains readable.

Action required after upgrade:

Workloads that mount <release>-credentials keep using the cached old password until they re-read the secret. Restart those pods, or run a controller such as Reloader to roll them automatically. Without this, application connections fail with authentication errors once their existing sessions expire.

Orphaned legacy secret:

The previous namespace-shared secret percona-server-mongodb-users is no longer referenced by any MongoDB CR after upgrade, but the operator does not garbage-collect it. If multiple MongoDB releases in the same namespace previously shared it, all of them rotate to their own per-CR secrets — passwords are no longer shared across CRs in the namespace, which is the intended outcome. Confirm no other consumers reference it, then remove it manually:

kubectl --namespace <namespace> delete secret percona-server-mongodb-users

storageClass is annotated as immutable in the chart schema — see docs/storage-immutability.md for the contract and which consumers enforce it.

Parameters

Common parameters

Name Description Type Value
replicas Number of MongoDB replicas in replica set. int 3
resources Explicit CPU and memory configuration for each MongoDB replica. When omitted, the preset defined in resourcesPreset is applied. object {}
resources.cpu CPU available to each replica. quantity ""
resources.memory Memory (RAM) available to each replica. quantity ""
resourcesPreset Default sizing preset used when resources is omitted. string t1.small
size Persistent Volume Claim size available for application data. quantity 10Gi
storageClass StorageClass used to store the data. string ""
external Enable external access from outside the cluster. bool false
version MongoDB major version to deploy. string v8

Sharding configuration

Name Description Type Value
sharding Enable sharded cluster mode. When disabled, deploys a replica set. bool false
shardingConfig Configuration for sharded cluster mode. object {}
shardingConfig.configServers Number of config server replicas. int 3
shardingConfig.configServerSize PVC size for config servers. quantity 3Gi
shardingConfig.mongos Number of mongos router replicas. int 2
shardingConfig.shards List of shard configurations. []object [...]
shardingConfig.shards[i].name Shard name. string ""
shardingConfig.shards[i].replicas Number of replicas in this shard. int 0
shardingConfig.shards[i].size PVC size for this shard. quantity ""

Users configuration

Name Description Type Value
users Users configuration map. map[string]object {}
users[name].password Password for the user (auto-generated if omitted). string ""

Databases configuration

Name Description Type Value
databases Databases configuration map. map[string]object {}
databases[name].roles Roles assigned to users. object {}
databases[name].roles.admin List of users with admin privileges (readWrite + dbAdmin). []string []
databases[name].roles.readonly List of users with read-only privileges. []string []

Backup parameters

Name Description Type Value
backup Backup configuration. object {}
backup.enabled Enable regular backups. bool false
backup.schedule Cron schedule for automated backups. string 0 2 * * *
backup.retentionPolicy Retention policy (e.g. "30d"). string 30d
backup.destinationPath Destination path for backups (e.g. s3://bucket/path/). string s3://bucket/path/to/folder/
backup.endpointURL S3 endpoint URL for uploads. string http://minio-gateway-service:9000
backup.insecureSkipTLSVerify Skip TLS verification for the S3 endpoint (self-signed, e.g. in-cluster seaweedfs). bool false
backup.s3AccessKey Access key for S3 authentication. string ""
backup.s3SecretKey Secret key for S3 authentication. string ""

Bootstrap (recovery) parameters

Name Description Type Value
bootstrap Bootstrap configuration. object {}
bootstrap.enabled Whether to restore from a backup. bool false
bootstrap.recoveryTime Timestamp for point-in-time recovery; empty means latest. string ""
bootstrap.backupName Name of backup to restore from. string ""