ingress-nginx Helm Chart 3.25.0 解析:通过 automountServiceAccountToken 收紧服务账户令牌权限
【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx
ingress-nginx Helm Chart 的 3.25.0 版本做了一项面向安全加固的小型但重要的变更:允许用户在 Chart 中显式指定automountServiceAccountToken(对应上游 PR #6957)。阅读本文可以了解该字段在 ServiceAccount、Pod spec 两层的语义与区别、Chart 中三处新增配置项的默认值与作用范围,以及如何利用它遵循最小权限原则部署 ingress-nginx。
3.25.0 版本变更内容
Helm Chart 的变更记录维护在 helm-chart-3.25.0.md 中,该版本仅包含一条功能性变更:
Add ability to specify automountServiceAccountToken
按照语义化版本(semver)规则,新增能力属于 minor 版本递增(3.24.0 → 3.25.0)。作为参照,前一个版本 helm-chart-3.24.0.md 的变更是 "Add volumes to default-backend deployment"(为 default-backend 的 Deployment 增加 volumes 支持),可见 3.25.0 延续了"为 Chart 增加缺失的可配置项"这一迭代方向。这些 changelog 条目由 helm-chart.md.gotmpl 模板在发版时自动生成。
需要说明适用前提:当前仓库中 Chart 的版本已演进到更高版本(见 Chart.yaml),但 3.25.0 引入的automountServiceAccountToken配置体系至今保留在 Chart 中,其模板与测试结构均未被改动。
背景:automountServiceAccountToken 控制什么
在 Kubernetes 中,Pod 内进程能否访问 API Server 取决于其 ServiceAccount 令牌是否被自动挂载(通常挂载到/var/run/secrets/kubernetes.io/serviceaccount/token)。这一行为由两层字段控制:
- ServiceAccount 级:
ServiceAccount.spec.automountServiceAccountToken,作为该 SA 下所有 Pod 的默认值; - Pod 级:
Pod.spec.automountServiceAccountToken,优先级更高,逐 Pod 覆盖 SA 级默认值。
从安全角度看,自动挂载令牌意味着 Pod 内的任何进程(包括被入侵的容器)都能以该 ServiceAccount 的身份访问 API Server,实际可执行的操作边界取决于该 SA 绑定的 RBAC 规则。因此业界通用做法是:对不需要调用 API 的 Pod 关闭自动挂载,从源头削减凭据暴露面。ingress-nginx 仓库自身也在 hardening-guide.md 中专门讨论了控制器部署的加固策略,automountServiceAccountToken正是其中最常被提到的一项。
3.25.0 之前,Chart 对这一字段没有暴露配置入口;3.25.0 之后,用户可以完全控制 Chart 所创建的全部 ServiceAccount 及其工作负载的令牌挂载行为。
Chart 中新增的三处配置项
本次变更加入了三个 values 键,在 values.yaml 中均默认设为true(保持向后兼容):
| values 键 | 默认值 | 定义位置 | 作用对象 |
|---|---|---|---|
serviceAccount.automountServiceAccountToken | true | values.yaml | ingress-nginx 控制器 ServiceAccount(controller Deployment/DaemonSet) |
defaultBackend.serviceAccount.automountServiceAccountToken | true | values.yaml | default-backend ServiceAccount |
controller.admissionWebhooks.patch.serviceAccount.automountServiceAccountToken | true | values.yaml | 准入 webhook patch Job 使用的 ServiceAccount |
Chart 的 README.md 参数表中将这三项的默认值描述为{"automountServiceAccountToken":true,"create":true,"name":""}等对象形式,与 values.yaml 一致。
模板实现:SA 级与 Pod 级双写
深入模板可以看出,Chart 对每一组组件都做了"SA 级 + Pod 级"双写,这是理解该特性的关键细节。
控制器(controller)
- SA 级:controller-serviceaccount.yaml 中直接输出
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}; - Pod 级:controller-deployment.yaml 与 controller-daemonset.yaml 的 Pod spec 中同样写入
automountServiceAccountToken,且与serviceAccountName相邻声明。
之所以在 Pod spec 层再写一次,从源码结构看有两层考虑:其一,Pod 级字段会覆盖 SA 级默认值,双写保证即使外部 SA 的默认行为不同,Chart 渲染结果仍然确定;其二,当用户通过serviceAccount.create: false使用外部 SA 时,SA 模板不再生效,Pod 级声明仍能约束令牌挂载行为。
default-backend
- SA 级:default-backend-serviceaccount.yaml;
- Pod 级:default-backend-deployment.yaml。
准入 webhook patch Job
webhook 证书补丁由 pre-install/pre-upgrade hook 触发的 Job 完成,涉及三个模板:
- SA 级:job-patch/serviceaccount.yaml,该 SA 带有
helm.sh/hook注解; - Pod 级:job-createSecret.yaml(创建 Secret 的 Job)与 job-patchWebhook.yaml(打补丁的 Job)。
实战:哪些组件适合关闭自动挂载
结合各组件的职责可以推断合理的配置策略:
default-backend(最典型的关闭对象)。default-backend 只是静态返回 404/503 的简单后端,从源码结构看它不需要调用 Kubernetes API。关闭后即使该组件被攻破,攻击者也无法从 Pod 内窃取有效的 API 凭据:
defaultBackend: serviceAccount: automountServiceAccountToken: false控制器(需谨慎评估)。控制器依赖 API 凭据监听 Ingress、Service、EndpointSlice 等资源,仓库的控制器代码(
internal/ingress/controller/、internal/k8s/)大量使用 API Client,因此绝大多数场景应保持serviceAccount.automountServiceAccountToken: true;仅在使用 TokenRequest API、自动挂载方式由平台策略统一管控等场景下才考虑调整。webhook patch Job(临时组件)。该 Job 需要访问 API 以创建/修改 Secret 和 ValidatingWebhook,运行时间极短;如果集群策略要求"零自动挂载",可以评估将 Job 设为
false并同时确认其凭据获取方式,但默认保持true是安全的。
一个更完整的示例:
# values.yaml 片段 serviceAccount: create: true automountServiceAccountToken: true # 控制器需要 API 访问,保持开启 defaultBackend: serviceAccount: automountServiceAccountToken: false # 后端无需 API 访问,关闭 controller: admissionWebhooks: patch: serviceAccount: automountServiceAccountToken: true # patch Job 需要 API 访问渲染验证命令(在仓库外执行):
helm template ingress-nginx ./charts/ingress-nginx \ --set defaultBackend.serviceAccount.automountServiceAccountToken=false \ | grep -n automountServiceAccountToken测试证据:单元测试覆盖的断言行为
Chart 使用 helm-unittest 风格的 YAML 测试验证渲染结果,3.25.0 的变更配套了覆盖全部三个组件的测试:
- controller-serviceaccount_test.yaml:设置
serviceAccount.automountServiceAccountToken: false后断言渲染出的 ServiceAccount 中automountServiceAccountToken为false; - controller-deployment_test.yaml 与 daemonset 对应测试 controller-daemonset_test.yaml:断言
spec.template.spec.automountServiceAccountToken为false,证明 Pod 级字段确实随 values 变化; - default-backend-serviceaccount_test.yaml:default-backend SA 的同名断言;
- webhook patch 一侧:job-patchWebhook_test.yaml 与 serviceaccount_test.yaml 分别覆盖 Job Pod spec 与 SA 两层。
这些测试共同确认了双写实现的正确性:无论修改哪个 values 键,SA 模板与 Pod spec 模板会同步渲染出一致的值。
小结
ingress-nginx Helm Chart 3.25.0 的这条 changelog 对应一次典型的安全加固能力补齐:
- 新增
serviceAccount、defaultBackend.serviceAccount、controller.admissionWebhooks.patch.serviceAccount三组automountServiceAccountToken配置,默认均为true以兼容存量部署; - 实现上采用 ServiceAccount 级与 Pod spec 级双写,覆盖控制器 Deployment/DaemonSet、default-backend 以及 webhook patch Job 三类工作负载;
- 对无需 API 访问的组件(如 default-backend)建议显式置
false,以落实最小权限原则;控制器本身因依赖 API 凭据,应保持开启或依据平台统一策略评估; - 变更行为有完整的 helm-unittest 用例佐证,渲染结果可通过
helm template直接验证。
【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考