antony@notes:~/kubernetes$ cat "Kubernetes-StatefulSet.md"
Kubernetes StatefulSet
Kubernetes StatefulSet
[TOC]
認識 StatefulSet

- StatefulSet 中所有 Pod 的名字都會以遞增整數作為結尾(以0為起點), 因此 Pod DNS 變得容易訪問, ReplicaSet 則隨機生成 Pod 名字 。

- 當 Pod 所在的 worker node 損毀, StatefulSet 會在其他 worker node 上創建該 Pod, 且保持 Pod 的名字和 hostname, ReplicaSet 則會重新分配 Pod 的名字和 hostname 。

- 當減小 StatefulSet 的 replica count 時, 會按照 Pod 的名字倒序移除 Pod, 一次只能移除一個 Pod, 序號最大的先被移除, ReplicaSet 則會隨機移除一個 Pod

- 由於 Pod 移轉時必須保證新建的 Pod 依然綁定原 Volume, StatefulSet 需要維持 Pod 與 PersistentVolumeClaim 之間的對應關係, 所以 PVC 不再由用戶管理
echo 'apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
serviceName: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: quay.io/flysangel/nginx
volumeMounts:
- name: html-storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: html-storage
spec:
storageClassName: local-path
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi' > statefulset-nginx.yaml$ kubectl exec -it nginx-0 -- bash -c "echo 'My nginx-0' > /usr/share/nginx/html/index.html"
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 4m53s 10.244.2.55 w2 <none> <none>
nginx-1 1/1 Running 0 4m27s 10.244.0.26 m1 <none> <none>
nginx-2 1/1 Running 0 58s 10.244.2.57 w2 <none> <none>
nginx-6f47499ff9-2dfcp 0/1 Pending 0 37m <none> <none> <none> <none>
nginx-6f47499ff9-5q6q8 0/1 Pending 0 37m <none> <none> <none> <none>
nginx-6f47499ff9-f5lh5 0/1 Pending 0 37m <none> <none> <none> <none>
$ curl 10.244.2.55
My nginx-0
$ curl 10.244.2.57
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>
$ curl 10.244.0.26
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>$ kubectl exec -it nginx-1 -- bash -c "echo 'My nginx-1' > /usr/share/nginx/html/index.html"
$ curl 10.244.2.57
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>
$ curl 10.244.0.26
My nginx-1
$ curl 10.244.2.55
My nginx-0$ kubectl exec -it nginx-2 -- bash -c "echo 'My nginx-2' > /usr/share/nginx/html/index.html"
bigred@m1:~/0613$ curl 10.244.2.57
My nginx-2
bigred@m1:~/0613$ curl 10.244.0.26
My nginx-1
bigred@m1:~/0613$ curl 10.244.2.55
My nginx-0認識 StatefulSet Service

- 對於指向 StatefulSet 的 Service, 其他服務訪問可透過該 Service 取得每個 Pod 的 DNS 名稱, 以 Pod A-0 為例, 透過 a-0.A.default.svc.cluster.local 即可訪問服務
$ echo 'apiVersion: v1
> kind: Service
> metadata:
> name: nginx
> spec:
> clusterIP: None
> selector:
> app: nginx' > svc-nginx.yaml
$ kubectl apply -f svc-nginx.yaml
service/nginx unchanged
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app1 ClusterIP 10.98.0.2 <none> 8080/TCP 4d18h
app2 ClusterIP 10.98.0.200 <none> 8080/TCP 4d18h
kubernetes ClusterIP 10.98.0.1 <none> 443/TCP 13d
nginx ClusterIP None <none> <none> 58m
svc-fbs ClusterIP 10.98.0.136 192.168.61.4 8080/TCP 11d
$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 20m 10.244.2.55 w2 <none> <none>
nginx-1 1/1 Running 0 19m 10.244.0.26 m1 <none> <none>
nginx-2 1/1 Running 0 16m 10.244.2.57 w2 <none> <none>
nginx-6f47499ff9-2dfcp 0/1 Pending 0 52m <none> <none> <none> <none>
nginx-6f47499ff9-5q6q8 0/1 Pending 0 52m <none> <none> <none> <none>
nginx-6f47499ff9-f5lh5 0/1 Pending 0 52m <none> <none> <none> <none>
$ nslookup
> server 10.98.0.10
Default server: 10.98.0.10
Address: 10.98.0.10#53
> 10.244.2.55
55.2.244.10.in-addr.arpa name = nginx-0.nginx.default.svc.k8s.org.
> 10.244.0.26
26.0.244.10.in-addr.arpa name = nginx-1.nginx.default.svc.k8s.org.
> 10.244.2.57
57.2.244.10.in-addr.arpa name = nginx-2.nginx.default.svc.k8s.org.
> nginx.default.svc.k8s.org
Server: 10.98.0.10
Address: 10.98.0.10#53
Name: nginx.default.svc.k8s.org
Address: 10.244.2.55
Name: nginx.default.svc.k8s.org
Address: 10.244.0.26
Name: nginx.default.svc.k8s.org
Address: 10.244.2.57刪除 StatefulSet
$ kubectl delete -f svc-nginx.yaml
service "nginx" deleted
$ kubectl delete -f statefulset-nginx.yaml
statefulset.apps "nginx" deleted
$ kubectl delete pvc html-storage-nginx-0 html-storage-nginx-1 html-storage-nginx-2
persistentvolumeclaim "html-storage-nginx-0" deleted
persistentvolumeclaim "html-storage-nginx-1" deleted
persistentvolumeclaim "html-storage-nginx-2" deleted由 StatefulSet 生成的 pvc ,他的生命週期會跟著 Namespace 活著,直到 Namespace 被刪除
練習
請問如何擴展 StatefulSet。 請觀察擴展 StatefulSet 時,pod 或 container 狀態為何。 請建立 StatefulSet replicas 為 3,並逐一新增 nginx 網頁,當 replicas 由 3 轉為 2 再恢復至 3 時,請問資料是否都還保存完整。
練習完後請刪除練習環境 Pod -> PVC
$ kubectl apply -f svc-nginx.yaml
$ kubectl apply -f statefulset-nginx.yaml
$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 86s 10.244.2.61 w2 <none> <none>
nginx-1 1/1 Running 0 76s 10.244.0.29 m1 <none> <none>
nginx-2 1/1 Running 0 66s 10.244.2.63 w2 <none> <none>
$ $ kubectl scale statefulset/nginx --replicas=6
statefulset.apps/nginx scale
$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 2m55s 10.244.2.61 w2 <none> <none>
nginx-1 1/1 Running 0 2m45s 10.244.0.29 m1 <none> <none>
nginx-2 1/1 Running 0 2m35s 10.244.2.63 w2 <none> <none>
nginx-3 1/1 Running 0 45s 10.244.1.126 w1 <none> <none>
nginx-4 1/1 Running 0 37s 10.244.1.128 w1 <none> <none>
nginx-5 1/1 Running 0 28s 10.244.0.31 m1 <none> <none>
$ kubectl scale statefulset/nginx --replicas=3
statefulset.apps/nginx scaled
bigred@m1:~/0613$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 3m38s 10.244.2.61 w2 <none> <none>
nginx-1 1/1 Running 0 3m28s 10.244.0.29 m1 <none> <none>
nginx-2 1/1 Running 0 3m18s 10.244.2.63 w2 <none> <none>
$ kubectl exec -it nginx-2 -- bash -c "echo 'My nginx-2' > /usr/share/nginx/html/index.html"
bigred@m1:~/0613$ curl 10.244.2.63
My nginx-2
$ kubectl scale statefulset/nginx --replicas=2
statefulset.apps/nginx scaled
bigred@m1:~/0613$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 5m13s 10.244.2.61 w2 <none> <none>
nginx-1 1/1 Running 0 5m3s 10.244.0.29 m1 <none> <none>
$ kubectl scale statefulset/nginx --replicas=3
statefulset.apps/nginx scaled
bigred@m1:~/0613$ kg pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 5m54s 10.244.2.61 w2 <none> <none>
nginx-1 1/1 Running 0 5m44s 10.244.0.29 m1 <none> <none>
nginx-2 1/1 Running 0 12s 10.244.2.64 w2 <none> <none>
$ curl 10.244.2.64
My nginx-2答:資料有保存