We can deploy the exact same ECR image twice:
Restaurant Company ECR Image
|
┌──────┴──────┐
↓ ↓
Deployment StatefulSet
↓ ↓
restaurant-* restaurant-0
random names restaurant-1
restaurant-2
This lets them see the difference, instead of only hearing the theory.
Part 1 — First find your exact ECR image
On EC2 run:
aws ecr describe-repositories --region us-east-1
Then:
aws ecr list-images \
--repository-name restaurant-company \
--region us-east-1
Your image should look something like:
459532536656.dkr.ecr.us-east-1.amazonaws.com/restaurant-company:v1
Use your actual tag below if it is not v1.
LAB 1 — Deployment
Tell students:
Сначала запускаем наш Restaurant Company как Deployment.
Потом удалим Pod и посмотрим, что Kubernetes создаст новый Pod с другим именем.
Create:
mkdir statefulset-lab
cd statefulset-lab
vim deployment.yaml
Put:
apiVersion: apps/v1
kind: Deployment
metadata:
name: restaurant-deployment
spec:
replicas: 3
selector:
matchLabels:
app: restaurant
template:
metadata:
labels:
app: restaurant
spec:
containers:
- name: restaurant
image: 459532536656.dkr.ecr.us-east-1.amazonaws.com/restaurant-company:v1
ports:
- containerPort: 80
Run:
kubectl apply -f deployment.yaml
Then:
kubectl get pods
Students should see something like:
restaurant-deployment-7d8c96b7d4-x7p2m
restaurant-deployment-7d8c96b7d4-k9t5z
restaurant-deployment-7d8c96b7d4-m4q8n
STOP HERE and ask them
Ребята, какое имя у первого Pod?
They'll give the long name.
Then:
Как будет называться следующий Pod?
They cannot know.
Explain:
DEPLOYMENT
restaurant-deployment-xxxxx-A
restaurant-deployment-xxxxx-B
restaurant-deployment-xxxxx-C
Identity не важна.
Delete one Deployment Pod
Get the names:
kubectl get pods
Copy one and delete it:
kubectl delete pod restaurant-deployment-XXXXXXXXXX-XXXXX
Immediately:
kubectl get pods -w
Show them:
OLD:
restaurant-deployment-abc123-x7p2m ❌
NEW:
restaurant-deployment-abc123-j8k4q ✅
Ask:
То же имя вернулось?
Нет.
That's the lesson:
Deployment говорит:
"Мне всё равно, какой Pod. Просто дай мне 3 работающих Pod."
LAB 2 — Same ECR image, but StatefulSet
Don't add storage yet.
Students need to understand identity first.
Create:
vim statefulset.yaml
Use:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: restaurant-statefulset
spec:
serviceName: restaurant
replicas: 3
selector:
matchLabels:
app: restaurant-stateful
template:
metadata:
labels:
app: restaurant-stateful
spec:
containers:
- name: restaurant
image: 459532536656.dkr.ecr.us-east-1.amazonaws.com/restaurant-company:v1
ports:
- containerPort: 80
Apply:
kubectl apply -f statefulset.yaml
Watch it:
kubectl get pods -w
Now something very important happens.
Students should see:
restaurant-statefulset-0
restaurant-statefulset-1
restaurant-statefulset-2
Tell them:
STOP. Смотрите на имена.
Compare:
DEPLOYMENT
restaurant-deployment-7d8c9-x8p2m
restaurant-deployment-7d8c9-k3j9q
restaurant-deployment-7d8c9-p7w4a
STATEFULSET
restaurant-statefulset-0
restaurant-statefulset-1
restaurant-statefulset-2
Now ask:
Если я поставлю replicas: 4, как будет называться следующий Pod?
Students should answer:
restaurant-statefulset-3
That's when they'll start understanding StatefulSet.
Now delete StatefulSet Pod
Run:
kubectl delete pod restaurant-statefulset-1
Then:
kubectl get pods -w
They should see:
restaurant-statefulset-1
come back.
Tell them:
Я удалил
restaurant-statefulset-1.
Kubernetes не сказал: "Дам тебе какой-нибудь новый Pod."Он сказал:
"Мне нужен именно номер 1 обратно."
Draw:
STATEFULSET
restaurant-statefulset-0
restaurant-statefulset-1 ❌
restaurant-statefulset-2
↓
restaurant-statefulset-0
restaurant-statefulset-1 ✅
restaurant-statefulset-2
This is stable identity.
Now the question that makes the class understand
Ask:
Хорошо. Имя вернулось. Но если внутри
restaurant-statefulset-1были важные данные — вернутся ли данные?
Answer:
Not automatically.
Now introduce storage.
Identity:
restaurant-statefulset-1
+
Storage:
PVC-1
=
Stateful application
LAB 3 — StatefulSet + Persistent Storage
For your Restaurant Company app, Nginx normally serves static files, so it does not actually need StatefulSet in production.
Tell students this clearly:
Мы используем Restaurant Company с StatefulSet для обучения.
В реальном проекте этот frontend лучше запускать Deployment.Database — MySQL, PostgreSQL, MongoDB — гораздо более естественный пример StatefulSet.
But Restaurant Company makes the mechanics easy to see.
Let's give each Pod its own /data.
First check:
kubectl get storageclass
Then modify statefulset.yaml:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: restaurant-statefulset
spec:
serviceName: restaurant
replicas: 3
selector:
matchLabels:
app: restaurant-stateful
template:
metadata:
labels:
app: restaurant-stateful
spec:
containers:
- name: restaurant
image: 459532536656.dkr.ecr.us-east-1.amazonaws.com/restaurant-company:v1
ports:
- containerPort: 80
volumeMounts:
- name: restaurant-data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: restaurant-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Because an existing StatefulSet may not accept this structural change cleanly, for the classroom the simplest route is to recreate the lab StatefulSet:
kubectl delete statefulset restaurant-statefulset
Then:
kubectl apply -f statefulset.yaml
Watch:
kubectl get pods -w
Then:
kubectl get pvc
Now the students should see the big idea:
restaurant-data-restaurant-statefulset-0
restaurant-data-restaurant-statefulset-1
restaurant-data-restaurant-statefulset-2
Draw:
restaurant-statefulset-0
|
↓
restaurant-data-restaurant-statefulset-0
restaurant-statefulset-1
|
↓
restaurant-data-restaurant-statefulset-1
restaurant-statefulset-2
|
↓
restaurant-data-restaurant-statefulset-2
Now PROVE the data survives
This is the most important part of today's class.
Enter Pod 1:
kubectl exec -it restaurant-statefulset-1 -- sh
Inside:
echo "HELLO FROM POD NUMBER 1" > /data/student.txt
Check:
cat /data/student.txt
You should get:
HELLO FROM POD NUMBER 1
Exit:
exit
Now tell students:
Сейчас я уничтожу Pod.
kubectl delete pod restaurant-statefulset-1
Watch:
kubectl get pods -w
Wait until:
restaurant-statefulset-1 1/1 Running
Now:
kubectl exec -it restaurant-statefulset-1 -- sh
Then:
cat /data/student.txt
And:
HELLO FROM POD NUMBER 1
This is your wow moment.
Tell them:
Pod умер.
Container умер.
Новый container был создан.
Но данные остались.
Because:
OLD POD
restaurant-statefulset-1 ❌
|
↓
PVC-1 ✅
|
↓
DATA ✅
NEW POD
restaurant-statefulset-1 ✅
|
↓
SAME PVC-1
|
↓
DATA ✅
Then prove each Pod has its OWN storage
Run:
kubectl exec -it restaurant-statefulset-0 -- sh
Inside:
cat /data/student.txt
It should not contain Pod 1's file.
Then:
echo "I AM POD ZERO" > /data/student.txt
exit
Check Pod 0:
kubectl exec restaurant-statefulset-0 -- cat /data/student.txt
Result:
I AM POD ZERO
Check Pod 1:
kubectl exec restaurant-statefulset-1 -- cat /data/student.txt
Result:
HELLO FROM POD NUMBER 1
Now draw this:
STATEFULSET
restaurant-statefulset
/ | \
/ | \
POD-0 POD-1 POD-2
| | |
↓ ↓ ↓
PVC-0 PVC-1 PVC-2
| | |
↓ ↓ ↓
"I AM 0" "HELLO 1" DATA-2
The sentence I want your students to repeat
Have the whole class say this:
Deployment сохраняет количество Pod.
StatefulSet сохраняет identity Pod.
PVC сохраняет данные.
And then:
Deployment:
"I need 3 Pods."
StatefulSet:
"I need Pod 0,
I need Pod 1,
I need Pod 2,
and each can have its own storage."
Top comments (0)