采用 Sidecar 容器

本节适用于为其工作负载采用新的内置边车容器功能的人员。

正如博客文章中所述,边车容器并不是一个新概念。Kubernetes 允许在 Pod 中运行多个容器来实现此概念。但是,将边车容器作为常规容器运行有很多局限性,新的内置边车容器支持正在解决这些局限性。

功能状态:Kubernetes v1.29 [beta](默认启用:true)

目标

  • 了解对边车容器的需求
  • 能够排查边车容器的问题
  • 了解将边车容器普遍“注入”到任何工作负载的选项

开始之前

您需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与您的集群通信。建议在至少有两个不充当控制平面主机的节点上运行本教程。如果您还没有集群,可以使用minikube创建一个,或者可以使用以下 Kubernetes 游乐场之一

您的 Kubernetes 服务器必须是 1.29 或更高版本。要检查版本,请输入 kubectl version

边车容器概述

边车容器是与同一Pod中的主应用程序容器一起运行的辅助容器。这些容器用于通过提供额外的服务或功能(如日志记录、监控、安全或数据同步)来增强或扩展主**应用程序容器**的功能,而无需直接更改主应用程序代码。您可以在边车容器概念页面中阅读更多内容。

边车容器的概念并不新鲜,并且有多种实现此概念的方法。除了您(定义 Pod 的人)想要运行的边车容器之外,您还可以发现一些插件会修改 Pod - 在 Pod 开始运行之前 - 以便有额外的边车容器。**注入**这些额外边车的机制通常是变异 Webhook。例如,服务网格插件可能会注入一个配置不同 Pod 之间相互 TLS 和传输中加密的边车。

虽然边车容器的概念并不新鲜,但 Kubernetes 中此功能的本机实现是新的。与每个新功能一样,采用此功能可能会带来某些挑战。

本教程探讨了最终用户以及边车容器作者可能会遇到的挑战和解决方案。

内置边车容器的优势

使用 Kubernetes 对边车容器的本机支持有几个好处

  1. 您可以配置本机边车容器以在初始化容器之前启动。
  2. 内置的边车容器可以被编写为保证它们最后终止。一旦所有常规容器完成并终止,边车容器将使用 SIGTERM 信号终止。如果边车容器没有正常关闭,则将使用 SIGKILL 信号终止它。
  3. 对于 Job,当 Pod 的 restartPolicy: OnFailurerestartPolicy: Never 时,本机边车容器不会阻止 Pod 完成。对于传统的边车容器,需要特别注意处理这种情况。
  4. 此外,对于 Job,内置的边车容器在完成后会保持重启,即使常规容器不会使用 Pod 的 restartPolicy: Never

请参阅与初始化容器的区别以了解更多信息。

采用内置边车容器

从 Kubernetes 1.29 版本开始,SidecarContainers 特性门控处于 beta 状态,并且默认启用。某些集群可能已禁用此功能或安装了与该功能不兼容的软件。

发生这种情况时,可能会拒绝 Pod,或者边车容器可能会阻止 Pod 启动,从而使 Pod 无用。这种情况很容易检测到,因为 Pod 只是在初始化时卡住。但是,通常不清楚是什么导致了问题。

以下是在为工作负载采用边车容器时可以采取的注意事项和故障排除步骤。

确保启用特性门控

作为第一步,请确保 API 服务器和节点都处于 Kubernetes v1.29 或更高版本。该功能将在节点运行较早版本的集群中中断,因为它在这些版本中未启用。

您应确保控制平面内的 API 服务器**和**所有节点都启用了特性门控。

检查特性门控启用情况的一种方法是运行如下命令

  • 对于 API 服务器

    kubectl get --raw /metrics | grep kubernetes_feature_enabled | grep SidecarContainers
    
  • 对于单个节点

    kubectl get --raw /api/v1/nodes/<node-name>/proxy/metrics | grep kubernetes_feature_enabled | grep SidecarContainers
    

如果您看到类似以下内容

kubernetes_feature_enabled{name="SidecarContainers",stage="BETA"} 1

则表示该功能已启用。

检查第三方工具和变异 Webhook

如果您在验证功能时遇到问题,这可能表明第三方工具或变异 Webhook 之一已损坏。

当启用 SidecarContainers 特性门控时,Pod 在其 API 中获得一个新字段。某些工具或变异 Webhook 可能是在较早版本的 Kubernetes API 中构建的。

如果工具使用各种修补策略按原样传递未知字段以变异 Pod 对象,则这不是问题。但是,有些工具会剥离未知字段;如果您有这些工具,则必须使用 v1.28+ 版本的 Kubernetes API 客户端代码重新编译它们。

检查此问题的方法是对通过变异准入的 Pod 使用 kubectl describe pod 命令。如果任何工具剥离了新字段(restartPolicy:Always),您将不会在命令输出中看到它。

如果遇到类似问题,请建议工具或 Webhook 的作者使用修补策略之一来修改对象,而不是完全更新对象。

边车的自动注入

如果您正在使用自动注入边车的软件,则可以遵循几种可能的策略,以确保可以使用本机边车容器。所有策略通常都是您可以选择的选项,以决定要注入边车的 Pod 是否会落到支持该功能的节点上。

例如,您可以关注Istio 社区中的此对话。讨论探讨了下面列出的选项。

  1. 标记落到支持边车的节点上的 Pod。您可以使用节点标签和节点亲和性来标记支持边车容器的节点以及落到这些节点上的 Pod。
  2. 在注入时检查节点兼容性。在边车注入期间,您可以使用以下策略来检查节点兼容性
    • 查询节点版本并假定在 1.29+ 版本上启用了特性门控
    • 查询节点 Prometheus 指标并检查特性启用状态
    • 假设节点运行的支持的版本倾斜来自 API 服务器
    • 可能还有其他自定义方法来检测节点兼容性。
  3. 开发通用边车注入器。通用边车注入器的想法是将边车容器注入为常规容器以及本机边车容器。并具有运行时逻辑来决定哪个起作用。通用边车注入器是浪费的,因为它将两次计算请求,但可以被认为是特殊情况下可行的解决方案。
    • 一种方法是在启动本机边车容器时检测节点版本,如果版本不支持边车功能,则立即退出。
    • 考虑运行时特性检测设计
      • 定义一个空目录,以便容器可以相互通信
      • 注入一个初始化容器,我们称之为 NativeSidecar,其中 restartPolicy=Always
      • NativeSidecar 必须将文件写入空目录,指示首次运行,并立即以退出代码 0 退出。
      • NativeSidecar 在重启时(当支持原生边车容器时)会检查空目录中是否已存在文件,并修改它 - 这表明内置的边车容器已受支持并正在运行。
      • 注入一个常规容器,我们称之为 OldWaySidecar
      • OldWaySidecar 在启动时会检查空目录中是否存在文件。
      • 如果文件表明 NativeSidecar 没有运行,则它会认为不支持边车功能,并假设自己是边车容器并工作。
      • 如果文件表明 NativeSidecar 正在运行,则它要么什么都不做并永远休眠(在 Pod 的 restartPolicy=Always 的情况下),要么立即以退出代码 0 退出(在 Pod 的 restartPolicy!=Always 的情况下)。

接下来是什么

上次修改时间:2024年11月06日 太平洋标准时间上午10:05: 清理教程:pod-sidecar-containers.md (96d69d62fe)