【Kubernetes】StatefulSet 使用

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

一、扩缩容 StatefulSet

StatefulSetDeploymentDaemonSet 一样,也可以手动进行扩缩容。主要通过修改配置中的 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 设置更新策略,可以用于更新 StatefulSetPodcontainer imagesresource requestslimitslabels、以及 annotations 等,目前支持两种更新策略:

  • RolingUpdate:默认策略,更新 StatefulSet 模板后,自动删除旧的 Pod 并创建新的 Pod,并且更新顺序与序号索引相反
  • OnDelete:更新 StatefulSet 模板后,只有手动删除了旧的 Pod 才会创建新的 Pod
  1. 使用默认策略更新容器的镜像,首先新开一个终端监控 Pod 的变化过程
kubectl get pods -w -l app=nginx
复制代码
  1. 更新 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
复制代码
  1. 再看 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
复制代码
  1. 查看新创建的 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 必须先启动/终止
  1. 创建 web.yamlpodManagementPolicy: "Parallel"
---
spec:
  serviceName: "nginx"
  podManagementPolicy: "Parallel"
  replicas: 2
复制代码
  1. 监控 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
复制代码

猜你喜欢

转载自juejin.im/post/7087487256293802014