Job Sidecar Terminator

FEATURE STATE: Kruise v1.4.0

对于 Job 类型的 Workload,我们通常希望当这些 Pod 中执行业务逻辑的主容器完成任务并退出后,日志收集等 sidecar 容器也能够主动退出,从而使得这些 Job Controller 能够正确判断 Pod 所处的完成状态,避免一些错误的信息上报和流程异常。

为了解决这个问题,我们在 Kruise 中加入了一个名为 SidecarTerminator 的控制器,专门用于在此类场景下,监听主容器的完成状态,并选择合适的时机终止掉 Pod 中的 sidecar 容器,而且无需对业务进行侵入式改造。

使用前提

  • 在安装或升级 Kruise 时启用 JobSidecarTerminator Feature-Gate(默认关闭)
  • 在安装或升级 Kruise 时启用 KruiseDaemon Feature-Gate(默认开启)。

使用方式

对于运行于普通节点的 Pod

对于运行于普通节点的 Pod,使用该特性非常简单,用户只需要在要在目标 sidecar 容器中添加一个特殊的 env 对其进行标识,控制器会在恰当的时机利用 Kruise Daemon 提供的 CRR 的能力,将这些 sidecar 容器终止:

  1. kind: Job
  2. spec:
  3. template:
  4. spec:
  5. containers:
  6. - name: sidecar
  7. env:
  8. - name: KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT
  9. value: "true"
  10. - name: main
  11. ... ...

对于运行于虚拟节点的 Pod

对于一些提供 Serverless 容器的平台,例如 ECI 或者 Fargate, 其 Pods 只能运行于 Virtual-Kubelet 之类的虚拟节点。 然而,Kruise Daemon 无法部署和工作在这些虚拟节点之上,导致无法使用 CRR 能力将容器终止。 但幸运地是,我们可以借助原生 Kubernetes 提供的 Pod 原地升级机制来达到同样的目的:只需要构造一个特殊镜像,这个镜像的唯一作用就是当被拉起后,会快速地主动退出,这样一来,只需要在退出 sidecar 时,将原本的 sidecar 镜像替换为快速退出镜像,即可达到退出 sidecar 的目的。

步骤一: 准备一个快速退出镜像

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

步骤二: 配置你的 sidecar 容器

  1. kind: Job
  2. spec:
  3. template:
  4. spec:
  5. containers:
  6. - name: sidecar
  7. env:
  8. - name: KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT_WITH_IMAGE
  9. value: "example/quick-exit:v1.0.0"
  10. - name: main
  11. ... ...

使用你自己准备的快速退出镜像来替换上述 "example/quick-exit:v1.0.0".

注意事项

  • sidecar 容器必须能够响应 SIGTERM 信号。当收到此信号时,EntryPoint 进程必须退出(即 sidecar 容器退出),且退出码应当为 0
  • 该特性适用于任意 Job 类型 Workload 所管理的 Pod,只要它们的 RestartPolicyNever/OnFailure 即可。
  • 具有环境变量 KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT 的容器将被视为 sidecar 容器,其他容器将被视为主容器,当所有主容器完成后,sidecar 容器才会被终止:
    • Never 重启策略下,主容器一旦退出,将被视为”已完成”。
    • OnFailure 重启策略下,主容器退出代码必须为0,才会被视为”已完成”。
  • 且运行在普通节点方式下,KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT 的优先级高于KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT_WITH_IMAGE