Skip to main content

API reference

This page is a practical field guide for the cloudnative-mysql CRDs that are used to run clusters, choose images, and manage backups.

The API group is:

mysql.cloudnative-mysql.io/v1alpha1

The API is still v1alpha1, so fields can change while the operator is under active development.

Cluster

Cluster is the main namespaced resource. It describes a Percona Server for MySQL topology, bootstrap method, storage, image, backup configuration, and operational policy.

Short names:

mysql
mysqlcluster

Minimal example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: Cluster
metadata:
name: cluster-sample
spec:
instances: 3
imageName: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4
storage:
size: 10Gi
mysql:
binlogFormat: ROW
bootstrap:
initdb:
database: app
owner: app

Top-level spec fields

FieldTypePurpose
descriptionstringHuman-readable description.
inheritedMetadataobjectLabels/annotations inherited by related objects.
imageNamestringDirect instance image reference. Mutually exclusive with imageCatalogRef.
imageCatalogRefobjectResolve an image from ImageCatalog or ClusterImageCatalog.
imagePullPolicyAlways, Never, IfNotPresentPull policy for instance images.
imagePullSecretsarrayPull Secrets for private registries.
instancesintegerNumber of MySQL instances. Minimum 1, default 1.
minSyncReplicasintegerMinimum semi-sync acknowledgers.
maxSyncReplicasintegerMaximum semi-sync acknowledgers; must be lower than instances.
mysqlobjectMySQL configuration.
storageobjectRequired data PVC configuration.
binlogStorageobjectOptional separate PVC configuration for binlogs.
bootstrapobjectFresh init or recovery bootstrap.
rootPasswordSecretlocal object refRoot password Secret. Generated when omitted.
enableSuperuserAccessboolWhether root access is exposed through the Secret. Default false.
certificatesobjectTLS/mTLS Secret configuration.
resourcesKubernetes ResourceRequirementsCPU/memory requests and limits for instance containers.
affinityobjectScheduling affinity, anti-affinity, node selectors, and tolerations.
topologySpreadConstraintsarrayKubernetes topology spread constraints.
priorityClassNamestringPod priority class.
schedulerNamestringScheduler name for instance Pods.
primaryUpdateStrategyunsupervised, supervisedStrategy for primary updates. Default unsupervised.
primaryUpdateMethodswitchover, restartMethod for primary update. Default switchover.
maxStartDelayinteger secondsStartup bound. Default 3600.
maxStopDelayinteger secondsShutdown bound. Default 1800.
smartShutdownTimeoutinteger secondsGraceful shutdown window before fast fallback. Default 180.
maxSwitchoverDelayinteger secondsSwitchover bound. Default 3600.
failoverDelayinteger secondsDelay before automatic failover. Default 0.
backupobjectObject-store, backup, retention, and archiving configuration.
replicaobjectReplica-cluster mode from an external source. Designed for later milestones.
externalClustersarrayExternal sources for replication or recovery.
managedobjectOperator-managed services and future managed resources.
monitoringobjectPodMonitor and custom query references.
nodeMaintenanceWindowobjectNode-maintenance behavior.
enablePDBboolCreate a PodDisruptionBudget. Default true.
serviceAccountTemplateobjectMetadata for generated ServiceAccount.
envarrayExtra environment variables on instance containers.
envFromarrayExtra environment sources on instance containers.
podSecurityContextKubernetes PodSecurityContextPod security context.
securityContextKubernetes SecurityContextContainer security context.
logLevelerror, warning, info, debug, tracePer-cluster operator log level. Default info.

Monitoring

spec:
monitoring:
enablePodMonitor: true
disableDefaultQueries: false
metricsQueriesTTL: 30s
tls:
enabled: false

Instances expose Prometheus metrics on the named container port metrics (9187) at /metrics. The endpoint is plain HTTP unless monitoring TLS is enabled.

FieldTypePurpose
enablePodMonitorboolCreate an owned Prometheus Operator PodMonitor. Default false.
customQueriesConfigMaparrayConfigMap keys that hold custom monitoring query definitions.
customQueriesSecretarraySecret keys that hold custom monitoring query definitions.
disableDefaultQueriesbool pointerDisable the built-in default query set once default query loading is enabled.
metricsQueriesTTLKubernetes DurationMinimum interval between custom/default query executions.
tls.enabledboolServe the metrics endpoint over TLS. Default false.

Image selection

Use either imageName or imageCatalogRef.

spec:
imageName: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4
spec:
imageCatalogRef:
apiGroup: mysql.cloudnative-mysql.io
kind: ImageCatalog
name: percona-images
major: 8

MySQL configuration

spec:
mysql:
parameters:
require_secure_transport: "ON"
max_connections: "500"
binlogFormat: ROW
semiSync:
enabled: true
timeoutMillis: 1000
dataDurability: preferred
additionalConfigFiles:
custom.cnf: |
[mysqld]
sort_buffer_size=4M
FieldTypePurpose
parametersmap string/stringMySQL settings rendered under [mysqld]. Denied keys block the cluster (see below).
binlogFormatROW, STATEMENT, MIXEDBinary-log format. Default ROW; required for safe replication and PITR.
semiSync.enabledboolEnable semi-synchronous replication.
semiSync.timeoutMillisintegerWait timeout before falling back to async behavior.
semiSync.dataDurabilitypreferred, requiredHow strictly minSyncReplicas is enforced when replicas are unhealthy. preferred (default) self-heals the acknowledgement count down to keep the primary writable; required keeps it fixed so writes block.
additionalConfigFilesmap string/stringExtra config files rendered into the MySQL config directory.

Denied and deprecated parameters

spec.mysql.parameters is validated before any instance is provisioned. Keys are compared case-insensitively with dashes and underscores treated as equivalent (log-binlog_bin).

  • Denied keys set the cluster phase: Blocked with a reason naming the offending key(s). These are either keys the operator manages directly (replication identity and topology, TLS material, binlog durability) or keys that would relocate on-disk paths or expose the administrative interface, for example server_id, gtid_mode, read_only, log_bin, ssl_cert, sync_binlog, datadir, socket, tmpdir, plugin_dir, secure_file_priv, log_error, admin_address, admin_ssl_cert, tls_ciphersuites, skip_replica_start, auto_generate_certs. require_secure_transport is not denied; requiring TLS for client connections is the user's choice.
  • Deprecated keys are accepted but emit a DeprecatedParameter warning event pointing at the current spelling, for example slave_parallel_workers (→ replica_parallel_workers), master_info_repository (removed on 8.0.23+).

Storage

spec:
storage:
storageClass: fast
size: 100Gi
resizeInUseVolumes: true

storage and binlogStorage use the same shape:

FieldTypePurpose
storageClassstringStorageClass for generated PVCs.
sizestringRequested storage size.
resizeInUseVolumesboolAllow PVC growth. Default true.
pvcTemplateKubernetes PersistentVolumeClaimSpecFull PVC template override.

Bootstrap

Fresh initialization:

spec:
bootstrap:
initdb:
database: app
owner: app
secret:
name: app-credentials
postInitSQL:
- CREATE TABLE app.ready (id int primary key)
characterSet: utf8mb4
collation: utf8mb4_0900_ai_ci

Recovery from a Backup:

spec:
bootstrap:
recovery:
backup:
name: backup-sample

Point-in-time recovery:

spec:
bootstrap:
recovery:
backup:
name: backup-sample
recoveryTarget:
targetGTID: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-500"

Raw object-store recovery (no Backup CR) points bootstrap.recovery.source at an externalClusters entry. The entry carries its own objectStore and its name is the S3 key prefix backups were stored under:

spec:
bootstrap:
recovery:
source: prod-cluster
backupID: "" # empty = latest completed; set to pin a backup
recoveryTarget: # optional, identical to the Backup path
targetGTID: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-500"
externalClusters:
- name: prod-cluster
objectStore:
bucket: cloudnative-mysql-backups
path: production
endpoint: http://minio.minio.svc:9000
credentials:
accessKeyId:
name: minio-creds
key: accessKey
secretAccessKey:
name: minio-creds
key: secretKey

recovery.backup and recovery.source are mutually exclusive. backupID is only meaningful with source; when empty the operator selects the latest completed backup discovered under the source prefix. See Restore from raw object store.

recoveryTarget accepts exactly one of:

FieldPurpose
targetTimeRFC3339 timestamp target.
targetGTIDInclusive MySQL GTID set target.
targetImmediateStop as soon as the base backup is consistent.

An empty recoveryTarget: {} means replay to the latest archived point. No recoveryTarget means restore the physical base backup only.

Backup and archiving configuration

spec:
backup:
objectStore:
bucket: cloudnative-mysql-backups
path: production
endpoint: http://minio.minio.svc:9000
credentials:
accessKeyId:
name: minio-creds
key: accessKey
secretAccessKey:
name: minio-creds
key: secretKey
retentionPolicy: 30d
target: prefer-standby
continuousArchiving:
enabled: true
targetRPOSeconds: 300
maxBinlogSizeMB: 16
binlogExpireSeconds: 604800
FieldTypePurpose
objectStoreS3ObjectStoreDestination for backups and binlog archives.
retentionPolicystringDuration such as 30d, 8w, 12m. Retention GC is future work.
targetprimary, prefer-standbyDefault source selection for backups.
xtrabackupOptionsarray stringExtra XtraBackup flags.
continuousArchiving.enabledboolEnable primary-gated binlog archiving.
continuousArchiving.targetRPOSecondsintegerTime-based binlog rotation/RPO bound. Default 300.
continuousArchiving.maxBinlogSizeMBintegerSize-based binlog rotation bound. Default 16.
continuousArchiving.binlogExpireSecondsintegerExpiry backstop under the purge guard. Default 604800.

Managed services

spec:
managed:
services:
disabledDefaultServices:
- ro
template:
metadata:
labels:
app.kubernetes.io/part-of: my-app
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internal
spec:
type: LoadBalancer
additional:
- name: mysql-lb
selectorType: rw
serviceTemplate:
spec:
type: LoadBalancer
- name: mysql-internal-read
selectorType: ro
updateStrategy: replace
serviceTemplate:
metadata:
labels:
pool: reporting
spec:
type: ClusterIP
FieldTypeDescription
disabledDefaultServicesarrayDefault services to disable. Accepts ro and r; the rw service cannot be disabled.
templateobjectService template merged onto each default rw/ro/r service.
additionalarrayUser-defined extra services routed to a role.
additional[].namestringRendered as <cluster>-<name>; unique and not colliding with default names.
additional[].selectorTypeenumrw, ro, or r.
additional[].updateStrategyenumpatch (default, merge) or replace (swap defaults).
additional[].serviceTemplateobjectSame shape as template.

The service template's spec exposes type, externalTrafficPolicy, sessionAffinity, loadBalancerSourceRanges, externalName, and healthCheckNodePort. The selector, ports, and clusterIP are operator-managed.

Managed roles

spec.managed.roles declares MySQL users (roles) the operator reconciles on the primary. The operator lists the live users, diffs them against the spec, and issues the minimal CREATE USER / ALTER USER / DROP USER needed. Passwords are read from a referenced Secret; when passwordSecret is omitted the operator generates a password and stores it in a Secret named <cluster>-<roleName> (key password).

spec:
managed:
roles:
- name: app
host: "%"
ensure: present
passwordSecret:
name: app-credentials
key: password
requireTLS: x509
maxUserConnections: 50
privileges:
- privileges: [SELECT, INSERT, UPDATE, DELETE]
"on": app.*
- name: readonly
ensure: present # operator-generated password
privileges:
- privileges: [SELECT]
"on": app.*
- name: legacy
ensure: absent # dropped if present
FieldTypeDescription
namestringMySQL user name (max 32 chars). Reserved names (root, mysql.*, cloudnative-mysql_*) are rejected.
hoststringMySQL host part. Defaults to %.
ensureenumpresent (default) or absent.
passwordSecretobject{name, key} selecting the password. Omit for an operator-generated password.
superuserboolGrants ALL PRIVILEGES ON *.* WITH GRANT OPTION. Mutually exclusive with privileges.
maxUserConnectionsint32Per-account simultaneous-connection limit. 0 = no limit.
maxQueriesPerHourint32Hourly query limit. 0 = no limit.
maxUpdatesPerHourint32Hourly update limit. 0 = no limit.
maxConnectionsPerHourint32Hourly connection limit. 0 = no limit.
requireTLSenumnone (default), ssl, or x509.
privilegesarrayGrants: {privileges: [...], on: "db.*"}. on defaults to *.*.

Quote the on key ("on": app.*). Unquoted, YAML parses on as the boolean true, and the API server rejects the manifest with a strict-decoding error.

Users present in MySQL but not declared in spec.managed.roles are left untouched. To remove one, declare it with ensure: absent. Reconciliation runs after the cluster reaches Ready; outcomes appear in status.managedRolesStatus.

External clusters

externalClusters defines named external sources for future replica or raw object-store recovery flows:

spec:
externalClusters:
- name: source-cluster
connectionParameters:
host: mysql.example.com
port: "3306"
password:
name: source-creds
key: password
objectStore:
bucket: source-backups
path: production
credentials:
inheritFromIAMRole: true

Live external replica mode and raw S3 recovery are planned milestones; verify current implementation status before relying on these fields.

Cluster status

FieldPurpose
instancesTotal observed instances.
readyInstancesReady instances.
instanceNamesInstance Pod names.
currentPrimaryCurrent primary instance.
targetPrimaryDesired primary during bootstrap, switchover, or failover.
currentPrimaryTimestampWhen the current primary was elected.
targetPrimaryTimestampWhen the current primary-change request started.
divergedInstancesInstances excluded because of errant GTIDs.
primaryFailingSinceWhen the current primary first became unhealthy.
latestGeneratedNodeLatest generated instance ordinal.
phase / phaseReasonHuman-readable reconciliation state.
imageResolved image in use.
gtidExecutedByInstanceLast observed GTID set by instance.
certificatesResolved certificate Secret names and managed certificate expirations.
continuousArchivingBinlog archive health and frontier.
lastRetentionRunTimeLast retention GC pass time.
managedRolesStatusPer-role reconciliation state: byStatus, cannotReconcile, and applied passwordStatus.
observedGenerationLast reconciled generation.
conditionsKubernetes conditions such as Ready, Progressing, Degraded.

Database

Database is a namespaced CRD (short name mydatabase) that declares a MySQL schema and the accounts scoped to it. It references a Cluster in the same namespace, which makes it the unit you delegate to tenant teams; see Multi-Tenancy. The controller diffs the spec against the live server and issues the minimal SQL to converge; nothing is dropped unless you ask for it.

Example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: Database
metadata:
name: tenant-a
namespace: shared # must match the Cluster's namespace
spec:
cluster:
name: shared
name: tenant_a # the MySQL schema; defaults to the resource name
ensure: present
characterSet: utf8mb4
collation: utf8mb4_0900_ai_ci
reclaimPolicy: retain
users:
- name: tenant_a_app
host: "%"
ensure: present
passwordSecret:
name: tenant-a-db
key: password
grants:
- privileges: [SELECT, INSERT, UPDATE, DELETE]
# `on` defaults to the managed schema (tenant_a.*)

Spec fields

FieldTypeDescription
clusterobject{name} of the target Cluster in the same namespace. Required.
namestringMySQL schema name. Defaults to the resource name.
ensureenumpresent (default) creates the schema; absent drops it.
characterSetstringSchema character set (e.g. utf8mb4).
collationstringSchema collation (e.g. utf8mb4_0900_ai_ci).
reclaimPolicyenumretain (default) keeps the schema on object deletion; delete drops it (finalizer-guarded).
usersarrayAccounts managed for this schema (see below).

users[]

FieldTypeDescription
namestringMySQL user name. Required.
hoststringHost part. Defaults to %.
ensureenumpresent (default) or absent.
passwordSecretobject{name, key} selecting the password Secret in the same namespace.
grantsarrayGrants: {privileges: [...], on: "db.*"}. on defaults to the managed schema.

Database status

FieldPurpose
appliedtrue once MySQL matches the spec.
messageDetail, typically an error.
observedGenerationLast reconciled generation.
passwordStatusPer user (name@host), the source Secret resourceVersion last applied; drives password re-application only on change.
conditionsLatest observations of the database state.

Backup

Backup is a namespaced one-shot physical backup request.

Short name:

mybackup

Example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: Backup
metadata:
name: backup-sample
spec:
cluster:
name: cluster-sample
method: xtrabackup
target: prefer-standby
online: true

Spec fields

FieldTypePurpose
cluster.namestringRequired Cluster to back up.
objectStoreS3ObjectStoreOptional destination override. Uses the Cluster object store when omitted.
methodxtrabackup, volumeSnapshotBackup method. Default xtrabackup; only XtraBackup is implemented today.
targetprimary, prefer-standbySource instance selection. Default prefer-standby.
onlineboolHot backup flag. Default true.

Status fields

FieldPurpose
phasepending, running, completed, or failed.
instanceNameInstance selected as backup source.
methodMethod used by the controller.
backupIdStable ID used in object-store keys.
jobNameBackup worker Job.
destinationPathFull archive URI.
sha256SHA256 checksum of backup.xbstream.
beginGTID / endGTIDGTID metadata.
beginBinlog / endBinlogBinlog coordinate metadata.
startedAt / stoppedAtBackup timing.
errorFailure message.
conditionsReady, Progressing, and Degraded observations.

Deleting a Backup object does not delete remote object-store data.

ScheduledBackup

ScheduledBackup is a namespaced cron scheduler that creates Backup objects.

Short name:

myscheduledbackup

Example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: ScheduledBackup
metadata:
name: cluster-sample-daily
spec:
schedule: "0 0 2 * * *"
cluster:
name: cluster-sample
immediate: true
backupOwnerReference: self
method: xtrabackup
target: prefer-standby
online: true

Spec fields

FieldTypePurpose
schedulesix-field cronRequired schedule including seconds.
cluster.namestringRequired Cluster to back up.
suspendboolPause schedule. Default false.
immediateboolCreate one Backup at creation time. Default false.
backupOwnerReferencenone, self, clusterOwner reference mode for generated Backups. Default self.
methodxtrabackup, volumeSnapshotMethod propagated to generated Backups. Default xtrabackup.
targetprimary, prefer-standbySource selection propagated to generated Backups. Default prefer-standby.
onlineboolHot backup flag propagated to generated Backups. Default true.

schedule uses:

second minute hour day-of-month month day-of-week

Status fields

FieldPurpose
lastCheckTimeLast schedule evaluation time.
lastScheduleTimeLast scheduled time that created or adopted a Backup.
nextScheduleTimeNext expected schedule time.

Generated Backups are labelled with:

mysql.cloudnative-mysql.io/scheduled-backup=<scheduledbackup-name>

Immediate Backups also carry:

mysql.cloudnative-mysql.io/immediate-backup=true

ImageCatalog

ImageCatalog is a namespaced mapping from MySQL major version to cloudnative-mysql instance image.

Short name:

myimagecatalog

Example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: ImageCatalog
metadata:
name: percona-images
spec:
images:
- major: 8
image: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4
- major: 9
image: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:9.x

Fields

FieldTypePurpose
spec.imagesarrayRequired image mappings. Minimum one, maximum eight.
spec.images[].majorintegerMajor key used by Cluster.spec.imageCatalogRef.major.
spec.images[].imagestringFully qualified instance image reference.

Each major value can appear at most once.

ClusterImageCatalog

ClusterImageCatalog has the same spec.images shape as ImageCatalog, but it is cluster-scoped and can be reused across namespaces.

Short name:

myclusterimagecatalog

Example

apiVersion: mysql.cloudnative-mysql.io/v1alpha1
kind: ClusterImageCatalog
metadata:
name: global-percona-images
spec:
images:
- major: 8
image: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4
- major: 9
image: ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:9.x

Reference it from a Cluster:

spec:
imageCatalogRef:
apiGroup: mysql.cloudnative-mysql.io
kind: ClusterImageCatalog
name: global-percona-images
major: 8

Shared object-store fields

S3ObjectStore appears in Cluster.spec.backup.objectStore, Backup.spec.objectStore, and Cluster.spec.externalClusters[].objectStore.

FieldTypePurpose
endpointstringCustom S3-compatible endpoint. Empty targets AWS S3.
regionstringBucket/signing region.
bucketstringRequired bucket name.
pathstringKey prefix.
forcePathStyleboolPath-style addressing. Default true.
signatureVersions3v4, s3v2Signing scheme. Default s3v4.
serverSideEncryptionstringSSE algorithm, such as AES256 or aws:kms.
storageClassstringObject-store storage class.
credentials.accessKeyIdsecret key selectorAccess key ID.
credentials.secretAccessKeysecret key selectorSecret access key.
credentials.sessionTokensecret key selectorOptional session token.
credentials.inheritFromIAMRoleboolUse workload/IAM credentials instead of static Secrets.
tls.insecureSkipVerifyboolDisable endpoint certificate verification. Testing only.
tls.caBundleSecretsecret key selectorCA bundle for private object-store CAs.

Shared condition types

cloudnative-mysql resources use Kubernetes metav1.Condition entries. Common condition types are:

ConditionMeaning
ReadyResource is fully functional.
ProgressingResource is being created, updated, backed up, restored, or changed.
DegradedResource failed to reach or maintain the desired state.