今天要來介紹什麼是 Statefulset ,一般我們前面進行透過 Deployment 部署的 POD,他都是 stateless , statefulset 跟 Deployment 的差別就在於它對對每一個 POD 產生固定的識別資訊,不會因為 POD 重啟而有所變動,所掛載的硬碟也都可以持續使用。
那到底什麼時侯應該使用 Statefulset ?
這邊先給一個標準的 redis statefulset 設置
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
selector:
matchLabels:
app: redis
serviceName: "redis"
replicas: 1
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:5.0.4
command: ["redis-server", "--appendonly", "yes"]
ports:
- containerPort: 6379
name: web
volumeMounts:
- name: redis-aof
mountPath: /data
volumeClaimTemplates:
- metadata:
name: redis-aof
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "gp2"
resources:
requests:
storage: 1Gi
目前筆者 local 環境 multipass + k3s ,暫時無法實作出 local pvc,所以暫時無操作示範
照上面的 yaml 去部署相關檔案,應該會出現如下所示
$ kubectl --kubeconfig ~/.kube/k3s.yaml get pods
NAME READY STATUS RESTARTS AGE
redis-0 1/1 Running 2 5d17h
那我們需要去部署一個 headless service,用來搭配 Statefulset,
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
spec:
ports:
- port: 6379
name: web
# 這邊跟一般 service 不同的重點在這,要把 clusterIP 設定為 None
clusterIP: None
selector:
app: redis
這樣就完成了一個有狀態的 redis 設定。
大家有興趣可以去嘗試看看,另外部署一個無狀態的 redis,然後分別對這兩個 redis 設定資料,然後去 delete pods,看看 pod 重啟後,資料是不是都還在。
下面附上無狀態的 redis 設定檔,讓大家嘗試看看。
apiVersion: apps/v1
# 這裡改回 Deployment
kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
app: redis
serviceName: "redis"
replicas: 1
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:5.0.4
command: ["redis-server", "--appendonly", "yes"]
ports:
- containerPort: 6379
name: web
---
kind: Service
apiVersion: v1
metadata:
name: redis
spec:
type: ClusterIP
selector:
app: redis
ports:
- protocol: TCP
port: 6379
targetPort: 6379