This guide will walk you through the necessary steps to deploy MySQL on Kubernetes with built-in cross-region or multicloud business continuity.

That means, that at the event of a failure of your cluster, or the entire cloud region where it is deployed, you’ll be able to start your database, with all of its latest data intact, on another cluster at a different location in just a few seconds.

Before You Begin

Before you begin, it might be useful to familiarize yourself with Statehub concepts such as Clusters, States, Volumes and the the Default State.

Prerequisites

The following is necessary to use Statehub with your Kubernetes clusters:

  1. A Statehub account. Sign up here
  2. A UNIX-compatible command line interface (Linux or Mac terminal, WSL or CygWin for Windows)
  3. The kubectl command line utility to control your clusters
  4. The helm command line utility to deploy Helm charts on your clusters

Initial Setup
This guide assumes you have two Kubernetes clusters in two distinct cloud locations, similar to the diagram below:

Step 1: Set Up the Statehub CLI

Go to https://get.statehub.io to download and install the Statehub CLI.

Setting up your Kubernetes clusters to use Statehub requires the use of the Statehub CLI. After installation is complete, a link will be displayed to log you in to your Statehub account. Copy the link to your browser and go to the Statehub login page.

If you don’t already have a Statehub account, you can create one by clicking a link on the Statehub login page.

Once you’ve logged in to your Statehub account, you sould be automatically redirected tokens page, and prompted to create a token for your CLI. Click “Yes” to create a token. Copy the token that’s been created to the CLI prompt and press Enter.

Your Statehub CLI installation should now be configured for your Statehub account.

Step 2: Register Your Clusters with Statehub

Register the clusters using the Statehub CLI.

The following command will register the cluster associated with your current context:

kubectl config use-context my-cluster
statehub register-cluster

To register another cluster, switch to its context, and then run register it:

kubectl config use-context another-cluster
statehub register-cluster

ℹ️ Note:
In certain scenarios, you might not have a second cluster in place at another location, but still want your data to be replicated to another location, and create a cluster on-demand in the event of your primary location’s failure. In this case, follow the procedure to add a location to a state. This will allow you to add another replication location for your application’s state without having a cluster deployed there in advance.

What We’ve Done

In order to use Statehub with your Kubernetes clusters, you must use register them using the Statehub CLI. The Statehub CLI makes use of your Kubernetes configuration contexts to identify your clusters, and is aware of the current context.

To register another cluster, either switch to the appropriate context and run the aforementioned command. You need to register all the clusters you between which you want to be able to move your stateful applications.

This operation will:

  1. Make Statehub aware of your clusters
  2. Identify your clusters’ location(s) and report them to Statehub
  3. Generate a cluster token for your cluster and save it in your cluster’s secrets, so that your cluster can access the Statehub REST API.
  4. Install the Statehub Controller components and the Statehub CSI driver on your cluster
  5. Add the cluster’s location(s) to the default state, if default state doesn’t span this location yet
  6. Configure the default state’s corresponding storage class (default.YourStatehubOrgId.statehub.io) as the default storage class.

Once you’ve registered all of your clusters, you should be able to start stateful applications and fail them over between your clusters.

At this point, your topology will look like this:

Step 3: Deploy MySQL

Apply a configuration containing persistent volumes to your Kubernetes cluster.

The stateful application manifest usually contains a stateful set with a volume claim template or a different configuration describing a persistent volume claim. Any configuration with persistent volume claims would work, and a simple MySQL example would be:

---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
  selector:
    application: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      application: mysql
      app: statehub-demo
  serviceName: mysql
  replicas: 1
  template:
    metadata:
      labels:
        application: mysql
        app: statehub-demo
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: dbdata
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: dbdata
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "default.YourStatehubOrgId.statehub.io"
      resources:
        requests:
          storage: 10Gi

ℹ️ Note:
The storageClassName is set to the storage class corresponding with the default state (replace YourStatehubOrgId with your Statehub organization ID). If you’ve registered the cluster with default parameters, you can omit the storage class name since your default state storage class should have been set the default for this cluster.

  1. Choose the cluster on which you want your application on and switch to its context
    kubectl config use-context my-cluster
    
  2. Make sure this cluster is the owner of the default state by running
    statehub set-owner default my-cluster
    
  3. Apply your MySQL configuration
    kubectl apply -f mysql.yaml
    

What We’ve Done

As soon as Kubernetes tries to create a PVC with a Statehub-created storage class (i.e., *.YourStatehubId.statehub.io), Statehub will create a volume on the state corresponding to the storage class, replicated between all of the locations the state spans.

Since the owner of the state is the our primary cluster, only it is allowed to access the volumes, and create new volumes on the state.

After starting your application, your setup will resemble this:

Step 4: Failing Over Between Clusters in Different Locations

When you need to fail over your application to another cluster, set the other cluster as the owner of the state and apply the configuration to it.

Optionally, in case of a planned failover, remove the application on the cluster you’re moving away from. Don’t worry, this will not affect the data:

kubectl delete -f mysql.yaml

To start your application on the other cluster,

  1. Choose the cluster on which you want your application on and switch to its context
    kubectl config use-context another-cluster
    
  2. Make sure this cluster is the owner of the default state by running
    statehub set-owner default another-cluster
    
  3. Apply your stateful application configuration
    kubectl apply -f mysql.yaml
    

After your MySQL database has failed over to another location, you can start your other applications (microservices, etc.) on the other cluster.

Conclusion

Anything can happen in the cloud. It wasn’t built around your business and your needs, and failures can occur quite often. The best way to be protected from downtime, and ensure business continuity is not to depend on one location to run your applications.

Statehub gives you the ability to quickly and affordably set up an environment that will provide business continuity on the public cloud at a level of protection and experience only seen before in expensive on-prem deployments.