本文适用于使用新的内置边车容器特性的用户。
边车容器并不是一个新概念,正如在博客文章中所提到的那样。Kubernetes 允许在一个 Pod 中运行多个容器来实现这一概念。然而,作为一个普通容器运行边车容器存在许多限制,这些限制通过新的内置边车容器支持得到了解决。
Kubernetes v1.33 [stable](默认启用)你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 1.29.要获知版本信息,请输入 kubectl version.
边车容器是与主应用程序容器在同一 Pod内一起运行的辅助容器。这些容器通过提供额外的服务或功能(如日志记录、监控、安全或数据同步)来增强或扩展主应用容器的功能,而无需直接修改主应用程序代码。你可以在边车容器概念页面中阅读更多相关内容。
边车容器的概念并不新鲜,有许多不同的实现方式。除了你(定义 Pod 的人)希望运行的边车容器外,一些插件也会在 Pod 开始运行之前对其进行修改,以添加额外的边车容器。这些额外边车容器的注入机制通常是变更 Webhook(Mutating Webhook)。例如,服务网格插件可能会注入一个配置双向 TLS(Mutual TLS)和传输中加密的边车容器。
虽然边车容器的概念并不新鲜,但 Kubernetes 对这一特性的原生实现却是新的。与每一项新特性一样,采用这一特性可能会带来某些挑战。
本教程探讨了终端用户和边车容器作者可能遇到的挑战及其解决方案。
使用 Kubernetes 对边车容器的原生支持可以带来以下几个好处:
SIGTERM 信号。如果边车容器未能体面关闭,系统将使用 SIGKILL 信号终止它。restartPolicy: OnFailure 或 restartPolicy: Never 时,原生边车容器不会阻止 Pod 完成。而对于传统边车容器,需要特别处理这种情况。restartPolicy: Never 时常规容器不会重启,内置边车容器仍会在完成后继续重启。更多详情请参见与 Init 容器的区别。
从 Kubernetes 1.29 版本开始,SidecarContainers
特性门控处于 Beta 阶段,并默认启用。某些集群可能禁用了此特性,或者安装了与该特性不兼容的软件。
当这种情况发生时,Pod 可能会被拒绝,或者边车容器可能阻止 Pod 启动,导致 Pod 无法使用。这种情况下很容易检测到问题,因为 Pod 会卡在初始化阶段。然而,通常不清楚是什么原因导致了问题。
以下是在使用边车容器处理工作负载时可以考虑的因素和排查步骤。
首先,确保 API 服务器和节点都在 Kubernetes v1.29 及更高版本上运行。如果节点运行的是早期版本且未启用该特性,集群中的该特性将无法正常工作。
此特性可以在 1.28 版本的节点上启用。然而,内置边车容器的终止行为在 1.28 版本中有所不同,不建议将边车的行为调整为 1.28 中的行为。但是,如果唯一的关注点是启动顺序,上述陈述可以改为:运行 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 出现了问题。
当 SidecarContainers 特性门控启用后,Pod 在其 API 中会新增一个字段。某些工具或变更 Webhook 可能是基于早期版本的 Kubernetes API 构建的。
如果工具使用各种修补策略将未知字段原样传递,这不会有问题。然而,有些工具会删除未知字段;如果你使用的是这些工具,必须使用 v1.28+ 版本的 Kubernetes API 客户端代码重新编译它们。
检查这一点的方法是使用 kubectl describe pod 命令查看已通过变更准入的 Pod。如果任何工具删除了新字段(如 restartPolicy: Always),你将不会在命令输出中看到它。
如果你遇到了此类问题,请告知工具或 Webhook 的作者使用修补策略来修改对象,而不是进行完整的对象更新。
变更 Webhook 可能会根据某些条件更新 Pod。因此,边车容器可能对某些 Pod 有效,但对其他 Pod 无效。
如果你使用的是自动注入边车的软件,可以采取几种策略来确保能够使用原生边车容器。所有这些策略通常都是你可以选择的选项,以决定注入边车的 Pod 是否会落在支持该特性的节点上。
例如,可以参考 Istio 社区中的这次讨论。讨论中探讨了以下选项:
NativeSidecar,并设置 restartPolicy=Always。NativeSidecar 必须在空目录中写入一个文件,表示首次运行并立即退出,退出码为 0。 - `NativeSidecar` 在重启时(当支持原生边车时)检查空目录中是否已存在该文件,并进行更改 —— 表示已支持原生边车容器并正在运行。
OldWaySidecar。OldWaySidecar 启动时检查空目录中是否存在文件。NativeSidecar 未运行,则假设边特性不支持,并按边车的方式工作。NativeSidecar 正在运行,则根据 Pod 的 restartPolicy 决定行为:restartPolicy=Always,则不做任何操作并永远休眠。restartPolicy!=Always,则立即退出,退出码为 0。