OpenKruise :Kubernetes背后的托底

本文分享自华为云社区《OpenKruise核心能力和工作原理》,作者:可以交个朋友。

一、 诞生背景

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. 在升级之前,确保已经了解新版本的不兼容变化。
  2. 如果你要重置之前旧版本上用的参数或者配置一些新参数,建议在 helm upgrade 命令里加上 --reset-values。
  3. 如果你在将 Kruise 从 0.x 升级到 1.x 版本,你需要为 upgrade 命令添加 --force 参数,其他情况下这个参数是可选的。

 

点击关注,第一时间了解华为云新鲜技术~

 

热门相关:霍先生结婚吧   霍先生结婚吧   锦衣当国   锦绣医妃之庶女凰途   霸宠天下:腹黑帝君妖娆后