乐趣区

关于kubernetes:k8s集群StatefulSets的Pod优雅调度问题思考

k8s 集群 StatefulSets 的 Pod 优雅调度问题思考?

考点之你能解释一下为什么 k8s 的 StatefulSets 须要 VolumeClaimTemplate 嘛?
考点之简略形容一下 StatefulSets 对 Pod 的编排调度过程?
考点之针对线上 StatefulSet 的 Pod 缩容故障无奈失常缩容的状况,你能灰度剖析一下嘛?
考点之聊聊什么是 StatefulSet 的分区滚动更新吧?什么场景须要应用分区更新?
考点之 StatefulSet 提供优雅稳固的存储,然而线上告警 StatefulSet Pod 从新调度后数据失落?

囧么肥事 - 胡言乱语

你能解释一下为什么 k8s 的 StatefulSets 须要 VolumeClaimTemplate 嘛?

对于 k8s 集群来说有状态的正本集都会用到 长久存储

Deployment中的 Pod template 里定义的存储卷,是 基于模板配置调度 所有正本集共用一个存储卷,数据是雷同的。

StatefulSet职责是治理 有状态利用 ,所以它治理的每个Pod 都要自已的 专有存储卷,它的存储卷就不能再用 Pod 模板来创立。

所以 StatefulSets 须要一种新形式来为管辖的 Pod 调配存储卷。

就这样 VolumeClaimTemplate 来了,k8sStatefulSets 设置了 VolumeClaimTemplate,也就是 卷申请模板

说了为什么须要它,那么 VCT 到底是什么呢?

VolumeClaimTemplate:基于 动态或动静 地 PV 供应形式为 Pod 资源提供 专有且固定的存储,它会为每个 Pod 都生成不同的PVC,并且绑定 PV,实现每个 Pod 都有本人独立专用的存储卷。

简略形容一下 StatefulSets 对 Pod 的编排调度过程?

StatefulSets 提供了 有序且优雅的部署和扩缩保障

SS 是如何优雅部署和扩缩的呢?

对于蕴含 N 个 正本的 StatefulSet

当部署 Pod 时,它们是顺次创立的,程序为 `0..N-1`。当删除 Pod 时,它们是逆序终止的,程序为 `N-1..0`。在将缩放操作利用到 Pod 之前,它后面的所有 Pod 必须是 Running 和 Ready 状态。在 Pod 终止之前,所有的继任者必须齐全敞开

创立或扩容过程,以 Nginx 举例

定义正本数 replicas=3

SS 会创立 3 个 Pod
调配有序序号
ng-0, ng-1, ng-2

SS 严格执行部署或调度程序,按序部署
ng-0 开始部署...
ng-0 进入 Running 和 Ready 状态

SS 检测 ng-0 部署状态
确定 ng-0,合乎 Running 和 Ready 状态

ng-1 开始部署
ng-1 进入 Running 和 Ready 状态

SS 检测 ng-0 和 ng-1 部署状态
确定 ng-0 和 ng-1 都合乎 Running 和 Ready 状态
才会执行 ng-2 部署

假如此时 ng-0 产生故障
那么 ng-2 会阻塞,期待 ng-0 重新部署实现

ng-2 开始部署
ng-2 进入 Running 和 Ready 状态

相似,StatefulSet 进行缩容跟扩容整体规定是一样的,只不过缩容时,终止程序和创立程序 相同

依照 ng-2, ng-1, ng-0 的程序进行缩容操作。ng-2没有齐全进行和删除前,ng- 1 不会进行终止操作。

留神:如果 SS 在缩容过程中,有些 Pod 产生了故障,那么终止会进入阻塞,期待产生故障的 Pod 从新调度,进入 Running 和 Ready 状态之后才会继续执行 SS 缩容。

针对线上 StatefulSet 的 Pod 缩容故障无奈失常缩容的状况,你能灰度剖析一下嘛?

为什么缩容无奈失常执行?

StatefulSet 执行缩容操作,须要保障管辖范畴内的 Pod 处于衰弱状态 。如果某些 Pod 产生故障,则缩容会陷入阻塞,无奈继续执行。

仅当 StatefulSet 期待到所有 Pod 都处于运Running 和 Ready 状态后才可持续进行缩容操作。

理解完为什么缩容无奈执行,那么再聊聊可能导致无奈失常缩容起因都有哪些?

如果 spec.replicas 大于 1,Pod 正本数量大于 1,Kubernetes 无奈间接断定 Pod 不衰弱的起因。

Pod 不衰弱可能是因为 永久性故障造成也可能是瞬态故障

永久性故障

如果该 Pod 不衰弱是因为永久性故障导致,则在不纠正该故障的状况下进行缩容可能会导致 StatefulSet 成员 Pod 数量低于应失常运行的正本数。这种状态兴许会导致 StatefulSet 不可用。

瞬态故障

瞬态故障可能是 节点降级或保护而引起的节点重启 造成的。

如果因为瞬态故障而导致 Pod 不衰弱,个别状况下,Pod 最终会再次变为可用,然而瞬态谬误也可能会烦扰 你对 StatefulSet 的扩容 / 缩容操作。

一些分布式数据库在同时有节点退出和来到时会遇到问题。

在这些状况下,最好是在 利用级别进行剖析扩缩操作的状态,并且只有在确保 Stateful 利用的集群是齐全衰弱时才执行扩缩操作。

聊聊什么是 StatefulSet 的分区滚动更新吧?什么场景能够应用分区更新?什么状况分区更新会生效?

先说一下 StatefulSet 的更新策略

StatefulSet.spec.updateStrategy 字段能够配置和禁用掉主动滚动更新 Pod 的容器、标签、资源申请或限度、以及注解。

spec.updateStrategy 有两个容许的值:RollingUpdateOnDelete

RollingUpdate 更新策略

对 StatefulSet 中的 Pod 执行主动的滚动更新。这是默认的更新策略

OnDelete更新策略

StatefulSet 将不会自动更新 StatefulSet 中的 Pod

当 StatefulSet 的 .spec.template 设置呈现变动
用户必须手动删除 Pod 以便让控制器创立新的 Pod

滚动更新

StatefulSet.spec.updateStrategy.type 被设置为 RollingUpdate 时,属于默认滚动更新策略,这个时候如果 template 发生变化,StatefulSet 控制器会主动发动调度,进行删除和重建 StatefulSet 中的每个 Pod。它将依照与 Pod 终止雷同的程序(从最大序号到最小序号)进行,每次更新一个 Pod。

Kubernetes 管制面会等到被更新的 Pod 进入 Running 和 Ready 状态,而后再更新其前身 Pod。

如果你设置了 .spec.minReadySeconds(最短就绪秒数),管制面在 Pod 就绪后会额定期待肯定的工夫再执行下一步。

接下来进入主题什么是分区滚动更新?

分区滚动更新是滚动更新策略中的一个非凡场景,StatefulSet 管制肯定范畴内的 Pod 进行滚动更新,调度为新版本 Pod 运行,而范畴外的 Pod 持续维持老版本运行。

能够了解为,学校 16 个班级,校长告诉说:” 明天最初 5 个班级留下来打扫卫生 ”

通过申明 .spec.updateStrategy.rollingUpdate.partition 的形式,RollingUpdate 更新策略能够实现分区。

如果申明了一个分区,当 StatefulSet 的 .spec.template 被更新时

所有序号大于等于该分区序号的 Pod 都会被更新
所有序号小于该分区序号的 Pod 都不会被更新

分区更新,就是进行 分段解决

假如原来有 5 个 Pod
ng-0
ng-1
ng-2
ng-3
ng-4

SS 滚动更新
ng-4 更新
ng-3 更新
ng-2 更新
ng-1 更新
ng-0 更新

如果指定 partition=2
那么 SS 执行滚动更新时
ng-4 更新
ng-3 更新
ng-2 更新
ng-1 不更新
ng-0 不更新

须要留神的是,分区范畴外的 Pod,即便他们被删除或是从新调度,也会根据 之前的旧版本进行重建,不会依赖以后最新版本重建。

此外,如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于它的 .spec.replicas,对它的 .spec.template 的更新将不会传递到它的 Pod,此时所谓分区更新将失去意义。

分区更新利用场景?

在大多数状况下,你不须要应用分区,但如果你心愿进行 阶段式更新、执行金丝雀或执行分阶段上线,则分区更新会十分有用。

StatefulSet 提供优雅稳固的存储,然而线上告警 StatefulSet Pod 从新调度后数据失落?

到底是什么状况呢?

咱们都晓得 k8s 中当 StatefulSet 或者它治理的 Pod 被删除时并 不会删除关联的卷 ,当从新调度实现后,新 Pod 应该会 挂载原 PV,持续应用上一个 Pod 的数据。

好事来了,本应该持续应用原 PV,大快人心,可是线上告警发现 PV 长久卷无奈应用,导致数据失落。咦,失联了???

k8s 删除 StatefulSet 治理的 Pod 并不会删除关联的 PV 卷,这是为了确保你有机会从新调度 Pod 之后持续应用原 PV 卷,或者在删除卷之前从卷中复制数据,保证数据不会失落。当一个 Pod 被调度(从新调度)到节点上时,它的 volumeMounts 会挂载与其 PVC 相关联的 PV。

删除 StatefulSet 和 Pod 尽管不会删除关联的 PV 卷,然而删除 PVC 就不肯定了,问题就呈现在这里,在 Pod 来到终止状态后删除 PVC,可能会触发删除背地的 PV 长久卷,具体触发策略要取决配置的存储类和回收策略。

正告:⚠️ 永远不要假设在 PVC 删除后依然可能拜访卷

正告:⚠️ 删除 PVC 时要审慎,因为这可能会导致数据失落

获取更多干货(MySQL、K8S),欢送关注微信公众号:囧么肥事


Kubernetes 举荐学习书

Kubernetes 权威指南 PDF
链接:https://pan.baidu.com/s/11huL… 提取码:sa88

k8s 系列所有问题更新记录:GitHub Gitee

退出移动版