KubeBlocks
BlogsKubeBlocks Cloud
Overview
Quickstart

Topologies

MySQL Semi-Synchronous Cluster
MySQL Cluster with ProxySQL
MySQL Group Replication Cluster
MySQL Group Replication with ProxySQL
MySQL Cluster with Orchestrator
MySQL with Orchestrator & ProxySQL

Operations

Lifecycle Management
Vertical Scaling
Horizontal Scaling
Volume Expansion
Manage MySQL Services
Minor Version Upgrade
Modify MySQL Parameters
Planned Switchover in MySQL
Decommission MySQL Replica
Recovering MySQL Replica

Backup And Restores

Create BackupRepo
Create Full Backup
Scheduled Backups
Scheduled Continuous Backup
Restore MySQL Cluster
Restore with PITR

Custom Secret

Custom Password
Custom Password Policy

TLS

MySQL Cluster with TLS
MySQL Cluster with User-Provided TLS
MySQL Cluster with mTLS

Monitoring

Observability for MySQL Clusters

Advanced Pod Management

Custom Scheduling Policies
Custom Pod Resources
Pod Management Parallelism
Using OnDelete for Controlled Pod Updates
Gradual Rolling Update
  1. Prerequisites
  2. Deploy a MySQL Semi-Synchronous Cluster
  3. Verifying the Deployment
  4. Scale-out (Add Replicas)
    1. Option 1.: Using OpsRequest
    2. Option 2.: Direct Cluster API Update
    3. Verify Scale-Out
  5. Scale-in (Remove Replicas)
    1. Verify Scale-In
  6. Summary

Horizontal Scaling for MySQL Clusters with KubeBlocks

This guide explains how to perform horizontal scaling (scale-out and scale-in) on a MySQL cluster managed by KubeBlocks. You'll learn how to use both OpsRequest and direct Cluster API updates to achieve this.

Prerequisites

Before proceeding, ensure the following:

  • Environment Setup:
    • A Kubernetes cluster is up and running.
    • The kubectl CLI tool is configured to communicate with your cluster.
    • KubeBlocks CLI and KubeBlocks Operator are installed. Follow the installation instructions here.
  • Namespace Preparation: To keep resources isolated, create a dedicated namespace for this tutorial:
kubectl create ns demo
namespace/demo created

Deploy a MySQL Semi-Synchronous Cluster

Deploy a 2-node MySQL cluster (1 primary, 1 replica) with semi-synchronous replication:

kubectl apply -f - <<EOF
apiVersion: apps.kubeblocks.io/v1
kind: Cluster
metadata:
  name: example-mysql-cluster
  namespace: demo
spec:
  clusterDef: mysql
  topology: semisync
  terminationPolicy: Delete
  componentSpecs:
    - name: mysql
      serviceVersion: 8.0.35
      replicas: 2
      resources:
        limits:
          cpu: '0.5'
          memory: 0.5Gi
        requests:
          cpu: '0.5'
          memory: 0.5Gi
      volumeClaimTemplates:
        - name: data
          spec:
            storageClassName: ""
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 20Gi
EOF

Verifying the Deployment

Monitor the cluster status until it transitions to the Running state:

kubectl get cluster example-mysql-cluster -n demo -w

Example Output:

NAME                     CLUSTER-DEFINITION   TERMINATION-POLICY   STATUS    AGE
example-mysql-cluster   mysql                Delete               Creating   8s
example-mysql-cluster   mysql                Delete               Running    87s

Once the cluster status becomes Running, your MySQL cluster is ready for use.

Scale-out (Add Replicas)

Option 1.: Using OpsRequest

Scale out the MySQL cluster by adding 1 replica:

kubectl apply -f - <<EOF
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
  name: example-mysql-cluster-scale-out-ops
  namespace: demo
spec:
  # Specifies the name of the Cluster resource that this operation is targeting.
  clusterName: example-mysql-cluster
  type: HorizontalScaling
  # Lists HorizontalScaling objects, each specifying scaling requirements for a Component, including desired total replica counts, configurations for new instances, modifications for existing instances, and instance downscaling options
  horizontalScaling:
    # Specifies the name of the Component.
  - componentName: mysql
    # Specifies the replica changes for scaling in components
    scaleOut:
      # Specifies the replica changes for the component.
      # add one more replica to current component
      replicaChanges: 1
EOF

Monitor the progress of the scaling operation:

kubectl describe ops example-mysql-cluster-scale-out-ops -n demo

Expected Result:

Status:
  Phase:            Succeed
  Progress:         1/1
  ...

Option 2.: Direct Cluster API Update

Alternatively, you can perform a direct update to the replicas field in the Cluster resource:

kubectl patch cluster example-mysql-cluster -n demo --type=json -p='[{"op": "replace", "path": "/spec/componentSpecs/0/replicas", "value": 3}]'

Verify Scale-Out

After applying the operation, you will see a new pod created and the MySQL cluster status goes from Updating to Running, and the newly created pod has a new role secondary.

kubectl get pods -n demo -l app.kubernetes.io/instance=example-mysql-cluster

Example Output (3 Pods):

NAME                           READY   STATUS    RESTARTS   AGE
example-mysql-cluster-mysql-0   4/4     Running   0          4m30s
example-mysql-cluster-mysql-1   4/4     Running   0          4m30s
example-mysql-cluster-mysql-2   4/4     Running   0          49s

New replicas automatically join as secondary nodes.

kubectl get pods -n demo -l app.kubernetes.io/instance=example-mysql-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubeblocks\.io/role}{"\n"}{end}'

Example Output:

example-mysql-cluster-mysql-0	primary
example-mysql-cluster-mysql-1	secondary
example-mysql-cluster-mysql-2	secondary

Scale-in (Remove Replicas)

Option 1: Using OpsRequest Scale in the MySQL cluster by removing 1 replica:

kubectl apply -f - <<EOF
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
  name: example-mysql-cluster-scale-in-ops
  namespace: demo
spec:
  # Specifies the name of the Cluster resource that this operation is targeting.
  clusterName: example-mysql-cluster
  type: HorizontalScaling
  # Lists HorizontalScaling objects, each specifying scaling requirements for a Component, including desired total replica counts, configurations for new instances, modifications for existing instances, and instance downscaling options
  horizontalScaling:
    # Specifies the name of the Component.
  - componentName: mysql
    # Specifies the replica changes for scaling in components
    scaleIn:
      # Specifies the replica changes for the component.
      # remove one replica from current component
      replicaChanges: 1
EOF

Monitor progress:

kubectl describe ops example-mysql-cluster-scale-in-ops -n demo

Example Output:

Status:
  Phase:            Succeed
  Progress:         1/1
  ...

Option 2: Direct Cluster API Update

Alternatively, update the replicas field in the Cluster resource:

kubectl patch cluster example-mysql-cluster -n demo --type=json -p='[{"op": "replace", "path": "/spec/componentSpecs/0/replicas", "value": 2}]'

Verify Scale-In

Example Output (2 Pods):

kubectl get pods -n demo -l app.kubernetes.io/instance=example-mysql-cluster
NAME                           READY   STATUS    RESTARTS   AGE
example-mysql-cluster-mysql-0   4/4     Running   0          10m
example-mysql-cluster-mysql-1   4/4     Running   0          10m

Summary

In this guide, you learned how to:

  • Perform scale-out operations to add replicas to a MySQL cluster.
  • Perform scale-in operations to remove replicas from a MySQL cluster.
  • Use both OpsRequest and direct Cluster API updates for horizontal scaling.

KubeBlocks ensures seamless scaling with minimal disruption to your database operations. with minimal disruption to your database operations.

© 2025 ApeCloud PTE. Ltd.