Ravindra BagaleCourses & study guides मराठी

Chapter 75: DevOps Projects Part 5: Kubernetes Cluster Deploy Ingress TLS HPA Probes StatefulSet Blue-Green

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.

What you will build in this project

  1. Headless Service mysql.
  2. StatefulSet mysql-0 with PVC.
  3. Insert a row into shop.items.
  4. 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.

ServiceclusterIP NoneStatefulSetmysql-0PVCdata-mysql-0recreate Poddata remains
Picture 1: headless Service + StatefulSet + PVC survives Pod delete

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.

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.

Lab: try at home

  1. Create headless Service.
  2. Apply StatefulSet with PVC template.
  3. Insert a row.
  4. Delete mysql-0 and verify.
  5. 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.