MOCO is designed to have the following properties.
- Compatibility with the standard MySQL
- This is the reason that MOCO does not adopt group replication that has a number of limitations.
- MOCO only allows writes to a single instance called the primary at a time.
- MOCO configures loss-less semi-synchronous replication with sufficient replicas.
- MOCO detects and excludes instances having errant transactions.
- MOCO can quickly switch the primary in case of the primary failure or restart.
- MOCO allows up to 5 instances in a cluster.
Blog article: Introducing MOCO, a modern MySQL operator on Kubernetes
- MySQL: 8.0.18, 8.0.25, 8.0.26, 8.0.27, 8.0.28, 8.0.30, 8.0.31, 8.0.32, 8.0.33, 8.0.34
- Kubernetes: 1.25, 1.26, 1.27
Other MySQL 8 releases would probably work. They are simply not tested in our CI.
- Cluster with odd number of MySQL instances
- Replication from an external MySQL instance
- Manual and automatic switchover of the primary instance
- Automatic failover of the primary instance
- Backup and Point-in-Time Recovery
- Errant transaction detection
- Different MySQL versions for each cluster
- Upgrading MySQL version of a cluster
- Monitor for replication delays
- Built-in mysqld_exporter for
- Services for the primary and replicas, respectively
- Custom Pod, Service, and PersistentVolumeClaim templates
- Redirect slow query logs to a sidecar container
- Auto-generate PodDisruptionBudget
You can quickly run MOCO using kind.
- Prepare a Linux machine and install Docker.
- Checkout MOCO and go to
You can then create a three-instance MySQL cluster as follows:
$ cat > mycluster.yaml <<'EOF' apiVersion: moco.cybozu.com/v1beta1 kind: MySQLCluster metadata: namespace: default name: test spec: replicas: 3 podTemplate: spec: containers: - name: mysqld image: ghcr.io/cybozu-go/moco/mysql:8.0.34 volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi EOF $ export KUBECONFIG=$(pwd)/.kubeconfig $ ../bin/kubectl apply -f mycluster.yaml
Check the status of MySQLCluster until it becomes healthy as follows:
$ ../bin/kubectl get mysqlcluster test NAME AVAILABLE HEALTHY PRIMARY SYNCED REPLICAS ERRANT REPLICAS test True True 0 3
Once it becomes healthy, you can use
kubectl-moco to play with
$ ../bin/kubectl moco mysql -it test
To destroy the Kubernetes cluster, run:
$ make stop
examples directory contains example MySQLCluster manifests.
Docker images are available on ghcr.io/cybozu-go/moco.