75.8 Project 38: StatefulSet MySQL with persistent volumes
Friends, databases need stable names and disks. Today we create a headless Service, a MySQL StatefulSet with volumeClaimTemplates, write a row, delete the Pod, and prove the data returns.
मित्रांनो, databases ला stable names आणि disks लागतात. आज headless Service, MySQL StatefulSet, row लिहा, Pod delete, data परत.
दोस्तों, databases को stable names और disks चाहिए. आज headless Service, MySQL StatefulSet, row लिखें, Pod delete, data वापस.
What you will build in this project
- Headless Service mysql.
- StatefulSet mysql-0 with PVC.
- Insert a row into shop.items.
- Delete Pod and prove data persists.
1. Start from a real company story
At Zoho in Chennai, a MySQL Deployment used an emptyDir. A node drain wiped the database before the demo.
Sales lost a week. Rough cost: about ₹18 lakh in delayed contracts.
Imran moved MySQL to a StatefulSet with PVCs and a headless Service for stable DNS.
Today we build that StatefulSet lab on kind.
Ravindra Bagale's Tip
Many students run MySQL as a plain Deployment with emptyDir. One restart and data is gone. Use StatefulSet plus PVC. Keep that habit.
खूप students MySQL Deployment + emptyDir ने चालवतात. Restart आणि data गेले. StatefulSet + PVC. सवय ठेवा.
बहुत students MySQL Deployment + emptyDir चलाते हैं. Restart और data गया. StatefulSet + PVC. आदत रखिए.
2. Start and prepare
Step 1: Why StatefulSet
Why: Stable identity. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: why. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: a1
Type this:
echo 'StatefulSet gives stable network identity and ordered Pods for databases'
You will see:
StatefulSet gives stable network identity and ordered Pods for databases
What it means: Why StatefulSet for MySQL.
Example 2: a2
Type this:
echo 'volumeClaimTemplates create a PVC per Pod automatically'
You will see:
volumeClaimTemplates create a PVC per Pod automatically
What it means: PVC per Pod.
Example 3: a3
Type this:
echo 'Headless Service (clusterIP None) lets Pods resolve mysql-0.mysql'
You will see:
Headless Service (clusterIP None) lets Pods resolve mysql-0.mysql
What it means: Headless DNS tip.
Step 2: Headless Service
Why: clusterIP None. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf svc. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: b1
Type this:
mkdir -p /tmp/k8s38 && printf '%s\n' 'apiVersion: v1' 'kind: Service' 'metadata: {name: mysql}' 'spec:' ' clusterIP: None' ' selector: {app: mysql}' ' ports: [{port: 3306, name: mysql}]' > /tmp/k8s38/svc.yaml && grep clusterIP /tmp/k8s38/svc.yaml
You will see:
clusterIP: None
What it means: Headless Service YAML.
Example 5: b2
Type this:
kubectl apply -f /tmp/k8s38/svc.yaml
You will see:
service/mysql created
What it means: Headless Service created.
Example 6: b3
Type this:
kubectl get svc mysql -o jsonpath='{.spec.clusterIP}'; echo
You will see:
None
What it means: clusterIP is None as required.
Step 3: StatefulSet YAML
Why: volumeClaimTemplates. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf sts. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: c1
Type this:
printf '%s\n' 'apiVersion: apps/v1' 'kind: StatefulSet' 'metadata: {name: mysql}' 'spec:' ' serviceName: mysql' ' replicas: 1' ' selector: {matchLabels: {app: mysql}}' ' template:' ' metadata: {labels: {app: mysql}}' ' spec:' ' containers:' ' - name: mysql' ' image: mysql:8.0' ' env:' ' - {name: MYSQL_ALLOW_EMPTY_PASSWORD, value: "yes"}' ' - {name: MYSQL_DATABASE, value: shop}' ' ports: [{containerPort: 3306, name: mysql}]' ' volumeMounts: [{name: data, mountPath: /var/lib/mysql}]' ' volumeClaimTemplates:' ' - metadata: {name: data}' ' spec:' ' accessModes: [ReadWriteOnce]' ' resources: {requests: {storage: 1Gi}}' > /tmp/k8s38/sts.yaml && grep volumeClaimTemplates /tmp/k8s38/sts.yaml
You will see:
volumeClaimTemplates:
What it means: StatefulSet with 1Gi PVC template.
Example 8: c2
Type this:
kubectl apply -f /tmp/k8s38/sts.yaml
You will see:
statefulset.apps/mysql created
What it means: StatefulSet created.
Example 9: c3
Type this:
kubectl rollout status statefulset/mysql --timeout=180s
You will see:
statefulset rolling update complete 1 pods at revision
What it means: Pod mysql-0 Ready (may take time to pull).
3. Build the main pieces
Step 4: Wait mysql-0
Why: Pod Ready. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: rollout status. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: d1
Type this:
kubectl get pods -l app=mysql -o wide
You will see:
NAME READY STATUS
mysql-0 1/1 Running
What it means: Stable Pod name mysql-0.
Example 11: d2
Type this:
kubectl get pvc
You will see:
NAME STATUS VOLUME CAPACITY
data-mysql-0 Bound ... 1Gi
What it means: PVC data-mysql-0 Bound.
Example 12: d3
Type this:
kubectl get sts mysql
You will see:
NAME READY AGE
mysql 1/1 ...
What it means: StatefulSet READY 1/1.
Step 5: Prove PVC Bound
Why: PVC Bound. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: kubectl get pvc. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: e1
Type this:
kubectl exec mysql-0 -- mysql -e 'SHOW DATABASES;'
You will see:
Database
information_schema
shop
mysql
...
What it means: shop database exists inside MySQL.
Example 14: e2
Type this:
kubectl exec mysql-0 -- mysql -e 'CREATE TABLE shop.items(id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO shop.items VALUES (1,"pen"); SELECT * FROM shop.items;'
You will see:
id name
1 pen
What it means: Wrote a row to prove persistence path.
Example 15: e3
Type this:
echo 'Lab uses empty password only on kind; never in real clusters'
You will see:
Lab uses empty password only on kind; never in real clusters
What it means: Security note.
Step 6: Insert row
Why: SQL write. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: kubectl exec mysql. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: f1
Type this:
kubectl delete pod mysql-0
You will see:
pod "mysql-0" deleted
What it means: Delete Pod to prove identity returns.
Example 17: f2
Type this:
kubectl rollout status statefulset/mysql --timeout=180s
You will see:
statefulset rolling update complete 1 pods at revision
What it means: mysql-0 recreated.
Example 18: f3
Type this:
kubectl exec mysql-0 -- mysql -N -e 'SELECT name FROM shop.items WHERE id=1;'
You will see:
pen
What it means: Data survived on the PVC.
4. Automate and verify
Step 7: Delete and recheck
Why: Data persists. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: delete pod. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: g1
Type this:
kubectl get pv | head -5
You will see:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
What it means: PV provisioned by the lab StorageClass.
Example 20: g2
Type this:
kubectl get sc
You will see:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE
standard ...
What it means: Default StorageClass present on kind.
Example 21: g3
Type this:
echo 'Production picks gp3 or similar; set storageClassName explicitly'
You will see:
Production picks gp3 or similar; set storageClassName explicitly
What it means: Prod tip.
Step 8: PV and StorageClass
Why: SC for disks. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: kubectl get sc. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: h1
Type this:
echo 'Ordinals: mysql-0 then mysql-1 when replicas grow'
You will see:
Ordinals: mysql-0 then mysql-1 when replicas grow
What it means: Ordered scale tip.
Example 23: h2
Type this:
echo 'Do not scale MySQL StatefulSet like a stateless web app without a plan'
You will see:
Do not scale MySQL StatefulSet like a stateless web app without a plan
What it means: Caution.
Example 24: h3
Type this:
echo 'Operators like Percona charts handle HA better than raw STS alone'
You will see:
Operators like Percona charts handle HA better than raw STS alone
What it means: Next-step tip.
Step 9: Scale caution
Why: Do not casual scale. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: echo caution. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: i1
Type this:
kubectl get endpoints mysql
You will see:
NAME ENDPOINTS
mysql 10.x:3306
What it means: Headless still lists Pod IP.
Example 26: i2
Type this:
echo 'DNS shape for ordinal 0 is mysql-0.mysql.default.svc.cluster.local'
You will see:
DNS shape for ordinal 0 is mysql-0.mysql.default.svc.cluster.local
What it means: Stable DNS for ordinal 0.
Example 27: i3
Type this:
echo 'Use nslookup from a busybox Pod to prove it on your lab'
You will see:
Use nslookup from a busybox Pod to prove it on your lab
What it means: How to prove DNS.
5. Harden and accept
Step 10: DNS for mysql-0
Why: DNS works. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: nslookup. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: j1
Type this:
kubectl describe pvc data-mysql-0 | head -15
You will see:
Name: data-mysql-0
Status: Bound
...
What it means: PVC details and Bound status.
Example 29: j2
Type this:
kubectl get sts mysql -o jsonpath='{.spec.serviceName}'; echo
You will see:
mysql
What it means: serviceName links to headless Service.
Example 30: j3
Type this:
echo 'Default delete of STS removes Pods; PVCs often remain until you delete them'
You will see:
Default delete of STS removes Pods; PVCs often remain until you delete them
What it means: Delete semantics tip.
Step 11: PVC describe
Why: Describe PVC. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: describe pvc. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: k1
Type this:
echo 'Backup tip: use mysqldump to an object store on a schedule'
You will see:
Backup tip: use mysqldump to an object store on a schedule
What it means: Backup habit.
Example 32: k2
Type this:
echo 'Snapshot tip: VolumeSnapshots for faster restore drills'
You will see:
Snapshot tip: VolumeSnapshots for faster restore drills
What it means: Snapshot tip.
Example 33: k3
Type this:
echo 'Fix data dir ownership with securityContext runAsUser; never world-writable modes'
You will see:
Fix data dir ownership with securityContext runAsUser; never world-writable modes
What it means: Permissions habit.
Step 12: Acceptance checklist
Why: Imran signs off. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: z1
Type this:
kubectl get pods -l app=mysql --no-headers | awk '{print $1,$3}'
You will see:
mysql-0 Running
What it means: Pod healthy.
Example 35: z2
Type this:
kubectl exec mysql-0 -- mysql -N -e 'SELECT COUNT(*) FROM shop.items;'
You will see:
1
What it means: Row still present.
Example 36: z3
Type this:
echo 'Imran: PASS'
You will see:
Imran: PASS
What it means: Project 38 accepted.
Check yourself
Q1. Who fixed Zoho MySQL?
Imran
Q2. Pod name?
mysql-0
Q3. PVC name pattern?
data-mysql-0
Q4. clusterIP value?
None
Q5. Image?
mysql:8.0
Q6. Database name?
shop
Friends, you proved MySQL data survived a Pod delete on a PVC. Did you understand? Let us try it once more. Write one mysqldump backup tip in your notebook.
मित्रांनो, PVC वर Pod delete नंतर data सिद्ध केले. mysqldump tip लिहा.
दोस्तों, PVC पर Pod delete के बाद data सिद्ध किया. mysqldump tip लिखें.
Lab: try at home
- Create headless Service.
- Apply StatefulSet with PVC template.
- Insert a row.
- Delete mysql-0 and verify.
- Note StorageClass and backup tips.
Recap
- Headless gives per-Pod DNS.
- Ordinals are stable names.
- PVCs outlive Pods.
- emptyDir is not for databases.
- Operators help for real HA.