【问题标题】:Upgrade and Failure Domains in KubernetesKubernetes 中的升级和故障域
【发布时间】:2018-10-12 00:08:20
【问题描述】:

背景

我曾计划使用 Service Fabric(本地)进行服务和容器编排。但是,由于内部讨论,我正在给 Kubernetes 看一看。主要是因为它非常受欢迎。

Service Fabric 具有称为升级域和故障域的概念。 “域”是一组主机节点。

在推出应用服务或容器更新时使用升级域。 Service Fabric 通过一次只关闭一个升级域来确保升级服务/容器仍然可用。 (这些也用于更新 Service Fabric 群集软件本身。)

故障域以类似的方式工作。这个想法是,故障域是根据硬件故障组创建的。 Service Fabric 确保每个故障域中都有服务/容器实例在运行。 (在硬件故障期间留出正常运行时间。)

问题

当我在 Kubernetes 上查看文档和收听播客时,我没有看到任何这些概念。它似乎只是托管容器(Pod)。我听说过一些关于“调度”和“标签”的信息。但它似乎只是手动配置 pod 的方式。

应用程序升级和容错是在 Kubernetes 中手动完成的吗? (也许通过调度和/或标签)

或者我缺少什么功能?

【问题讨论】:

    标签: kubernetes azure-service-fabric


    【解决方案1】:

    “域”是一组主机节点。

    没那么简单,如果你说“‘域’是资源的逻辑分组”会更准确。

    要正确理解它,您必须首先孤立地理解大多数组件。我首先推荐这些读物:

    那么,我们可以从中得出几点:

    • 节点不是虚拟机,节点运行在 azure 虚拟机之上。

      它们通常具有 1:1 映射,但在某些情况下您可以具有 5:1 节点/VM 映射,例如当您安装本地开发集群时。

    • Azure 虚拟机具有更新域和故障域,Service Fabric 节点具有升级域和故障域

      尽管它们看起来相同,但它们也有不同:

      故障域:

      • VM 故障域是用于物理部署的隔离插槽,这意味着:电源、网络、磁盘等...它们受区域限制。
      • SF 故障域是用于应用程序部署的逻辑节点槽,这意味着,当 SF 将应用程序部署到节点时,它将分布在不同的故障域上,为了使它们可靠,大部分时间 FD 将映射到 VM 故障域,但在复杂的场景中,您可以将其映射到任何东西,例如,您可以将整个区域映射到单个 SF FD。

      .

      更新\升级域:

      • VM 更新域是关于 OS\Hardware 补丁和更新,单独的更新域将单独处理,不会同时更新,因此,当需要更新 OS 以关闭您的 VM 时,它们将更新域按域。更新域数量越少意味着更新期间将关闭更多机器。
      • SF 升级域使用与虚拟机更新域类似的方法,但侧重于服务和集群升级本身,每次降低每个 UD 的 UD,并在前一个 UD 成功时转移到下一个。
      • 在这两种情况下,您都可以将 Update\Upgrade 调整为在升级期间可以关闭多少个 vm\nodes\services 实例 (%)。因此,例如,如果您的服务在具有 5 个 UD 的集群上有 100 个实例,那么 SF 将一次更新 20 个服务,如果您将 UD 的数量增加到 10 个,例如,下降的实例数量将减少到 10 个实例,但是部署应用程序的时间会以同样的比例增加。

    基于此,您可以将 FD 和 UP 视为可靠部署插槽的矩阵,您拥有的越多,可靠性就会越高(通过权衡取舍,例如所需的更新时间)。以下示例取自 SF 文档:

    Service Fabric,开箱即用会尽最大努力将您的服务实例放在不同的 FD\UD 上,这意味着,如果可能,它们将位于不同的 FD\UD 上,否则它将找到另一个实例数量最少的实例正在部署的服务。

    关于 Kubernetes:

    在 Kubernetes 上,这些功能并不是开箱即用的,k8s 有zones 的概念,但是根据文档,它们受区域限制,不能跨区域。

    Kubernetes 会自动将复制控制器或服务中的 pod 分散到单区域集群中的节点(以减少故障的影响)。对于多区域集群,这种传播行为可以跨区域扩展(以减少区域故障的影响)。这是通过 SelectorSpreadPriority 实现的。

    这是一个尽力而为的布局,因此如果集群中的区域是异构的(例如,不同数量的节点、不同类型的节点或不同的 pod 资源要求),这可能会阻止您的 pod 跨区域均匀分布.如果需要,您可以使用同质区域(相同数量和类型的节点)来减少不均等传播的可能性。

    与FD不同,但概念非常相似。

    要实现与 SF 类似的结果,需要跨区域部署集群或将节点映射到 VM FD\UD,以便它们在 SF 上表现为节点。将标签添加到节点以识别这些域。您还需要在不同 FD 上的节点上创建 NodeType 标签,以便您可以将 pod 部署在分隔节点上。

    例如:

    • Node01: FD01 : NodeType=FrontEnd
    • Node02: FD02 : NodeType=FrontEnd
    • Node03: FD03 : NodeType=FrontEnd
    • Node04:FD01:NodeType=BackEnd
    • Node05:FD02:NodeType=BackEnd

    当您部署应用程序时,您应该使用affinity 功能将 POD 分配给节点,在这种情况下,您的服务将具有:

    • NodeType=FrontEnd必需的相似性
    • 首选 AntiAfinity 优于 ContainerName=[itself]

    通过这些设置,使用亲和和反亲和 k8s 将尝试将容器的副本\实例放在单独的节点上,并且节点将已经被 NoteType 标签分隔的 FD\zone 分隔,然后 k8s 将像 SF 一样处理滚动更新。

    因为优先考虑反亲和性规则,k8s 将尽力平衡这些节点,如果没有可用的有效节点,它将开始在已经包含相同容器实例的节点上添加更多实例,

    结论

    这是一些额外的工作,但与目前在其他解决方案中使用的没有太大区别。 这里主要关注的是在 FD\Zones 上配置节点,在您将节点放置在正确的 FD 上之后,其余的将顺利进行。

    在 SF 上,您在 Azure 上部署集群时不必担心这一点,但如果您从头开始,这是一项艰巨的工作,甚至比 k8s 还要大。

    注意:如果您使用 AKS,它将跨可用性集(指定 VM 容错域和更新域的集)分布节点。目前,根据this post,AKS 不为您提供区域分发,因此如果您需要此级别的分发,则必须从头开始。

    【讨论】:

      【解决方案2】:

      来自文档123

      • 进程健康检查 最简单的健康检查形式就是进程级别的健康检查。 Kubelet 不断询问 Docker 守护进程,容器进程是否仍在运行,如果没有,则重新启动容器进程。在您目前运行的所有 Kubernetes 示例中,实际上已经启用了这种健康检查。它适用于在 Kubernetes 中运行的每个容器

      • Kubernetes 支持用户实现的应用程序健康检查。这些检查由 Kubelet 执行,以确保您的应用程序按照您提供的“正确”定义正确运行。

      目前,您可以选择三种类型的应用程序运行状况检查:

      1. HTTP 健康检查 - Kubelet 将调用网络挂钩。如果它返回 200 到 399 之间,则认为成功,否则失败。在此处查看运行状况检查示例。
      2. Container Exec - Kubelet 将在您的容器内执行命令。如果它以状态 0 退出,它将被视为成功。在此处查看运行状况检查示例。
      3. TCP Socket - Kubelet 将尝试为您的容器打开一个套接字。如果它可以建立连接,则认为容器健康,如果不能,则认为容器失败。 在所有情况下,如果 Kubelet 发现故障,容器就会重新启动。

        • 节点运行状况检查

      如果 [节点的] Ready 条件的状态为“未知”或“假”的时间超过 pod-eviction-timeout,则将参数传递给 kube-controller-manager 和所有的 Pod节点由节点控制器安排删除。默认驱逐超时持续时间为五分钟。在某些情况下,当节点无法访问时,apiserver 无法与其上的 kubelet 通信。删除 pod 的决定无法传达给 kubelet,直到它与 apiserver 重新建立通信。同时,计划删除的 pod 可能会继续在分区节点上运行

      • 应用升级

      用户希望应用程序始终可用,并且开发人员希望每天多次部署新版本的应用程序。在 Kubernetes 中,这是通过滚动更新完成的。滚动更新通过使用新的 Pod 实例增量更新 Pod 实例,允许 Deployments 的更新在零停机时间的情况下进行。新的 Pod 将安排在有可用资源的节点上。

      【讨论】:

        【解决方案3】:

        这些抽象目前在 Kubernetes 中不存在,尽管通常可以以自动化方式实现所需的行为。

        kubernetes 的元模型涉及代理(称为控制器和操作员)持续监视集群上的事件和配置,并逐渐将集群状态与控制器的声明性配置相协调。托管 Pod 的节点的突然丢失将导致与丢失的 Pod 对应的 IP 从服务和 ReplicationControllers 中删除,以便这些 Pod 在其他节点上启动新版本,否则会确保满足协同和反调度约束。

        同样,应用程序升级通常通过对 Deployment 的更改来进行,这会导致新的 Pod 被调度,而旧的 Pod 则以自动、渐进的方式被取消调度。

        现在可以使用 CustomResourceDefinitions 自定义声明性配置,因此该模型是可扩展的。底层原语和机制可供某人引入由自定义 Operator 管理的顶级声明性抽象,例如 FailureDomains 和 UpgradeDomains。

        kube 生态系统如此庞大且发展如此迅速,以至于可能会出现类似的东西,并且也可能会遇到竞争对手的概念。

        考虑采用 Kubernetes 的工厂所有者的底线是,Kubernetes 实际上仍然是一个工具匠的世界。有大量的工具,以及同样大量的未完成产品。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-27
          • 2021-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多