采用 Sidecar 容器
本节适用于为其工作负载采用新的内置sidecar 容器功能的人员。
正如博客文章中所述,Sidecar 容器并非新概念。Kubernetes 允许在 Pod 中运行多个容器来实现此概念。但是,将 sidecar 容器作为常规容器运行存在许多限制,这些限制正在通过新的内置 sidecar 容器支持得到修复。
Kubernetes v1.33 [stable]
(默认启用:true)目标
- 了解对 sidecar 容器的需求
- 能够排查 sidecar 容器的问题
- 了解通用“注入”sidecar 容器到任何工作负载的选项
准备工作
你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与你的集群通信。建议在至少有两个节点(不作为控制平面主机)的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用这些 Kubernetes 游乐场之一
你的 Kubernetes 服务器版本必须是 1.29 或更高版本。要检查版本,请输入 kubectl version
。
Sidecar 容器概述
Sidecar 容器是与主应用容器在同一个Pod 中运行的辅助容器。这些容器用于通过提供附加服务或功能(例如日志记录、监控、安全性或数据同步)来增强或扩展主*应用容器*的功能,而无需直接修改主应用程序代码。你可以在Sidecar 容器概念页面中了解更多信息。
Sidecar 容器的概念并非新鲜事物,并且存在多种实现此概念的方法。除了你(定义 Pod 的人)希望运行的 sidecar 容器之外,你还会发现一些附加组件会在 Pod 启动前修改 Pod,从而添加额外的 sidecar 容器。注入这些额外 sidecar 的机制通常是准入控制器(MutatingAdmissionWebhook)。例如,服务网格附加组件可能会注入一个 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,即使常规容器不会使用 Pod 的
restartPolicy: Never
,内置 sidecar 容器一旦完成仍会持续重启。
请参阅与 Init 容器的区别以了解更多信息。
采用内置 sidecar 容器
从 Kubernetes 1.29 版本开始,SidecarContainers
功能门控处于 Beta 状态,并默认启用。某些集群可能已禁用此功能或安装了与此功能不兼容的软件。
发生这种情况时,Pod 可能会被拒绝,或者 sidecar 容器可能会阻止 Pod 启动,使 Pod 无法使用。这种情况很容易检测,因为 Pod 只是卡在初始化阶段。然而,通常不清楚是什么导致了问题。
以下是为工作负载采用 sidecar 容器时可以考虑和采取的故障排除步骤。
确保功能门控已启用
作为第一步,请确保 API 服务器和节点都运行 Kubernetes v1.29 或更高版本。在节点运行早期版本(未启用该功能)的集群上,该功能将无法正常工作。
注意
此功能可以在版本 1.28 的节点上启用。内置 sidecar 容器的终止行为在版本 1.28 中有所不同,不建议将 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 注入期间,你可以使用以下策略来检查节点兼容性:
- 查询节点版本并假设该功能门控在 v1.29+ 版本上已启用
- 查询节点 Prometheus 指标并检查功能启用状态
- 假设节点正在以与 API 服务器支持的版本偏差运行
- 可能还有其他自定义方法来检测节点兼容性。
- 开发一个通用 Sidecar 注入器。通用 Sidecar 注入器的想法是将 Sidecar 容器作为常规容器以及原生 Sidecar 容器注入。并具有运行时逻辑来决定哪个将起作用。通用 Sidecar 注入器是浪费的,因为它将请求计数两次,但可以被认为是特殊情况下的可行解决方案。
- 一种方法是在原生 sidecar 容器启动时检测节点版本,如果该版本不支持 sidecar 功能,则立即退出。
- 考虑运行时功能检测设计
- 定义一个空目录,以便容器可以相互通信
- 注入一个初始化容器,我们称之为
NativeSidecar
,其restartPolicy=Always
。 NativeSidecar
必须向一个空目录写入一个文件,表示首次运行,并立即以退出码0
退出。NativeSidecar
在重启时(当支持原生 sidecar 时)检查该文件是否已存在于空目录中,并修改它——表明内置 sidecar 容器受到支持且正在运行。- 注入常规容器,我们称之为
OldWaySidecar
。 OldWaySidecar
启动时检查空目录中是否存在文件。- 如果文件表明
NativeSidecar
未运行,则它假定 sidecar 功能不受支持,并将其作为 sidecar 运行。 - 如果文件指示
NativeSidecar
正在运行,它要么什么都不做并永远休眠(在 Pod 的restartPolicy=Always
的情况下),要么立即以退出代码0
退出(在 Pod 的restartPolicy!=Always
的情况下)。
下一步
- 了解更多关于sidecar 容器的信息。