作者:立衡

前语

OpenKruise 是阿里云开源的云原生使用自动化办理套件,也是当时托管在 Cloud Native Computing Foundation (CNCF) 下的孵化项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部出产环境大规模使用的依据 Kubernetes 之上的规范扩展组件,也是紧贴上游社区规范、适应互联网规模化场景的技术理念与最佳实践。

OpenKruise:

github.com/openkruise/…

OpenKruise 在 2023.3.31 发布了最新的 v1.4 版别(ChangeLog [ 1] ),新增 Job Sidecar Terminator 重磅功用,本文将对新版别做全体的概览介绍。

01 重要更新

  • 为了方便大家运用 Kruise 增强才能,默许翻开了一些安稳的才能,如下:ResourcesDeletionProtection,WorkloadSpread,PodUnavailableBudgetDeleteGate,InPlaceUpdateEnvFromMetadata, StatefulSetAutoDeletePVC,PodProbeMarkerGate。上述才能大部分是需求特别配置才会收效的,所以默许翻开一般不会对存量集群形成影响,假如有一些特性不想运用,能够在晋级时关闭。
  • Kruise-Manager leader 选举方法从 configmaps 搬迁为 configmapsleases,为后面搬迁到 leases 方法做预备,别的,这是官方供给的滑润晋级的方法,不会对存量的集群形成影响。

02 Sidecar 容器办理才能:Job Sidecar Terminator

在 Kubernetes 中关于 Job 类型 Workload,人们通常期望当主容器完结任务并退出后,Pod 进入已完结状况。但是,当这些 Pod 拥有 Long-Running Sidecar 容器时,因为 Sidecar 容器在主容器退出后无法自行退出,导致 Pod 一直无法进入已完结状况。

面对这个问题,社区的常见处理方案一般都需求对 Main 和 Sidecar 进行改造,两者经过 Volume 共享来实现 Main 容器退出之后,Sidecar 容器完结退出的效果。

社区的处理方案能够处理这个问题,但是需求对容器进行改造,尤其关于社区通用的 Sidecar 容器,改造和维护的成本太高了。

为此,咱们在 Kruise 中参加了一个名为 SidecarTerminator 的控制器,专门用于在此类场景下,监听主容器的完结状况,并选择适宜的机遇终止掉 Pod 中的 sidecar 容器,而且无需对 Main 和 Sidecar 容器进行侵入式改造。

运转在一般节点的 Pod

关于运转于一般节点的 Pod(常规 Kubelet),运用该特性十分简单,用户只需求在要在方针 sidecar 容器中增加一个特别的 env 对其进行标识,控制器会在恰当的机遇利用 Kruise Daemon 供给的 CRR 的才能,将这些 sidecar 容器终止:

kind: Job
spec:
  template:
    spec:
      containers:
        - name: sidecar
          env:
            - name: KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT
              value: "true"
        - name: main
... ...

运转在虚拟节点的 Pod

关于一些供给 Serverless 容器的平台,例如**ECI [ 2] **或许**Fargate [ 3] **,其 Pods 只能运转于**Virtual-Kubelet [ 4] **之类的虚拟节点。但是,Kruise Daemon 无法部署和作业在这些虚拟节点之上,导致无法运用 CRR 才能将容器终止。但幸运地是,咱们能够借助原生 Kubernetes 供给的 Pod 原地晋级机制来达到相同的目的:只需求结构一个特别镜像,这个镜像的唯一效果便是当被拉起后,会快速地主动退出,这样一来,只需求在退出 sidecar 时,将原本的 sidecar 镜像替换为快速退出镜像,即可达到退出 sidecar 的目的。

过程一:预备一个快速退出镜像

  • 该镜像只需求具备十分简单的逻辑:当其被拉起后,直接退出,且退出码为 0。
  • 该镜像需求兼容原 sidecar 镜像的 commands 和 args,以防容器被拉起时报错。

过程二:配置你的 sidecar 容器

kind: Job
spec:
  template:
    spec:
      containers:
        - name: sidecar
          env:
            - name: KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT_WITH_IMAGE
              value: "example/quick-exit:v1.0.0"
        - name: main
... ...

运用你自己预备的快速退出镜像来替换上述 “example/quick-exit:v1.0.0”.

注意事项

  • sidecar 容器有必要能够呼应 SIGTERM 信号,而且当收到此信号时,entrypoint 进程需求退出(即 sidecar 容器需求退出),而且退出码应当为 0。
  • 该特性适用于恣意 Job 类型 Workload 所办理的 Pod,只要他们的 RestartPolicy 为 Never/OnFailure 即可。
  • 具有环境变量 KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT 的容器将被视为 sidecar 容器,其他容器将被视为主容器,当所有主容器完结后,sidecar 容器才会被终止:
    • 在 Never 重启策略下,主容器一旦退出,将被视为”已完结”。
    • 在 OnFailure 重启策略下,主容器退出代码有必要为0,才会被视为”已完结”。

03 增强版别的作业负载

CloneSet 优化功能 :新增 FeatureGate CloneSetEventHandlerOptimization

当时,无论是 Pod 的状况变化仍是 Metadata 变化,Pod Update 事情都会触发 CloneSet reconcile 逻辑。CloneSet Reconcile 默许配置了三个 worker,关于集群规模较小的场景,这种状况并不会形成问题。

但关于集群规模较大或 Pod Update 事情较多的状况,这些无效的 reconcile 将会阻塞真正的 CloneSet reconcile,从而导致 CloneSet 的翻滚晋级等改变推迟。为了处理这个问题,能够翻开 feature-gate CloneSetEventHandlerOptimization 来削减一些不必要的 reconcile 入队。

CloneSet 新增 disablePVCReuse 字段

假如一个 Pod 被外部直接调用删去或驱逐时,这个 Pod 相关的 PVCs 还都存在;而且 CloneSet controller 发现数量缺乏从头扩容时,新扩出来的 Pod 会复用原 Pod 的 instance-id 并相关本来的 PVCs。

但是,假如 Pod 所在的 Node 出现异常,复用可能会导致新 Pod 发动失利,详情参阅 **issue 1099 [ 5] **。为了处理这个问题,您能够设置字段 disablePVCReuse=true,当 Pod 被驱逐或许删去后,与 Pod 相关的 PVCs 将被自动删去,不再被复用。

apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
spec:
  ...
  replicas: 4
  scaleStrategy:
    disablePVCReuse: true

CloneSet 增加 PreNormal 生命周期钩子

CloneSet 现已支撑了 PreparingUpdate、PreparingDelete 两种生命周期钩子,用于使用的高雅下线,详情参阅**社区文档 [ 6] **。为了支撑高雅上线的场景,本次新增加了 PreNormal 状况,详细如下:

apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
spec:
  # define with finalizer
  lifecycle:
    preNormal:
      finalizersHandler:
      - example.io/unready-blocker
  # or define with label
  lifecycle:
    preNormal:
      labelsHandler:
        example.io/block-unready: "true"

当 CloneSet 创立一个 Pod(包括正常扩容和重建晋级)时:

  • 假如 Pod 满意了 PreNormal hook 的定义,才会被认为是 Available,而且才会进入 Normal 状况

这关于一些 Pod 创立时的后置检查很有用,比如你能够检查 Pod 是否现已挂载到 SLB 后端,从而防止翻滚晋级时,旧实例销毁后,新实例挂载失利导致的流量损失。

04 高级的使用运维才能

容器重启新增 forceRecreate 字段

当创立 CRR 资源时,假如容器正在发动过程中,CRR 将不会再重启容器。假如您想要强制重启容器,能够运用以下字段开启:

apiVersion: apps.kruise.io/v1alpha1
kind: ContainerRecreateRequest
spec:
  ...
  strategy:
    forceRecreate: true

镜像预热支撑 Attach metadata into cri interface

当 Kubelet 创立 Pod 时,Kubelet 将会 attach metadata 到 container runtime cri 接口。镜像库房能够依据这些 metadata 信息来确认拉镜像的来历事务,假如发生了库房过载、压力过大的状况,能够对详细的事务进行降级处理。OpenKruise 镜像预热相同支撑相似的才能,如下:

apiVersion: apps.kruise.io/v1alpha1
kind: ImagePullJob
spec:
  ...
  image: nginx:1.9.1
  sandboxConfig:
    annotations:
      io.kubernetes.image.metrics.tags: "cluster=cn-shanghai"
    labels:
      io.kubernetes.image.app: "foo"

社区参加

十分欢迎你经过 Github/Slack/钉钉/微信 等方法参加咱们来参加 OpenKruise 开源社区。你是否现已有一些期望与咱们社区交流的内容呢?能够在咱们的**社区双周会 [7 ] **上共享你的声音,或经过以下渠道参加评论:

  • 参加社区**Slack channel [ 8] **(English)
  • 参加社区钉钉群:查找群号 23330762 (Chinese)
  • 参加社区微信群(新):增加用户 openkruise 并让机器人拉你入群 (Chinese)

相关链接:

[1]ChangeLog

github.com/openkruise/…

[2]ECI

www.aliyun.com/product/eci

[3]Fargate

aws.amazon.com/cn/fargate/

[4]Virtual-Kubelet

virtual-kubelet.io/#:~:text=Vi…

[5]issue 1099

github.com/openkruise/…

[6]社区文档

openkruise.io/docs/user-m…

[7]社区双周会

browser.alibaba-inc.com/?Url=https:…

[8]Slack channel

kubernetes.slack.com/?redir=%2Fa…

点击此处,检查 OpenKruise 项目官方主页与文档