一般來說,k8s中的container大多為無狀態(stateless),這樣子進行cotroller進行rollout、rollback、pod self health時不需要為了還在執行中的request額外進行處理(ex:存到redis或是db裡面記錄)。
如果使用者的需求是要pod有辦法持久性時,就需要使用kind :Statefulset 這種模式進行部署。
Statefulset跟Deployment在pod建立之後有一個很明顯的差異點
Deployment : pod name後綴會帶一組亂數,pod 重啟後會重新產生新的名稱
Statefulset : pod name後綴為有序的數字(my-redis-0,my-redis-1),pod 重啟名稱不變
從下面執行就可以看的出來Deployment跟Statefulset pod name很明顯的差異性
kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-66f5d9f844-8z54q 1/1 Running 0 1d
my-app-redis-0 1/1 Running 0 1d
my-app-redis-7f6b9d4875-k27zl 1/1 Running 0 1d
apiVersion: v1
kind: Service
metadata:
name: my-app-redis
labels:
app: redis
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
protocol: TCP
name: redis
selector:
app: my-app-redis
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-app-redis
spec:
serviceName: "my-app-redis"
replicas: 2
selector:
matchLabels:
app: my-app-redis
template:
metadata:
labels:
app: my-app-redis
spec:
containers:
- name: my-app-redis
image: redis:5.0.5
args: ["--appendonly", "yes", "--save", "600", "1"]
ports:
- name: redis
containerPort: 6379
protocol: TCP
volumeMounts:
- name: data
mountPath: /data
resources:{}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 4Gi
跟Deployment
最大差異點在於volumeClaimTemplates
,定義了pvc,這樣子pod就會把redis資料放進在pvc裡面,就算是pod重啟也沒差,因為重啟後,redis會把放在pvc裡面的data重新載入回來,達成持久化的特性
目前會用到Statefulset的主要是redis,但是根據redis pod的使用情境不同,也不一定需要用到Statefulset,如果redis的用途主要是做cache用,redis沒資料時才會打到db,那也可以用Deployment就好,但是redis會存有狀態的資料時,使用上還是要用Statefulset比較保險喔