• Karmada 1.3 新特性:基于污点的故障迁移


    Karmada 在最近发布 v1.3.0 中更新了很多的新特性。其中对应用跨集群故障迁移功能进行了重新设计,实现了基于污点的故障驱逐机制,并提供平滑的故障迁移功能,可以有效保障服务迁移过程的连续性(不断服)。设计理念源于 K8s 的污点容忍机制,对于熟悉 K8s 的用户来说并没有过多的学习成本,很容易就能理解 Karmada 的 failover 的原理。Karmada 的控制器拥有众多的组件,每个组件各司其职。在 Karmada 原有的这套高度解耦的构架下很优雅地实现了 failover 的功能。

    故障转移依赖 cluster-controller、cluster-stauts-controller、taint-manager、scheduler、graceful-eviction、webhook 等多个控制器协同完成故障迁移流程,其中 taint-manager 是全新的组件,它是其中的重要一环,它决定是否驱逐工作负载。我们可以把整个流程可以分为:“集群故障判定”,“负载预驱逐”,“重新调度”,“清理冗余负载”。

    cluster-status 控制器来判断集群的健康状态,如果集群被判定为故障集群后,cluster 控制器会将集群标记 `effect` 为 “NoExecute” 的污点,随后 taint-manager 控制器根据容忍机制开始驱逐该该集群上的工作负载,最后调度器将重新调度被驱逐的工作负载到候选集群上。如果开启了优雅驱逐的特性,graceful-eviction 控制器会从队列中执行优雅驱逐的 task。

    01

    集群的
    健康状态

    在 Karmada 中,无论是 Push 还是 Pull 模式的 member 集群,都是由 cluster status 控制器持续间隔时间来探测 cluster 是否健康,并将状态信息在 `cluster.status.condition` 中进行更新。集群状态的 condition 为 `Ready`, 每次检测集群的隔间时间为 10 秒,可以通过 --cluster-status-update-frequency 的 flag 来设置。集群 `Ready` 的状态为 false 可以分为两种情况:

    • ClusterNotReachableReason: 集群在一个时间周期内请求没有响应。

    • ClusterNotReady:集群请求正常响应,在一个时间周期内健康检测的 endpoint 响应不正常。

    相应的时间周期我们可以通过 --cluster-failure-threshold 的 flag 进行设置,默认为 30 秒。只有当以上两种请求都能正常响应,我们才认为集群是健康的状态。下面是一个不健康的集群的案例:

    ​​​​​​​

    Status:  Conditions:    Last Transition Time:  2022-10-31T03:36:08Z    Message:               cluster is not reachable    Reason:                ClusterNotReachable    Status:                False    Type:                  Ready

    02

    集群
    污点标记

    目前 failover 的功能还处于 alpha 的阶段,想要使用该功能可以通过 `--feature-gates=Failover=true` flag 来开启。在 Karmada 中,集群的污点标记是自动的,cluster 的控制器会根据 cluster 的 condition 来为 cluster 标记污点。根据集群的状态可以分为下面几种类型的污点:

    • 当集群的 `Ready` 的 condition 的状态为 "False" 时:

    key: cluster.karmada.io/not-readyeffect: NoSchedule
    • 当集群的 `Ready` 的 condition 的状态为 "Unknown" 时:

    key: cluster.karmada.io/unreachableeffect: NoSchedule

    以上的污点并不会被 taint-manager 处理,它只会处理带有 `effect` 为`NotExecute`污点的集群。为了增加集群容错的时间,集群在处于 `NoSchedule` 一定时间后,才会被设置为 `NoExecute`。可以通过 `--failover-eviction-timeout` 来设置时间间隔,默认时间为 5 分钟。

    • 当集群被移除的时候,也会被设置为以下的污点:

    key: cluster.karmada.io/terminatingeffect: NoSchedule

    03

    集群
    污点容忍

    taint-manager 是整个功能关键组件,当集群被标记 `effect` 为 `NoExecute` 污点后,并不会立马驱逐该集群上的工作负载。它实现了污点容忍的机制,它会根据该集群的 `RB`/`CRB` 资源上设置的容忍参数进行判断,具体可以分为三种情况:

    • 需要立马驱逐:没有设置污点容忍或者没有容忍时间。

    • 永不驱逐:容忍了所有的污点。

    • 一定时间后进行驱逐:karmada-webhook 为每一个 PropagationPolicy/ClusterPropagationPolicy 自动设置默认的容忍时间,默认为 10 分钟。可以通过 `--default-not-ready-toleration-seconds` 和 `--default-unreachable-toleration-seconds`  flag 自定义容忍时间。

    apiVersion: policy.karmada.io/v1alpha1kind: PropagationPolicymetadata:  name: nginx-propagation  namespace: defaultspec:  placement:    clusterTolerations:    - effect: NoExecute      key: cluster.karmada.io/not-ready      operator: Exists      tolerationSeconds: 600    - effect: NoExecute      key: cluster.karmada.io/unreachable      operator: Exists      tolerationSeconds: 600  resourceSelectors:  - apiVersion: apps/v1    kind: Deployment    name: nginx    namespace: default

    04

    重新调度

    被驱逐的资源重新调度的流程,还是由 scheduler 来执行, taint-manager 在确定故障集群满足驱逐条件后,会在 RB/CRB 资源中把污点集群从可用集群列表中移除。Scheduler 控制器会重新触发调度流程。不过在 scheduler 中新增了 taint_toleration 插件,由这个插件来控制资源能否被污点集群所容忍。除此之外,还需要满足以下两点限制条件:

    • 重新调度的资源,还是需要满足传播策略的限制,例如:ClusterAffinity 或者 SpreadConstraints。

    • 在故障迁移整个过程中,之前已经被调度到 Ready 集群的资源会被保留。

    05

    优雅驱逐

    在真实场景中,如果当集群为判断为故障集群,应用还没有被迁移到可用集群就被删除了,可能会造成服务不可用,这对用户的体验上是不友好的。为了避免这个问题,Karmada 设计了优雅驱逐功能,整个过程可以保障在驱逐过程中业务不中断,让用户无感知。目前这个功能还处于 alpha 的阶段,需要通过 `-–GracefulEviction=true`  flag 开启。优雅驱逐由一个新的控制器 graceful-eviction 来完成的,它的执行过程可以分为:

    • taint-manager 通过污点容忍机制确定需要驱逐的应用,将创建一个 GracefulEviction 的 task,这个 task 将设置到 RB/CRB 的 `spec.GracefulEvictionTasks` 队列中。

    • scheduler 执行了重新调度的流程,在候选集群中选择集群去调度驱逐的工作负载。

    • graceful-eviction controller 确定了重新调度结果后,并检查资源的健康状态。在超过间隔时间后才将故障集群资源移除。这个间隔时间可以通过 `--graceful-eviction-timeout` 时间设置,默认 10 分钟。最后将这个 task 从队列移除。

    06

    对比 V1.3
    之前的故障迁移

    在 Karmada 1.3 版本之前的 failover 功能,只依赖了 cluster-status 和 scheduler 两个控制器就完成了整个流程。Schduler 监听到 cluster 状态为 NotReady 后,就启动了重调度的流程。启动的时机取决于 cluster-status 的状态判断,从这个过程中我们可以看出它并没有任何的集群容错能力,这对于真实的生产环境可能会造成频繁跨集群迁移带来的诸多风险。

    Karmada 基于污点的优雅驱逐机制的设计得非常合理,也非常符合 Karmada 当前的架构。不过目前还处于一个 alpha 的阶段,还需要一段时间来检验功能可靠性。


     本文作者 

    陈文

    现任「DaoCloud 道客」 云原生开发工程师


    参考资料:

    [1] https://karmada.io/docs/userguide/failover/#concept
    [2] https://bbs.huaweicloud.com/blogs/374327
    [3] https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/

  • 相关阅读:
    React Swiper.js使用(详细版)3D聚焦特效,自定义导航按钮等
    C++Qt开发——事件处理函数
    SpringCloud之NamedContextFactory
    为什么 conda 不能升级 python 到 3.12
    M4 tm4c1294单片机软件调式总结
    【算法设计zxd】第5章分治法
    U2Net 网络结构详解
    了解如何使用 Node.js 构建微服务
    Maven与IDEA版本兼容问题以及配置
    数据库的事务、并发一致性、封锁
  • 原文地址:https://blog.csdn.net/DaoCloud_daoke/article/details/127687730