k8s

OpenKruise介绍

简介

OpenKruise (官网: https://openkruise.io) 是CNCF(Cloud Native Computing Foundation) 的孵化项目。 它提供一套在 Kubernetes核心控制器 之外的扩展工作负载、应用管理能力。OpenKruise 提供的绝大部分能力都是基于 CRD 扩展来定义,它们不存在于任何外部依赖,可以运行在任意纯净的 Kubernetes 集群中。

核心能力

高级工作负载

通用工作负载能帮助你管理 stateless(无状态)、stateful(有状态)、daemon 类型和作业类的应用。它们不仅支持类似于 Kubernetes 原生 Workloads 的基础功能,还提供了如原地升级、可配置的扩缩容/发布策略、并发操作等。

其中,原地升级是一种升级应用容器镜像甚至环境变量的全新方式。它只会用新的镜像重建 Pod 中的特定容器,整个 Pod 以及其中的其他容器都不会被影响。因此它带来了更快的发布速度,以及避免了对其他 Scheduler、CNI、CSI 等组件的负面影响。

  • CloneSet - 无状态应用
  • Advanced StatefulSet - 有状态应用
  • Advanced DaemonSet - daemon 类型应用
  • BroadcastJob - 部署任务到一批特定节点上
  • AdvancedCronJob - 周期性地创建 Job 或 BroadcastJob

Sidecar 容器管理

OpenKruise 提供了多种通过旁路管理应用 sidecar 容器、多区域部署的方式。比如通过SidecarSet简化了Sidecar的注入, 并提供了sidecar原地升级的能力。另外, Kruise提供了增强的sidecar启动、退出的控制。

  • SidecarSet - 定义和升级你的 sidecar 容器
  • Container Launch Priority 控制sidecar启动顺序
  • Sidecar Job Terminator 当 Job 类 Pod 主容器退出后,Terminator Sidecar容器

多区域管理

它可以帮助你在一个 Kubernetes 集群中的多个区域上部署应用,比如不同的 node 资源池、可用区、机型架构(x86 & arm)、节点类型(kubelet & virtual kubelet)等。这里我们提供两种不同的方式:

  • WorkloadSpread - 旁路地分发 workload 创建的 pods
  • UnitedDeployment - 一个新的 workload 来管理多个下属的 workloads

增强运维能力

  • 原地重启 pod 中的容器
  • 指定的一批节点上拉取镜像
  • ResourceDistribution 支持 Secret、Configmaps 资源跨 Namespace 分发
  • PersistentPodState 保持Pod的一些状态,比如:"固定IP调度"
  • PodProbeMarker 提供自定义Probe探测的能力

应用安全防护

  • 保护 Kubernetes 资源及应用 pods 不被级联删除
  • PodUnavailableBudget - 覆盖更多的 Voluntary Disruption 场景,提供应用更加强大的防护能力

架构

file

API

所有 OpenKruise 的功能都是通过 Kubernetes API 来提供,包括很多CRD,资源对象中的特定标识(labels, annotations, envs 等)。

apiVersion: v1
kind: Namespace
metadata:
  labels:
    # 保护这个 namespace 下的 Pod 不被整个 ns 级联删除
    policy.kruise.io/delete-protection: Cascading

Manager

Kruise-manager 是一个运行 controller 和 webhook 中心组件,它通过 Deployment 部署在 kruise-system 命名空间中。Kruise-manager 会创建一些 webhook configurations 来配置哪些资源需要感知处理、以及提供一个 Service kruise-webhook-service 来给 kube-apiserver 调用。

Daemon

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

安装

使用helm安装的v1.7.2稳定版本。支持很多个feature-gate参数,详情请见:https://openkruise.io/zh/docs/installation 这里先默认安装。

helm repo add openkruise https://openkruise.github.io/charts/
helm repo update
# https://github.com/openkruise/charts/releases/download/kruise-1.7.2/kruise-1.7.2.tgz
helm install kruise openkruise/kruise --version 1.7.2 --set  manager.image.repository=openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/kruise-manager

file

原地升级

原地升级是 OpenKruise 提供的核心功能之一。目前支持原地升级的 Workload:CloneSetAdvanced StatefulSetAdvanced DaemonSetSidecarSetSidecarSet 的原地升级流程和其他 workloads 不太一样,比如它在升级 Pod 之前并不会把 Pod 设置为 not-ready 状态。因此,下文的内容并不完全适用于 SidecarSet

什么是原地升级

file

通过上图可以看到原地升级和重建升级的区别:

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

  • Pod 名字和 uid 发生变化,因为它们是完全不同的两个 Pod 对象(比如 Deployment 升级)
  • Pod 名字可能不变、但 uid 变化,因为它们是不同的 Pod 对象,只是复用了同一个名字(比如 StatefulSet 升级)
  • Pod 所在 Node 名字发生变化,因为新 Pod 很大可能性是不会调度到之前所在的 Node 节点的
  • Pod IP 发生变化,因为新 Pod 很大可能性是不会被分配到之前的 IP 地址的

原地升级 仍然复用同一个 Pod 对象,只是修改它里面的字段:

  • 可以避免如 调度、分配 IP、分配、挂载盘 等额外的操作和代价
  • 更快的镜像拉取,因为开源复用已有旧镜像的大部分 layer 层,只需要拉取新镜像变化的一些 layer
  • 当一个容器在原地升级时,Pod 中的其他容器不会受到影响,仍然维持运行

InPlaceIfPossible

这种 Kruise workload 的升级类型名为 InPlaceIfPossible,它意味着 Kruise 会尽量对 Pod 采取原地升级,如果不能则退化到重建升级。

以下的改动会被允许执行原地升级:

  • 更新 workload 中的 spec.template.metadata.*,比如 labels/annotations,Kruise 只会将 metadata 中的改动更新到存量 Pod 上。
  • 更新 workload 中的 spec.template.spec.containers[x].image,Kruise 会原地升级 Pod 中这些容器的镜像,而不会重建整个 Pod。
  • 从 Kruise v1.0 版本开始(包括 v1.0 alpha/beta),更新 spec.template.metadata.labels/annotations 并且 container 中有配置 env from 这些改动的 labels/anntations,Kruise 会原地升级这些容器来生效新的 env 值。

否则,其他字段的改动,比如 spec.template.spec.containers[x].envspec.template.spec.containers[x].resources,都是会回退为重建升级。

工作流程

file

  1. 更新pod,检查是否是原地升级。
  2. 如果是的话先更新pod status.conditions.status,把 Pod 设置为 not-ready 状态。
  3. 在pod的annotation中记录更新信息。
  4. 看是否设置了gracePeriodSeconds,如果设置了就等待,没有设置就更新pod信息。
  5. 如果老的pod存在preStophook脚本则执行该脚本。
  6. 停止老的容器。
  7. 拉取镜像,创建并启动新的容器,执行preStarthook脚本。
  8. 检查容器是否更新并运行。
  9. 在pod status中更新InPlaceUpdate conditions。
  10. 更新pod状态为ready。
  • 其中5,6步中,如果是镜像更新则有kubelet执行;如果是从metadata中获取的env值更新则有kruise-daemon执行。
  • 7,10步是由kubelet执行。
  • 其余步骤由kruise-manager执行。

多容器升级顺序控制

当你同时原地升级多个具有不同启动顺序的容器时,Kruise 会按照相同的权重顺序来逐个升级这些容器。

  • 对于不存在容器启动顺序的 Pod,在多容器原地升级时没有顺序保证。
  • 对于存在容器启动顺序的 Pod:
    • 如果本次原地升级的多个容器具有不同的启动顺序,会按启动顺序来控制原地升级的先后顺序。
    • 如果本地原地升级的多个容器的启动顺序相同,则原地升级时没有顺序保证。

查看pod的 apps.kruise.io/inplace-update-state这个annotation,只需要关注其中 containerBatchesRecord 来确保容器是被分为多批升级的。如果这个 Pod 在原地升级的过程中卡住了,你可以检查 nextContainerImages/nextContainerRefMetadata 字段,以及 preCheckBeforeNext 中前一次升级的容器是否已经升级成功并 ready 了。

使用要求

如果要使用 env from metadata 原地升级能力,你需要在安装或升级 Kruise chart 的时候打开 kruise-daemon(默认打开)和 InPlaceUpdateEnvFromMetadata(默认打开)两个 feature-gate。

virtual-kubelet 类型的 Node 节点,kruise-daemon 可能是无法在上面运行的,因此也无法使用 env from metadata 原地升级。

分类: k8s
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
最旧
最新 最多投票
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x