本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes v1.28:引入原生 Sidecar 容器

本文解释了如何使用新的 sidecar 功能,该功能支持可重启的 Init 容器,并在 Kubernetes 1.28 中以 Alpha 阶段提供。我们希望得到你的反馈,以便我们能尽快将此功能推向成熟。

“sidecar” 的概念几乎从 Kubernetes 诞生之初就存在了。2015 年,在一篇关于复合容器的博文中,sidecar 被描述为“扩展和增强‘主’容器”的附加容器。Sidecar 容器已成为一种常见的 Kubernetes 部署模式,通常用于网络代理或作为日志系统的一部分。到目前为止,sidecar 只是 Kubernetes 用户在没有原生支持的情况下应用的一个概念。缺乏原生支持导致了一些使用上的不便,本次功能增强旨在解决这些问题。

1.28 中的 Sidecar 容器是什么?

Kubernetes 1.28 为Init 容器添加了一个新的 restartPolicy 字段,当 SidecarContainers 功能门控被启用时可用。

apiVersion: v1
kind: Pod
spec:
  initContainers:
  - name: secret-fetch
    image: secret-fetch:1.0
  - name: network-proxy
    image: network-proxy:1.0
    restartPolicy: Always
  containers:
  ...

该字段是可选的,如果设置,唯一有效的值是 Always。设置此字段会改变 Init 容器的行为,具体如下:

  • 如果容器退出,它会重启。
  • 任何后续的 Init 容器都会在启动探针(startupProbe)成功完成后立即启动,而不是等待可重启的 Init 容器退出。
  • Pod 的资源使用计算方式发生变化,因为可重启 Init 容器的资源现在会被加到主容器资源请求的总和中。

Pod 终止仍然仅取决于主容器。一个 restartPolicyAlways 的 Init 容器(称为 sidecar)不会在主容器退出后阻止 Pod 终止。

可重启 Init 容器的以下特性使其非常适合 sidecar 部署模式:

  • 无论你是否设置 restartPolicy,Init 容器都有明确的启动顺序,因此你可以确保你的 sidecar 在清单中任何位于 sidecar 声明之后的容器声明之前启动。
  • Sidecar 容器不会延长 Pod 的生命周期,因此你可以在短生命周期的 Pod 中使用它们,而无需更改 Pod 的生命周期。
  • Sidecar 容器在退出时会重启,这提高了弹性,让你能够使用 sidecar 提供主容器可以更可靠地消费的服务。

何时使用 Sidecar 容器

你可能会发现内置的 sidecar 容器对以下工作负载很有用:

  • 批处理或 AI/ML 工作负载,或其他运行至完成的 Pod。这些工作负载将体验到最显著的好处。
  • 网络代理,在清单中任何其他容器之前启动。其他所有运行的容器都可以使用该代理容器的服务。有关说明,请参阅 Istio 中的 Kubernetes 原生 sidecar 博文
  • 日志收集容器,现在可以在任何其他容器之前启动,并一直运行到 Pod 终止。这提高了 Pod 中日志收集的可靠性。
  • Job,可以使用 sidecar 来实现任何目的,而 Job 的完成不会被正在运行的 sidecar 阻塞。无需额外配置即可确保此行为。

在 1.28 之前,用户是如何实现 Sidecar 行为的?

在 sidecar 功能出现之前,根据 sidecar 容器期望的生命周期,有以下几种实现 sidecar 行为的选项:

  • Sidecar 的生命周期短于 Pod 生命周期:使用 Init 容器,它提供了明确的启动顺序。但是,sidecar 必须退出,其他 Init 容器和主 Pod 容器才能启动。
  • Sidecar 的生命周期等于 Pod 生命周期:使用一个与工作负载容器一起在 Pod 中运行的主容器。这种方法无法控制启动顺序,并且可能导致 sidecar 容器在工作负载容器退出后阻止 Pod 终止。

内置的 sidecar 功能解决了生命周期等于 Pod 生命周期的用例,并具有以下额外的好处:

  • 提供对启动顺序的控制
  • 不阻塞 Pod 终止

将现有 Sidecar 过渡到新模型

在 Alpha 阶段,我们建议仅在短期测试集群中使用 sidecars 功能门控。如果你现有的 sidecar 被配置为主容器,以便它可以运行到 Pod 的整个生命周期,那么可以将其移动到 Pod 规范的 initContainers 部分,并为其设置 restartPolicyAlways。在许多情况下,sidecar 的工作方式应与之前相同,但增加了定义启动顺序和不延长 Pod 生命周期的好处。

已知问题

内置 sidecar 容器的 Alpha 版本存在以下已知问题,我们将在功能进入 Beta 阶段之前解决这些问题:

  • CPU、内存、设备和拓扑管理器不知道 sidecar 容器的生命周期和额外的资源使用情况,它们的行为会像 Pod 的资源请求比实际更低一样。
  • 当使用 sidecar 时,kubectl describe node 的输出是不正确的。输出显示的资源使用量低于实际使用量,因为它没有使用新的 sidecar 容器资源使用计算方法。

我们需要你的反馈!

在 Alpha 阶段,我们希望你在你的环境中试用 sidecar 容器,如果遇到错误或不便之处,请提交 issue。我们特别对以下方面的反馈感兴趣:

  • 关闭顺序,尤其是在有多个 sidecar 运行时
  • 针对崩溃的 sidecar 的退避超时调整
  • 当 sidecar 运行时,Pod 的就绪和存活探针的行为

要提交 issue,请访问 Kubernetes GitHub 仓库

下一步是什么?

除了将要解决的已知问题外,我们还在努力为 sidecar 和主容器添加终止顺序。这将确保 sidecar 容器仅在 Pod 的主容器退出后才终止。

我们很高兴看到 sidecar 功能来到 Kubernetes,并期待你的反馈。

致谢

距离最初的 KEP 编写已经过去了很多年,所以如果我们遗漏了这些年来为这个功能做出贡献的任何人,我们深表歉意。这是我们尽最大努力对参与这项工作的人员表示认可。

更多信息