写点什么

OpenKruise :Kubernetes 背后的托底

  • 2024-01-24
    福建
  • 本文字数:3269 字

    阅读完需:约 11 分钟

一、 诞生背景


Kubernetes 自身提供的应用部署管理功能,无法满足大规模应用场景的需求,例如应用发布时的原地升级策略,流式扩容,缩容顺序控制等等。所以 OpenKruise 的出现弥补了 Kubernetes 在应用部署、升级、防护、运维等领域的不足。



二、 OpenKruise 介绍


核心能力介绍,帮助快速入门 openkruise。


2.1 架构预览



OpenKruise 的功能都是通过 Kubernetes API 来提供的。


  • Kruise-manager :运行着 controller 和 webhook 的中心组件,它通过 Deployment 部署在 kruise-system 命名空间中,同样它们之间采用 leader-election 的方式选主,同一时间只有一个提供服务,达到高可用的目的。除了 controller 之外,kruise-controller-manager-xxx 中还包含了针对 Kruise CRD 以及 Pod 资源的 admission webhook。Kruise-manager 会创建 webhook configurations 来配置哪些资源需要感知处理、以及提供一个 Service 来给 kube-apiserver 调用。


  • kruise-daemon:这是从 Kruise v0.8.0 版本开始提供的一个新的 daemon 组件。它通过 DaemonSet 部署到每个 Node 节点上,提供镜像预热、容器重启等功能。


三、 核心能力


OpenKruise 是一个基于 Kubernetes 的扩展套件,主要聚焦于云原生应用的自动化,比如 部署、发布、运维以及可用性防护。OpenKruise 提供的绝大部分能力都是基于 CRD 扩展来定义,它们不存在于任何外部依赖,可以运行在任意纯净的 Kubernetes 集群中。核心能力包括:


  • 增强版本的 Workloads: 比如 CloneSet、Advanced StatefulSet、Advanced DaemonSet、BroadcastJob 等。它们不仅支持类似于 Kubernetes 原生 Workloads 的基础功能,还提供了如原地升级、可配置的扩缩容/发布策略、并发操作等。


  • 应用的旁路管理: OpenKruise 提供了多种通过旁路管理应用 sidecar 容器、多区域部署的方式,“旁路” 意味着你可以不需要修改应用的 Workloads 来实现它们。赋予单一 workload 的多区域和弹性部署的能力。


  • 高可用性防护:目前它可以保护你的 Kubernetes 资源不受级联删除机制的干扰,包括 CRD、Namespace、以及几乎全部的 Workloads 类型资源。


  • 高级的应用运维能力:OpenKruise 也提供了很多高级的运维能力来帮助你更好地管理应用。你可以通过 ImagePullJob 来在任意范围的节点上预先拉取某些镜像,或者指定某个 Pod 中的一个或多个容器被原地重启。


以下将对常用场景功能进行介绍。


3.1 丰富的调度策略


WorkloadSpread 能够将 workload 的 Pod 按一定规则分布到不同类型的 Node 节点上,赋予单一 workload 多区域部署和弹性部署的能力。


常见的一些规则包括:


  • 水平打散(比如按 host、az 等维度的平均打散)。


  • 按指定比例打散(比如按比例部署 Pod 到几个指定的 az 中)。


  • 带优先级的分区管理,比如:优先部署到 ecs,资源不足时部署到 eci;优先部署固定数量个 pod 到 ecs,其余到 eci;定制化分区管理,比如:控制 workload 部署不同数量的 Pod 到不同的 cpu 架构上;确保不同的 cpu 架构上的 Pod 配有不同的资源配额。


每一个 WorkloadSpread 定义多个区域(定义为 subset), 每个 subset 对应一个 maxReplicas 数量。WorkloadSpread 利用 Webhook 注入 subset 定义的域信息,同时控制 Pod 的扩缩容顺序。


3.2 缩容顺序控制


pod 的删除场景可通过 PodDeletionCost 进行控制: 较小 pod-deletion cost < 较大 pod-deletion cost

controller.kubernetes.io/pod-deletion-cost 是从 Kubernetes 1.21 版本后加入的 annotation,Deployment/ReplicaSet 在缩容时会参考这个 cost 数值来排序。


  • 用户可以把这个 annotation 配置到 pod 上,值的范围在 [-2147483647, 2147483647]。 它表示这个 pod 相较于同个 CloneSet 下其他 pod 的 “删除代价”,代价越小的 pod 删除优先级相对越高。 没有设置这个 annotation 的 pod 默认 deletion cost 是 0。


  • CloneSet 已经支持该特性。其他 native workload 需 kubernetes version >= 1.21。且 1.21 版本需要显式开启 PodDeletionCost feature-gate,自 1.22 起默认开启。


在 openkruise 中,我们可以配置 WorkloadSpread,借助 APIServer PodDeletionCost 特性,WorkloadSpread 利用 webhook 向 Pod 注入域规则,从而控制缩容顺序。


3.3 指定 Pod 缩容


当一个 CloneSet 被缩容时,支持用户指定一些 Pod 来删除。这对于 StatefulSet 或者 Deployment 来说是无法实现的,因为 StatefulSet 要根据序号来删除 Pod,而 Deployment/ReplicaSet 目前只能根据控制器里定义的排序来删除。


CloneSet 允许用户在缩小 replicas 数量的同时,指定想要删除的 Pod 名字。参考下面这个例子:


apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
spec:
# ...
replicas: 4
scaleStrategy:
podsToDelete:
- sample-9m4hp
复制代码


当控制器收到上面这个 CloneSet 更新之后,会确保 replicas 数量为 4。如果 podsToDelete 列表里写了一些 Pod 名字,控制器会优先删除这些 Pod。 对于已经被删除的 Pod,控制器会自动从 podsToDelete 列表中清理掉。


如果你只把 Pod 名字加到 podsToDelete,但没有修改 replicas 数量,那么控制器会先把指定的 Pod 删掉,然后再扩一个新的 Pod。


3.4、原地升级


原地升级是 OpenKruise 提供的核心功能之一。目前支持原地升级的 Workload:


  • CloneSet

  • Advanced StatefulSet

  • Advanced DaemonSet

  • SidecarSet


当我们要升级一个存量 Pod 中的镜像时,这是 重建升级 和 原地升级 的区别:



重建升级时我们要删除旧 Pod、创建新 Pod:


  • Pod 名字和 uid 发生变化,因为它们是完全不同的两个 Pod 对象(比如 Deployment 升级)


  • Pod 名字可能不变、但 uid 变化,因为它们是不同的 Pod 对象,只是复用了同一个名字(比如 StatefulSet 升级)


  • Pod 所在 Node 名字发生变化,因为新 Pod 很大可能性是不会调度到之前所在的 Node 节点的


  • Pod IP 发生变化,因为新 Pod 很大可能性是不会被分配到之前的 IP 地址的


但是对于原地升级,我们仍然复用同一个 Pod 对象,只是修改它里面的字段。因此:


  • 可以避免如 调度、分配 IP、分配、挂载盘 等额外的操作和代价


  • 更快的镜像拉取,因为开源复用已有旧镜像的大部分 layer 层,只需要拉取新镜像变化的一些 layer


  • 当一个容器在原地升级时,Pod 中的其他容器不会受到影响,仍然维持运行


3.5 镜像预热


NodeImage 和 ImagePullJob 是从 Kruise v0.8.0 版本开始提供的 CRD。


Kruise 会自动为每个 Node 创建一个 NodeImage,它包含了哪些镜像需要在这个 Node 上做预热。


用户能创建 ImagePullJob 对象,来指定一个镜像要在哪些 Node 上做预热。



注意,NodeImage 是一个偏底层的 API,一般只在你要明确在某一个节点上做一次预热的时候才使用,否则你都应该使用 ImagePullJob 来指定某个镜像在一批节点上做预热。


四、安装部署 &升级


从 v1.0.0 (alpha/beta) 开始,OpenKruise 要求在 Kubernetes >= 1.16 以上版本的集群中安装和使用。

安装: 推荐使用 helm 方式进行安装


# 首先添加helm仓库
$ helm repo add openkruise https://openkruise.github.io/charts/
$ helm repo update
# 安装指定版本,1.5.0为当前最新的stable版本
$ helm install kruise openkruise/kruise --version 1.5.0
复制代码


如果不想使用默认的参数进行安装,可以手动下载 chart 包进行定制化安装,例如修改 resources 限制或者配置 feature-gates,chart 包下载地址参考:https://openkruise.github.io/charts/


升级: 通过 helm 方式升级


# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/
# [Optional]
$ helm repo update
# Upgrade to the latest version.
$ helm upgrade kruise openkruise/kruise --version 1.5.0 [--force]
复制代码


  1. 在升级之前,确保已经了解新版本的不兼容变化。


  1. 如果你要重置之前旧版本上用的参数或者配置一些新参数,建议在 helm upgrade 命令里加上 --reset-values。


  1. 如果你在将 Kruise 从 0.x 升级到 1.x 版本,你需要为 upgrade 命令添加 --force 参数,其他情况下这个参数是可选的。


文章转载自:华为云开发者联盟

原文链接:https://www.cnblogs.com/huaweiyun/p/17982633

体验地址:http://www.jnpfsoft.com/?from=001

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
OpenKruise :Kubernetes背后的托底_Kubernetes_不在线第一只蜗牛_InfoQ写作社区