入门Kubernetes-StatefulSets
前言:
前面文中对通过DaemonSet、存储资源对象,实现了在指定节点中运行一个守护进程。
在真实的业务场景中,部署的服务都是有状态的、且有数据需要持久化的;那么如何实现呢?
那么接下来学习一种更加重要的资源——StatefulSets。
一、StatefulSets 介绍
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
与Deployment 类似,StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个有粘性的ID。这些 Pod 是基于相同的规约来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。
应用场景:
· StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
- 稳定的、唯一的网络标识符。
- 稳定的、持久的存储。
- 有序的、优雅的部署和缩放。
- 有序的、自动的滚动更新。
使用限制:
- 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的
storage class
来提供,或者由管理员预先提供。 - 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
- StatefulSet 当前需要无头服务 来负责 Pod 的网络标识。你需要负责创建此服务。
- 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0。
- 在默认 Pod 管理策略(
OrderedReady
) 时使用 滚动更新,可能进入需要人工干预 才能修复的损坏状态
二、StatefulSets使用方式
-
创建StatefulSets
创建StatefulSets的yaml格式:
apiVersion: apps/v1 kind: StatefulSet #StatefulSet类型 metadata: name: web #StatefulSet 名称 spec: #service名称 serviceName: "nginx" #Pod数量 replicas: 2 selector: matchLabels: app: nginx #Pod定义 template: metadata: labels: app: nginx spec: #容器设置 containers: - name: nginx #镜像名称 image: nginx:1.9.6 ports: - containerPort: 80 name: web volumeMounts: #持久化存储名称 - name: www mountPath: /usr/share/nginx/html #持久化存储定义 volumeClaimTemplates: - metadata: #名称 name: www spec: #访问方式 accessModes: ["ReadWriteOnce"] #资源定义 resources: requests: storage: 1Gi
应用该yaml后Pod创建顺序如下:
>>kubectl apply -f web.yaml
service/nginx created
statefulset apps/web created
>>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 1s web-0 1/1 Running 0 3s 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
可见:StatefulSets中Pod顺序创建成功。
再查看下Nginx中持久化存储资源:
kubectl get pvc -l app=nginx NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-c431e9d6-0dba-4c1d-ba83-b9f1d5b8824a 1Gi RWO standard 137m www-web-1 Bound pvc-58070d7f-9fec-4e28-b77b-b15fdf30c965 1Gi RWO standard 124m
-
扩容/缩容StatefulSets
StatefulSet策略:
-
- 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为
0..N-1
。 - 当删除 Pod 时,它们是逆序终止的,顺序为
N-1..0
。 - 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
- 在 Pod 终止之前,所有的继任者必须完全关闭。
- 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为
扩容:StatefulSet 按序号索引顺序的创建每个 Pod,并且会等待前一个 Pod 变为 Running 和 Ready 才会启动下一个 Pod
#扩容Pod数量为4 >>kubectl scale sts web --replicas=4 statefulset.apps/web scaled #查看pod变化 >>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 53m web-1 1/1 Running 0 53m web-2 0/1 Pending 0 0s web-2 0/1 Pending 0 0s web-2 0/1 Pending 0 3s web-2 0/1 ContainerCreating 0 3s web-2 1/1 Running 0 6s web-3 0/1 Pending 0 0s web-3 0/1 Pending 0 0s web-3 0/1 Pending 0 2s web-3 0/1 ContainerCreating 0 2s web-3 1/1 Running 0 4s
缩容:会按照与 Pod 序号索引相反的顺序每次删除一个 Pod。在删除下一个 Pod 前会等待上一个被完全关闭
#缩容为2个pod >>kubectl scale -n default statefulset web --replicas=2 #查看Pod变化: >>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 59m web-1 1/1 Running 0 59m web-2 1/1 Running 0 4m30s web-3 1/1 Running 0 4m24s web-3 1/1 Terminating 0 7m23s web-3 0/1 Terminating 0 7m24s web-3 0/1 Terminating 0 7m25s web-3 0/1 Terminating 0 7m25s web-2 1/1 Terminating 0 7m31s web-2 0/1 Terminating 0 7m32s web-2 0/1 Terminating 0 7m33s web-2 0/1 Terminating 0 7m33s
注意:扩容时会根据设置自动创建久化存储资源(PVC)并关联到Pod,当缩容时,PVC不会同步删除。当再次扩容时;会自动绑定到之前的PVC上。
-
StatefulSets更新策略
更新策略由 StatefulSet API Object 的spec.updateStrategy
字段决定。这个特性能够用来更新一个 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。 RollingUpdate
滚动更新是 StatefulSets 默认策略。
OnDelete:当 StatefulSet 的 .spec.updateStrategy.type
设置为 OnDelete
时,它的控制器将不会自动更新 StatefulSet 中的 Pod。 用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 .spec.template
的变动作出反应
滚动更新:RollingUpdate
更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。 在没有声明 .spec.updateStrategy
时,RollingUpdate
是默认配置。 当 StatefulSet 的 .spec.updateStrategy.type
被设置为 RollingUpdate
时, StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。 它会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新前一个
-
StatefulSets删除
StatefulSet 同时支持级联和非级联删除。使用非级联方式删除 StatefulSet 时,StatefulSet 的 Pod 不会被删除。使用级联删除时,StatefulSet 和它的 Pod 都会被删除。
StatefulSet 永远不会删除和一个 Pod 相关联的 PersistentVolumes。 当你重建这个 StatefulSet 并且重新启动了Pod时,它原本的 PersistentVolume 会被重新挂载
非级联删除:Pod不会删除
#非级联删除statefulset kubectl delete statefulset web --cascade=orphan
查看状态:Pod信息,所有Pod依旧运行
级联删除:StatefulSet 和它的 Pod 都会被删除
#级联删除 kubectl delete statefulset web
查看状态:Pod逐步从Pod1->Pod0删除
三、总结
StatefulSet 是一种较常用的资源类型,能够稳定、有序的部署和扩缩Pod集合, 并为这些 Pod 提供持久存储和持久标识符。