StatefulSet(有狀態集,縮寫為sts)常用於部署有狀態的且需要有序啟動的應用程序,比如在進行SpringCloud項目容器化時,Eureka的部署是比較適合用StatefulSet部署方式的,可以給每個Eureka實例創建一個唯一且固定的標識符,並且每個Eureka實例無需配置多余的Service,其余Spring Boot應用可以直接通過Eureka的Headless Service即可進行注冊。
Eureka的statefulset的資源名稱是
eureka,eureka-0
eureka-1
eureka-2
Service:headless service,沒有ClusterIP [每個]
eureka-svc Eureka-0.eureka-svc.NAMESPACE_NAME eureka-1.eureka-svc …
連接 eureka的資源名稱為:eureka
statefullset示例
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
[root@k8s-master01 statefullset]# kubectl create -f statefullset.yaml
service/nginx created
statefulset.apps/web created
#擴容:
replicas: 2 #[定義副本集數量]
[root@k8s-master01 statefullset]# kubectl get pod
web-0 1/1 Running 0 1m
web-1 1/1 Running 0 1m
#命令擴容
[root@k8s-master01 statefullset]# kubectl scale --replicas=3 sts web
statefulset.apps/web scaled
#檢查擴容
[root@k8s-master01 statefullset]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 15m
web-1 1/1 Running 0 12m
web-2 1/1 Running 0 35s
#檢查擴容流程:
[root@k8s-master01 ~]# kubectl scale --replicas=5 sts web
statefulset.apps/web scaled
[root@k8s-master01 ~]# kubectl get pod -l app=nginx -w
NAME READY STATUS RESTARTS AGE
nginx-68db656dd8-cc4jv 1/1 Running 0 36h
nginx-68db656dd8-hvj8x 1/1 Running 0 36h
web-0 1/1 Running 0 18h
web-1 1/1 Running 0 18h
web-2 0/1 Pending 0 0s
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 18s
web-3 0/1 Pending 0 0s
web-3 0/1 Pending 0 0s
web-3 0/1 ContainerCreating 0 0s
web-3 1/1 Running 0 18s
web-4 0/1 Pending 0 0s
web-4 0/1 Pending 0 0s
web-4 0/1 ContainerCreating 0 0s
web-4 1/1 Running 0 17s
statefulset 更新策略
#默認更新策略:
updateStrategy:
rollingUpdate:
partition: 0 # 設置為1 一次更新一個,如果設置為 0 則是隨機更新
type: RollingUpdate #--- statefulset默認更新策略 滾動更新,有一個更新失敗就不會繼續更新,deployment是隨機更新模式
statefulset更新策略:
1. RollingUpdate 滾動更新 [從下往上更新,倒序更新]
2. OnDelete 手動更新 [需要刪除一個pod才會觸發更新策略]
默認更新策略RollingUpdate示例:
執行命令: kubectl edit sts web
找到:
containers:
- image: nginx
改為:
containers:
- image: nginx:1.15.2
# 查看更新過程:
[root@k8s-master01 ~]# kubectl get pod -l app=nginx -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 20h
web-1 1/1 Running 0 20h
web-2 1/1 Running 0 89m
web-2 1/1 Terminating 0 90m
web-2 0/1 Terminating 0 90m
web-2 0/1 Terminating 0 90m
web-2 0/1 Terminating 0 90m
web-2 0/1 Pending 0 0s
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 19s
web-1 1/1 Terminating 0 20h
web-1 0/1 Terminating 0 20h
web-1 0/1 Terminating 0 20h
web-1 0/1 Terminating 0 20h
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 20s
web-0 1/1 Terminating 0 20h
web-0 0/1 Terminating 0 20h
web-0 0/1 Terminating 0 20h
web-0 0/1 Terminating 0 20h
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 19s
# 查看更新結果:
[root@k8s-master01 ~]# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 59s
web-1 1/1 Running 0 88s
web-2 1/1 Running 0 118s
# 驗證結果:
[root@k8s-master01 ~]# kubectl exec -it web-0 -- sh
# nginx -v
nginx version: nginx/1.15.2
OnDelete策略示例:
# 修改為 OnDelete 策略
# kubectl edit sts web
找到:
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
改為:
updateStrategy:
type: OnDelete
# 修改鏡像版本來查看 是否此策略會更新版本
image: nginx
#改為:
image: nginx:1.15.3
#保存 [刪除 rollingUpdate: 與 partition: 0 並且將 type: RollingUpdate 改為 type: OnDelete ]
#檢查:
[root@k8s-master01 ~]# kubectl get pod |grep web
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 6m58s
web-1 1/1 Running 0 7m17s # <-- 並未更新
web-2 1/1 Running 0 7m48s
#再次修改鏡像版本並刪除其中一個pod:
[root@k8s-master01 ~]# kubectl edit sts web #把 nginx:1.15.3 改為 nginx:1.15.2
statefulset.apps/web edited
[root@k8s-master01 statefullset]# kubectl delete pod web-1
pod "web-1" deleted
# 檢查刪除的pod更新狀態:
[root@k8s-master01 statefullset]# kubectl get pod web-1 -o yaml|grep image
- image: nginx:1.15.3
imagePullPolicy: Always
image: nginx:1.15.3
imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
# 檢查未刪除的pod版本:
[root@k8s-master01 statefullset]# kubectl get pod web-0 -o yaml|grep image
- image: nginx
imagePullPolicy: Always
image: nginx:latest
imageID: docker-pullable://nginx@sha256:353c20f74d9b6aee359f30e8e4f69c3d7eaea2f610681c4a95849a2fd7c497f9
# 再刪除這個未刪除的版本檢查刪除后是否會更新,剛刪除的web-1 現在刪除web-0:
[root@k8s-master01 statefullset]# kubectl delete pod web-0
pod "web-0" deleted
#檢查刪除后的web-0 是否更新了版本
[root@k8s-master01 statefullset]# kubectl get pod web-0 -o yaml|grep image
- image: nginx:1.15.3
imagePullPolicy: Always
image: nginx:1.15.3 # -- 確定已經更新了版本
imageID: docker-pullable://nginx@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
這就是Ondelete的更新策略