Quickstart
This guide brings up cloudnative-mysql in a development Kubernetes cluster and creates a three-instance Percona Server for MySQL cluster.
The commands assume a Kind-style local environment and the default development image names used by the repository.
Prerequisites
godockeror a compatible container toolkubectlkindmakecert-managerin the target cluster, unless you install it as part of your local e2e setup
cloudnative-mysql uses cert-manager-issued certificates for instance-manager mTLS and MySQL TLS.
Build images
Build the operator image:
make docker-build IMG=cloudnative-mysql-controller:dev
Pull the published instance image. These are built and published from the
separate containers repo:
docker pull ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4
For a local Kind cluster, load both images:
kind load docker-image cloudnative-mysql-controller:dev --name cloudnative-mysql-test-e2e
kind load docker-image ghcr.io/cloudnative-mysql/cloudnative-mysql-instance:8.4 --name cloudnative-mysql-test-e2e
Deploy the operator
Install CRDs and deploy the controller:
make install
make deploy IMG=cloudnative-mysql-controller:dev
Check the controller manager:
kubectl get pods -n cloudnative-mysql-system
Install the CLI plugin
make install-plugin
Verify:
kubectl cloudnative-mysql version
The plugin is now available as kubectl cloudnative-mysql. Most commands default to the
only cluster in the current namespace, so you can often skip the cluster name.
Create a cluster
Apply a minimal three-instance cluster:
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
Wait for readiness:
kubectl wait --for=condition=Ready cluster/cluster-sample --timeout=15m
kubectl cloudnative-mysql status cluster-sample
Expected topology:
cluster-sample-1,cluster-sample-2, andcluster-sample-3Pods exist.- One Pod has
mysql.cloudnative-mysql.io/role=primary. - The remaining ready Pods have
mysql.cloudnative-mysql.io/role=replica. status.readyInstancesis3.
Connect through services
cloudnative-mysql creates role-routed Services:
cluster-sample-rw: read-write endpoint for the current primary.cluster-sample-ro: read-only endpoint for replicas.cluster-sample-r: read endpoint for any ready instance.
Inspect them:
kubectl get svc cluster-sample-rw cluster-sample-ro cluster-sample-r
The generated application credentials are stored in the application Secret. The exact Secret name depends on the cluster plan; inspect the generated Secrets:
kubectl get secrets -l mysql.cloudnative-mysql.io/cluster=cluster-sample
For quick smoke testing, exec from a MySQL client image or a temporary debug Pod
inside the same namespace and connect to cluster-sample-rw.
Scale the cluster
Increase the instance count:
kubectl patch cluster cluster-sample --type merge -p '{"spec":{"instances":4}}'
kubectl wait --for=condition=Ready cluster/cluster-sample --timeout=15m
Scale down:
kubectl patch cluster cluster-sample --type merge -p '{"spec":{"instances":1}}'
Scale-down deletes replica Pods highest ordinal first and retains their PVCs. Delete retained PVCs only after you are sure the data is no longer needed.
Take a backup
kubectl cloudnative-mysql backup cluster-sample
This creates a Backup object with defaults (xtrabackup, prefer-standby, online).
Track it:
kubectl get backup backup-sample -w
kubectl describe backup backup-sample
Clean up
Delete the Cluster:
kubectl delete cluster cluster-sample
Deleting a Backup object does not delete S3 objects. Remove object store data
manually or through external lifecycle policies.
Next steps
- Configure object storage and backups.
- Enable continuous archiving before relying on PITR.
- Read the operations runbook before testing switchover or failover.