Lab 7.1 - StatefulSet for Database
Lab Objectives
By the end of this lab, you will be able to:
- Deploy a database (MySQL) with a StatefulSet.
- Configure persistent storage for a database.
- Understand the importance of startup order for databases.
- Configure a headless Service for discovery.
- Test database data persistence.
Estimated Duration
60-75 minutes
Prerequisites
- kubectl installed and configured.
- Functional local Kubernetes cluster (minikube or kind).
- Knowledge of StatefulSets (Chapter 7.1).
Part 1: Preparing the StorageClass
Create a StorageClass for database storage:
# storageclass-mysql.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql-storage
provisioner: k8s.io/minikube-hostpath # For minikube
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
Apply the StorageClass:
kubectl apply -f storageclass-mysql.yaml
Part 2: Creating the Secret for MySQL
Create a Secret to store the MySQL root password:
# mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
mysql-root-password: cGFzc3dvcmQxMjM= # "password123" in base64
mysql-password: cGFzc3dvcmQxMjM= # "password123" in base64
Apply the Secret:
kubectl apply -f mysql-secret.yaml
Part 3: Creating the Headless Service
A StatefulSet requires a headless Service for DNS discovery:
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None # Headless service
selector:
app: mysql
Apply the Service:
kubectl apply -f mysql-service.yaml
Part 4: Creating the MySQL StatefulSet
Create the StatefulSet for MySQL with persistent storage:
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql # Name of the headless Service
replicas: 1 # For this lab, a single MySQL instance
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: busybox:1.35
command:
- sh
- -c
- |
# Create the data directory if needed
if [ ! -d /var/lib/mysql/mysql ]; then
echo "Initializing MySQL data directory"
fi
volumeMounts:
- name: data
mountPath: /var/lib/mysql
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: mysql-root-password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
resources:
requests:
cpu: 500m
memory: 512Mi
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: mysql-storage
resources:
requests:
storage: 1Gi
Apply the StatefulSet:
kubectl apply -f mysql-statefulset.yaml
Part 5: Verifying the Deployment
Step 5.1: Verify the Pod
Wait for the Pod to be Running:
kubectl get pods -l app=mysql
Check the logs to ensure MySQL starts correctly:
kubectl logs mysql-0
Step 5.2: Verify the PVC
Check that the PVC was created:
kubectl get pvc
You should see a PVC named data-mysql-0.
Part 6: Testing the Database
Step 6.1: Create a Database and a Table
Connect to MySQL and create a test database:
kubectl exec -it mysql-0 -- mysql -uroot -ppassword123 -e "CREATE DATABASE testdb;"
kubectl exec -it mysql-0 -- mysql -uroot -ppassword123 -e "USE testdb; CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));"
kubectl exec -it mysql-0 -- mysql -uroot -ppassword123 -e "USE testdb; INSERT INTO users (name) VALUES ('Alice'), ('Bob'), ('Charlie');"
Step 6.2: Verify the Data
Check that the data was inserted:
kubectl exec -it mysql-0 -- mysql -uroot -ppassword123 -e "USE testdb; SELECT * FROM users;"
Part 7: Testing Persistence
Step 7.1: Delete the Pod
Delete the Pod to test persistence:
kubectl delete pod mysql-0
The StatefulSet will automatically recreate the Pod with the same name.
Wait for the new Pod to be Running:
kubectl get pods -l app=mysql
Wait a few seconds for MySQL to fully restart:
kubectl logs mysql-0 -f
Press Ctrl+C once MySQL is ready.
Step 7.2: Verify Data Persistence
Check that the data is still present:
kubectl exec -it mysql-0 -- mysql -uroot -ppassword123 -e "USE testdb; SELECT * FROM users;"
You should see the three users (Alice, Bob, Charlie), proving that the data persisted!
Part 8: Cleanup
Delete the created resources:
kubectl delete statefulset mysql
kubectl delete service mysql
kubectl delete secret mysql-secret
kubectl delete pvc data-mysql-0
kubectl delete -f storageclass-mysql.yaml
Lab Summary
In this lab, you deployed a MySQL database with a StatefulSet. You learned how to configure persistent storage for a database, use Secrets for passwords, and test data persistence during restarts. StatefulSets are ideal for stateful applications like databases.
Next Steps
The next lab will show you how to use DaemonSets to deploy agents on all nodes.
Lab 7.2: DaemonSet for Monitoring
Lab created: December 2024