StatefulSets in Kubernetes with MySQL

StatefulSets in Kubernetes are ideal for managing stateful applications like MySQL. They ensure stable network identities, ordered deployment, and scaling, making them a great choice for databases that require consistent state management.


Key Features of StatefulSets

  1. Stable Network Identity: Each Pod gets a unique and consistent DNS name (e.g., mysql-0, mysql-1).

  2. Ordered Deployment and Scaling: Pods are created or deleted sequentially.

  3. Simplified Data Management: Each Pod can maintain its state independently.


Deploying MySQL with StatefulSets

Step 1: Create the MySQL Namespace

Create a namespace named mysql:


apiVersion: v1
kind: Namespace
metadata:
  name: mysql

Apply the namespace manifest:

kubectl apply -f mysql-namespace.yml

Verify the namespace :

kubectl get ns

Step 2: Create the StatefulSet

Below is a minimal StatefulSet definition for MySQL:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-statefulset
  namespace: mysql
spec:
  serviceName: "mysql-service"
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: root
        - name: MYSQL_DATABASE
          value: devops
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

Apply the StatefulSet:

kubectl apply -f mysql-statefulset.yml

Verify the StatefulSet:

kubectl get statefulset -n mysql


Step 3: Expose the MySQL Service

A Headless Service is used to allow Pods in the StatefulSet to communicate with each other.

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
      targetPort: 3306

Apply the Service:

kubectl apply -f mysql-service.yml

Verify the Service:

kubectl get svc -n mysql

Step 4:Check the MySQL Pods

First, let’s confirm that the MySQL StatefulSet has been properly deployed and the pods are running. Run the following command:

kubectl get pods -n mysql

This will display the status of the MySQL pods.

Verify Stateful Behavior:

  • Insert some data into a database.

  • Delete the Pod:

      kubectl delete pod mysql-statefulset-0 -n mysql
    
  • Verify the Pod is recreated with the same identity and retains the state.

Step 5:Access the MySQL Pod

Next, we’ll access the first MySQL pod using kubectl exec to interact with it. Use the following command to enter the pod:

kubectl exec -it mysql-statefulset-0 -n mysql -- bash

This will drop you into a bash shell inside the MySQL pod.

Step 6:Connect to MySQL

Once inside the pod, you can connect to MySQL by running:

mysql -u root -p

You’ll be prompted to enter the MySQL root password. Enter the password you’ve configured (in our case, root).

Step 7:List Databases

Now that you are inside the MySQL shell, let’s list the available databases by running the command:

show databases;

This will return a list of the databases:

🎉 Conclusion

By using StatefulSets, Kubernetes ensures that stateful applications like MySQL operate efficiently with stable network identities and ordered operations. This setup provides a robust solution for database deployments in Kubernetes clusters.