乐趣区

关于阿里云:OpenKruise-V14-版本解读新增-Job-Sidecar-Terminator-能力

作者:立衡

前言

OpenKruise 是阿里云开源的云原生利用自动化治理套件,也是以后托管在 Cloud Native Computing Foundation (CNCF) 下的孵化我的项目。它来自阿里巴巴多年来容器化、云原生的技术积淀,是阿里外部生产环境大规模利用的基于 Kubernetes 之上的规范扩大组件,也是紧贴上游社区规范、适应互联网规模化场景的技术理念与最佳实际。

OpenKruise:

https://github.com/openkruise/kruise

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

https://github.com/openkruise/kruise/blob/master/CHANGELOG.md

[2] ECI

https://www.aliyun.com/product/eci

[3] Fargate

https://aws.amazon.com/cn/fargate/

[4] Virtual-Kubelet

https://virtual-kubelet.io/#:~:text=Virtual%20Kubelet%20is%20an%20open,as%20serverless%20cloud%20container%20platforms.

[5] issue 1099

https://github.com/openkruise/kruise/issues/1099

[6] 社区文档

https://openkruise.io/docs/user-manuals/cloneset/#lifecycle-hook

[7] 社区双周会

https://browser.alibaba-inc.com/?Url=https://shimo.im/docs/gX…

[8] Slack channel

https://kubernetes.slack.com/?redir=%2Farchives%2Fopenkruise

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

退出移动版