一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
一、扩缩容 StatefulSet
StatefulSet
和 Deployment
、DaemonSet
一样,也可以手动进行扩缩容。主要通过修改配置中的 replicas
字段实现。
扩容 StatefulSet
:
# 由于实验环境中只有两个 Node,扩容操作不会成功,大家可以自行在本地尝试
kubectl scale sts web --replicas=5
statefulset.apps/web scaled
复制代码
缩容 StatefulSet
:
kubectl patch sts web -p '{"spec":{"replicas":1}}'
statefulset.apps/web patched
复制代码
二、更新 StatefulSet
StatefulSet
可以使用字段 spec.updateStrategy.type
设置更新策略,可以用于更新 StatefulSet
中 Pod
的 container images
、resource requests
、limits
、labels
、以及 annotations
等,目前支持两种更新策略:
RolingUpdate
:默认策略,更新StatefulSet
模板后,自动删除旧的Pod
并创建新的Pod
,并且更新顺序与序号索引相反OnDelete
:更新StatefulSet
模板后,只有手动删除了旧的Pod
才会创建新的Pod
- 使用默认策略更新容器的镜像,首先新开一个终端监控
Pod
的变化过程
kubectl get pods -w -l app=nginx
复制代码
- 更新
Pod
的镜像为nginx-slim:0.7
$ kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"registry-vpc.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx-slim:0.7"}]'
statefulset.apps/web patched
复制代码
- 再看
Pod
的变化过程
$ kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 38s
web-1 1/1 Running 0 36s
# 先更新 web-1 Pod
web-1 1/1 Terminating 0 68s
web-1 0/1 Terminating 0 69s
web-1 0/1 Terminating 0 75s
web-1 0/1 Terminating 0 75s
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 2s
# 然后更新 web-0 Pod
web-0 1/1 Terminating 0 79s
web-0 0/1 Terminating 0 79s
web-0 0/1 Terminating 0 87s
web-0 0/1 Terminating 0 87s
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 3s
复制代码
- 查看新创建的
Pod
的容器镜像,可以发现都已经更新为新镜像了
$ kubectl get pod -l app=nginx -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
web-0 registry-vpc.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx-slim:0.7
web-1 registry-vpc.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx-slim:0.7
$ kubectl rollout status sts/web
partitioned roll out complete: 2 new pods have been updated...
复制代码
七、删除 StatefulSet
删除 StatefulSet
分为两种方式:
- 非级联删除:删除
StatefulSet
时,由StatefulSet
创建的Pod
不会被删除 - 级联删除:删除
StatefulSet
时,StatefulSet
本身及其所创建的Pod
都会被删除,并且删除顺序与序号索引相反
(1)非级联删除
使用 --cascade=false
参数就表示非级联删除:
$ kubectl delete statefulset web --cascade=false
statefulset.apps "web" deleted
# 由 StatefulSet 创建的 Pod 并没有被删除,依然是运行状态
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 50m
web-1 1/1 Running 0 51m
复制代码
尝试手动删除 web-0 Pod
$ kubectl delete pod web-0
pod "web-0" deleted
# 由于删除了 web StatefulSet,所以 web-0 Pod 没有被继续创建了
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-1 1/1 Running 0 53m
复制代码
重新创建 web StatefulSet
# 由于没有删除 nginx 服务,所以重新创建的时候有报错提醒,可以忽略
$ kubectl create -f web.yaml
statefulset.apps/web created
Error from server (AlreadyExists): error when creating "web.yaml": services "nginx" already exists
复制代码
查看当前环境中运行的 Pod
# 当前环境运行的都是新创建的 Pod,原来单独剩下的 web-1 Pod 被删除了
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 3m7s
web-1 1/1 Running 0 2m54s
复制代码
更加详细的过程如下:
$ kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
# 删除 web-0
web-0 1/1 Terminating 0 52m
web-0 0/1 Terminating 0 52m
web-0 0/1 Terminating 0 52m
web-0 0/1 Terminating 0 52m
# web-1 处于运行状态
web-1 1/1 Running 0 62m
# 新创建 web StatefulSet 时,按顺序首先创建 web-0 Pod,创建成功后,由于检测到环境中有单独留下的 web-1 Pod,于是老的 web-1 Pod 被删除,然后重新创建新的 web-1 Pod
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 2s
web-1 1/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
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 1s
复制代码
注意的是:删除
StatefulSet
时,并不会删除与Pod
相关联的PersistentVolumes
,当重新构建StatefulSet
后,新创建的Pod
会挂载原来的PersistentVolumes
。
(2)级联删除
省略参数 --cascade
就表示级联删除:
$ kubectl delete statefulset web
statefulset.apps "web" deleted
复制代码
查看 Pod
变化过程
# 依然是先删除 web-1 Pod,然后删除 web-0 Pod
$ kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 19m
web-1 1/1 Running 0 19m
web-1 1/1 Terminating 0 19m
web-0 1/1 Terminating 0 20m
web-0 0/1 Terminating 0 20m
web-1 0/1 Terminating 0 19m
复制代码
手动删除 nginx
服务
$ kubectl delete service nginx
service "nginx" deleted
复制代码
三、Pod
管理策略
对于某些分布式的系统,有的时候不强制要求 Pod
的启动必须有顺序,只是为了使用 StatefulSet
中的唯一性和身份标志的特性,可以通过 spec.podManagementPolicy
字段设置启动顺序。主要分为两种顺序:
OrderedReady
:默认选项,表示按顺序启动Parallel
:可以并行启动/终止所有Pod
,在启动/终止一个Pod
时不需要等待其它Pod
必须先启动/终止
- 创建
web.yaml
,podManagementPolicy: "Parallel"
---
spec:
serviceName: "nginx"
podManagementPolicy: "Parallel"
replicas: 2
复制代码
- 监控
Pod
的创建过程,并执行创建:
$ kubectl create -f web.yaml
service/nginx created
statefulset.apps/web created
# 可以看到同时启动了 web-0 和 web-1 Pod
$ kubectl get pods -w -l app=nginx
web-0 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-0 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 2s
web-0 1/1 Running 0 2s
复制代码