StatefulSet如何提供穩定的網絡辨別和狀态
ReplicaSet中的Pod都是無狀态,可随意替代的。又因為ReplicaSet中的Pod是根據模闆生成的多副本,無法對每個副本都指定單獨的PVC。
來看一下StatefulSet如何解決的。
提供穩定的網絡辨別
StatefulSet建立Pod都有一個從零開始的順序索引,這會展現在Pod的名稱和主機名上,同樣也會展現在Pod對應的固定存儲上。是以這些名字是可預先知道的,不同于ReplicaSet的随機生成名字。
因為他們的名字都是固定的,而且彼此狀态都不同,通常會操作他們其中的一個。如此情況,一般都會建立一個與之對應的headless Service,通過這個Service,每個Pod将擁有獨立的DNS記錄。
擴容一個StatefulSet會使用下一個順序索引建立一個新的Pod,縮容會删除索引值最高的。并且縮容任何時候隻會操作一個Pod。
如何提供穩定的存儲
StatefulSet可以擁有一個或多個PVC模闆,這些PVC會在建立Pod前建立出來,綁定到一個Pod執行個體上。
擴容的時候會建立一個Pod以及若幹個PVC,删除的時候隻會删除Pod。StatefulSet縮容時不會删除PVC,擴容時會重新挂上。
使用StatefulSet
定義三個PV
定義pv-(a|b|c)
# stateful-pv-list.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-a
spec:
capacity:
storage: 1Mi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
hostPath:
path: /tmp/pva
---
apiVersion: v1
kind: PersistentVolume
# 以下忽略
headless的Service
# stateful-service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: rwfile
spec:
clusterIP: None
selector:
app: rwfile
ports:
- port: 80
定義StatefulSet
先建立兩個Pod副本。使用volumeClaimTemplates定義了PVC模闆。
# stateful.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rwfile
spec:
replicas: 2
serviceName: rwfile
selector:
matchLabels:
app: rwfile
template:
metadata:
labels:
app: rwfile
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/orzi/rwfile
name: rwfile
ports:
- containerPort: 8000
volumeMounts:
- name: data
mountPath: /tmp/data
volumeClaimTemplates:
- metadata:
name: data
spec:
resources:
requests:
storage: 1Mi
accessModes:
- ReadWriteOnce
建立三個PV,一個headless的Service,一個StatefulSet
-> [[email protected]] [~] k create -f stateful-pv-list.yaml
persistentvolume/pv-a created
persistentvolume/pv-b created
persistentvolume/pv-c created
-> [[email protected]] [~] k create -f stateful-service-headless.yaml
service/rwfile created
-> [[email protected]] [~] k create -f stateful.yaml
statefulset.apps/rwfile created
檢視
-> [[email protected]] [~] k get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/rwfile-0 1/1 Running 0 12s 10.244.1.52 kube1.vm <none> <none>
pod/rwfile-1 1/1 Running 0 8s 10.244.2.56 kube2.vm <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 81s <none>
service/rwfile ClusterIP None <none> 80/TCP 23s app=rwfile
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/rwfile 2/2 12s rwfile registry.cn-hangzhou.aliyuncs.com/orzi/rwfile
檢視PV和PVC,可以看到已經有兩個PVC綁定了PV
-> [[email protected]] [~] k get pv,pvc -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/pv-a 1Mi RWO Recycle Bound default/data-rwfile-0 7m20s Filesystem
persistentvolume/pv-b 1Mi RWO Recycle Bound default/data-rwfile-1 7m20s Filesystem
persistentvolume/pv-c 1Mi RWO Recycle Available 7m20s Filesystem
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
persistentvolumeclaim/data-rwfile-0 Bound pv-a 1Mi RWO 6m55s Filesystem
persistentvolumeclaim/data-rwfile-1 Bound pv-b 1Mi RWO 6m51s Filesystem
請求Pod
啟動代理
-> [[email protected]] [~] k proxy
Starting to serve on 127.0.0.1:8001
發送請求
-> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/ -d "a=123"
data stored in : rwfile-0
-> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/
a=123
删除測試
删除rwfile-0,然後檢視,從時間上看确實是被删除重建的。
-> [[email protected]] [~] k delete po rwfile-0
pod "rwfile-0" deleted
-> [[email protected]] [~] k get po
NAME READY STATUS RESTARTS AGE
rwfile-0 1/1 Running 0 7s
rwfile-1 1/1 Running 0 19m
看一下之前存儲的資料還在不在
-> [[email protected]] [~] curl http://localhost:8001/api/v1/namespaces/default/pods/rwfile-0/proxy/
a=123
還是在的,此次測試實際上也證明了StatefulSet提供了穩定的網絡辨別和存儲。
發現StatefulSet的夥伴節點
使用DNS解析headless的Service的FQDN。
例子以後再寫吧。。
如何處理節點失效
除非确定節點無法運作或者不會在通路,否則不要強制删除有狀态的Pod
k delete pod rwfile-0 --force --grace-period 0
小結
- StatefulSet建立Pod都有一個從零開始的順序索引
- 通常會建立一個與StatefulSet對應的headless Service。
- 擴容一個StatefulSet會使用下一個順序索引建立一個新的Pod,縮容會删除索引值最高的。
- 建立StatefulSet需要指定headless ServiceName和volumeClaimTemplates。
- 使用DNS發現StatefulSet的夥伴節點
- 強制删除:
k delete pod rwfile-0 --force --grace-period 0