采用 Sidecar 容器
本节与采用新的内置 Sidecar 容器 特性的工作负载相关。
Sidecar 容器并非新概念,如 博客文章 中所述。Kubernetes 允许在 Pod 中运行多个容器以实现此概念。但是,将 Sidecar 容器作为常规容器运行有很多限制,这些限制正在通过新的内置 Sidecar 容器支持得到解决。
Kubernetes v1.33 [稳定](默认启用)目标
- 了解 Sidecar 容器的需求
- 能够排查 Sidecar 容器的问题
- 了解将 Sidecar 容器通用“注入”到任何工作负载的选项
开始之前
您需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在至少具有两个非控制平面主机的集群上运行本教程。如果您还没有集群,可以使用 minikube 或使用以下 Kubernetes 游乐场之一创建集群
您的 Kubernetes 服务器必须是版本 1.29 或更高版本。要检查版本,请输入 kubectl version。
Sidecar 容器概述
Sidecar 容器是与 Pod 内的主要应用程序容器一起运行的辅助容器,位于同一个 Pod 中。这些容器用于通过提供额外的服务或功能(例如日志记录、监控、安全性或数据同步)来增强或扩展主要应用程序容器的功能,而无需直接更改主要应用程序代码。您可以在 Sidecar 容器 概念页面上了解更多信息。
Sidecar 容器的概念并非全新,并且有多种实现此概念的方法。除了您定义 Pod 时想要运行的 Sidecar 容器之外,您还可以发现某些 插件 会在 Pod 开始运行之前修改 Pod,从而添加额外的 Sidecar 容器。用于注入这些额外 Sidecar 的机制通常是 变更型准入 Webhook。例如,服务网格插件可能会注入一个 Sidecar,以配置 Pod 之间传输的相互 TLS 和加密。
虽然 Sidecar 容器的概念并非全新,但 Kubernetes 中此功能的本机实现却是全新的。并且与每个新功能一样,采用此功能可能会带来某些挑战。
本教程探讨了最终用户和 Sidecar 容器作者可能遇到的挑战和解决方案。
内置 Sidecar 容器的优势
使用 Kubernetes 对 Sidecar 容器的本机支持提供了几个优势
- 您可以配置本机 Sidecar 容器在 初始化容器 之前启动。
- 内置 Sidecar 容器可以被编写为保证最后终止。Sidecar 容器在所有常规容器完成并终止后,会收到
SIGTERM信号终止。如果 Sidecar 容器未优雅关闭,将使用SIGKILL信号终止它。 - 对于 Jobs,当 Pod 的
restartPolicy: OnFailure或restartPolicy: Never时,本机 Sidecar 容器不会阻止 Pod 完成。对于旧版 Sidecar 容器,需要特别注意处理这种情况。 - 此外,对于 Jobs,内置 Sidecar 容器即使常规容器不使用 Pod 的
restartPolicy: Never,也会在完成之后继续重启。
请参阅 与应用程序容器的区别,以了解更多信息。
采用内置 Sidecar 容器
从 Kubernetes 版本 1.29 开始,SidecarContainers 特性门控 处于 Beta 状态,默认启用。某些集群可能已禁用此特性,或者安装了与该特性不兼容的软件。
当发生这种情况时,Pod 可能会被拒绝,或者 Sidecar 容器可能会阻止 Pod 启动,从而使 Pod 无法使用。这种状况很容易检测到,因为 Pod 只是卡在初始化状态。但是,通常不清楚是什么导致了问题。
以下是在采用 Sidecar 容器用于其工作负载时可以采取的注意事项和故障排除步骤。
确保启用特性门控
首先,确保 API 服务器和节点都处于 Kubernetes 版本 v1.29 或更高版本。该特性将在运行早期版本且未启用该特性的节点上中断。
说明
可以在版本 1.28 的节点上启用该特性。版本 1.28 中内置 Sidecar 容器的终止行为有所不同,不建议将 Sidecar 的行为调整为该行为。但是,如果唯一的关注点是启动顺序,则可以将上述语句更改为运行版本 1.28 并启用特性门控的节点。您应确保控制平面中的 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 客户端代码重新编译它们。
检查此方法是使用 kubectl describe pod 命令和通过变更型准入传递的 Pod。如果任何工具删除了新字段(restartPolicy:Always),则不会在命令输出中看到它。
如果您遇到类似问题,请建议工具或 Webhook 的作者使用一种补丁策略来修改对象,而不是完全更新对象。
说明
变更型 Webhook 可能会根据某些条件更新 Pod。因此,Sidecar 容器可能适用于某些 Pod,而对于其他 Pod 则可能失败。自动注入 Sidecar
如果您正在使用自动注入 Sidecar 的软件,您可以遵循以下几种策略来确保可以使用本机 Sidecar 容器。所有策略通常都是您可以选择的选项,以确定 Sidecar 将被注入到的 Pod 是否会降落在支持该特性的节点上。
例如,您可以遵循 Istio 社区中的此对话。该讨论探讨了以下选项。
- 标记降落在支持 Sidecar 的节点上的 Pod。您可以使用节点标签和节点亲和性来标记支持 Sidecar 容器的节点和降落在这些节点上的 Pod。
- 在注入时检查节点兼容性。在 Sidecar 注入期间,您可以使用以下策略来检查节点兼容性
- 查询节点版本并假设该特性门控已在版本 1.29+ 中启用
- 查询节点 Prometheus 指标并检查特性启用状态
- 假设节点正在运行与 API 服务器的 支持版本偏差
- 可能还有其他自定义方法来检测节点兼容性。
- 开发通用的 Sidecar 注入器。通用 Sidecar 注入器的想法是以常规容器以及本机 Sidecar 容器的形式注入 Sidecar 容器。并具有运行时逻辑来确定哪个容器将起作用。通用 Sidecar 注入器效率低下,因为它会两次计算请求,但对于特殊情况可能被认为是可行的解决方案。
- 一种方法是在原生 sidecar 容器启动时检测节点版本,如果版本不支持 sidecar 功能则立即退出。
- 考虑一种运行时功能检测设计
- 定义一个空目录,以便容器之间可以相互通信
- 注入一个 init 容器,我们称之为
NativeSidecar,并设置restartPolicy=Always。 NativeSidecar必须将一个文件写入空目录,指示首次运行,并立即以退出代码0退出。NativeSidecar在重启时(当支持原生 sidecar 时)检查该文件是否已存在于空目录中,并修改它 - 指示内置 sidecar 容器正在支持和运行。- 注入常规容器,我们称之为
OldWaySidecar。 OldWaySidecar在启动时检查空目录中是否存在文件。- 如果文件指示
NativeSidecar未运行,则它假定 sidecar 功能不受支持,并假设它是 sidecar 本身。 - 如果文件指示
NativeSidecar正在运行,则它要么什么也不做并永久休眠(在 Pod 的restartPolicy=Always的情况下),要么立即以退出代码0退出(在 Pod 的restartPolicy!=Always的情况下)。
接下来
- 了解更多关于 sidecar 容器的信息。