news 2026/9/12 21:57:32

Dapr 1.4.2 修复解析:sidecar-injector 准入 Webhook 阻断 Pod 创建的根因与排查方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dapr 1.4.2 修复解析:sidecar-injector 准入 Webhook 阻断 Pod 创建的根因与排查方案

Dapr 1.4.2 修复解析:sidecar-injector 准入 Webhook 阻断 Pod 创建的根因与排查方案

【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/dapr

导读

Dapr 1.4.2 是一个专注于修复 Sidecar 注入器(sidecar-injector)准入 Webhook 误伤问题的补丁版本。此前,当 Pod 由未在"允许的控制器账号"名单中的组件创建(例如 Tekton CICD 控制器创建 TaskRun Pod)时,sidecar-injector.dapr.io会直接拒绝该 Pod 的准入请求,导致 Pod 无法创建、CI 流水线整体失败。本文以 docs/release_notes/v1.4.2.md 为主线,结合仓库中注入器服务的源码实现(pkg/injector/service)与 Helm 配置(charts/dapr/charts/dapr_sidecar_injector/values.yaml),剖析该问题的根因、1.4.2 的修复策略,以及如何通过ALLOWED_SERVICE_ACCOUNTS配置自定义放行规则,帮助你在部署 Dapr 或接入 CI/CD 时快速定位同类准入错误。

背景:Sidecar 注入器与准入 Webhook

在 Kubernetes 上启用 Dapr 后,dapr-sidecar-injector服务以MutatingAdmissionWebhook的形式运行:任何带有dapr.io/enabled: "true"注解的 Pod 在创建时,其 AdmissionReview 请求都会被转发到注入器,由注入器判断是否需要注入 Dapr sidecar,并返回 JSON Patch 供 API Server 应用。这一入口逻辑位于 handler.go 的handleRequest中,处理链路依次为:

  1. 校验请求体的 Content-Type 与 AdmissionReview 解码;
  2. 仅处理Kind == "Pod"的请求;
  3. 通过 podHasDaprEnabled 判断 Pod 是否带有dapr.io/enabled注解,非 Dapr Pod 直接放行(respondWithAllowed);
  4. 对 Dapr Pod 执行请求方身份校验(isAuthorizedUser),通过后调用getPodPatchOperations生成注入补丁。

也就是说,注入器既是"注入器",也是 Pod 准入链路上的一个"关卡"——这正是 1.4.1/1.4.2 修复风暴的舞台。

问题现象:Pod 创建被 Webhook 直接拒绝

v1.4.2 的发布说明中明确指出修复了问题 #3709:

Sidecar-injector.dapr.io was blocking Pod admissions if sidecar could not be injected.

当某个控制器(Controller)代表工作负载创建 Pod、而注入器因身份校验无法为其注入 Dapr sidecar 时,Webhook 不是"跳过注入"而是"整体拒绝准入",最终导致 Pod 根本无法创建。发布说明给出的真实场景是使用Tekton CICD部署任务时的报错:

- lastTransitionTime: '2021-09-24T07:48:19Z' message: >- failed to create task run pod "function-sample-builder-cgmn8-buildrun-nfkb8-nlbjs": admission webhook "sidecar-injector.dapr.io" denied the request: service account 'system:serviceaccount:tekton-pipelines:tekton-pipelines-controller' not on the list of allowed controller accounts. Maybe invalid TaskSpec reason: CouldntGetTask status: 'False' type: Succeeded

这个报错的几个关键信息:

  • 请求方身份system:serviceaccount:tekton-pipelines:tekton-pipelines-controller,即 Tekton Pipeline 控制器在集群内使用的 ServiceAccount(Kubernetes 的UserInfo.Username格式);
  • 拒绝原因not on the list of allowed controller accounts,即该 ServiceAccount 不在注入器内置的"允许的控制器账号"名单中;
  • 业务影响:TaskRun Pod 无法创建,Task 状态变为CouldntGetTaskSucceeded=False),流水线失败。

问题的由来:1.4.1 修复 #3699 时引入了过度收紧

要理解 1.4.2 修复什么,必须先看 1.4.1。在 docs/release_notes/v1.4.1.md 中,1.4.1 修复了问题 #3699:使用kubectl debug调试节点(例如kubectl debug node/<node> -it --image=...)时,请求同样会触发注入器并报出admission webhook "sidecar-injector.dapr.io" denied the request: service account 'xxxxxxx' not on the list of allowed controller accounts

1.4.1 的修复方式是引入"允许的控制器账号"白名单机制:注入器只信任来自白名单控制器(如 deployment-controller、statefulset-controller 等)或系统管理员组(system:masters)的准入请求。但白名单天然存在覆盖不全的问题:任何不在名单内的控制器(Tekton、Argo、GitHub Actions Runner 等 CI 控制器)创建的 Pod 都会被误拒,这就是 #3709 的由来。1.4.2 正是在 1.4.1 允许注入 Dapr sidecar(修复 #3699)的基础上,把误伤导致的 Pod 创建阻断一并解决。

根因剖析:allowed controller accounts 机制与身份校验链

允许名单的源码定义

当前仓库中,内置的允许名单定义在 injector.go:

var AllowedServiceAccountInfos = []string{ "kube-system:replicaset-controller", "kube-system:replication-controller", "kube-system:deployment-controller", "kube-system:cronjob-controller", "kube-system:job-controller", "kube-system:statefulset-controller", "kube-system:daemon-set-controller", "openshift-operator-lifecycle-manager:olm-operator-serviceaccount", "tekton-pipelines:tekton-pipelines-controller", //nolint:misspell "mirrord:mirrord-operator", }

注意其中的tekton-pipelines:tekton-pipelines-controller——这正是 1.4.2 针对 #3709 场景补充的条目:Tekton 控制器创建的 Pod(TaskRun Pod)现在被视为合法请求方,不会再被拒绝。从中也可以看出 Dapr 后续版本持续在为各类控制器扩展这份名单(如 OpenShift OLM、mirrord)。

身份校验的完整调用链

请求方校验发生在handleRequest的这段逻辑(handler.go):

if !i.isAuthorizedUser(ar.Request) { log.Errorf("service account '%s' not on the list of allowed controller accounts", ar.Request.UserInfo.Username) diagAppID := getAppIDFromRequest(ar.Request) respondWithAllowed(w, ar, gvk) RecordFailedSidecarInjectionCount(diagAppID, "pod_patch") return }

isAuthorizedUser(handler.go)采用三重放行策略:

func (i *injector) isAuthorizedUser(req *admissionv1.AdmissionRequest) bool { return i.allowServiceAccountUser(req.UserInfo.Username) || utils.Contains(i.authUIDs, req.UserInfo.UID) || utils.Contains(req.UserInfo.Groups, systemGroup) }
  1. 按 ServiceAccount 名称匹配allowServiceAccountUser会先从Username中剥离system:serviceaccount:前缀(常量serviceAccountUserInfoPrefix,见 injector.go),取出namespace:name后交给namespaceNameMatcher匹配;
  2. 按 UID 匹配authUIDs是启动时通过 AllowedControllersServiceAccountUID 从集群中查询白名单 ServiceAccount 的真实 UID 集合(getServiceAccount会调用 Kubernetes API 列出 ServiceAccount 并解析其 UID,见 injector.go),作为名称匹配之外的第二道防线(defense-in-depth);
  3. 按用户组匹配:请求方若属于system:masterssystemGroup)则直接放行,这是管理员操作的兜底通道。

关键点:拒绝与"放行但不注入"的差异

值得对比的是:当前仓库代码在身份校验失败时调用的是respondWithAllowed(返回Allowed: true但不附带任何 Patch),同时记录一条RecordFailedSidecarInjectionCount指标。也就是说,注入器演进后的行为是"放行 Pod、跳过注入"而非"拒绝准入"——这与 1.4.2 修复前的"denied the request"行为不同。这一点印证了 1.4.2 修复的核心方向:注入失败不应阻断业务 Pod 的生命周期,Dapr 应该选择性地放弃注入而不是成为准入链路上的硬故障点。

匹配机制演进:从精确名单到 Glob 模式

1.4.2 时代的问题本质是"精确白名单覆盖不全"。当前仓库中,该机制已演进为基于 Gopath.Match的 Glob 匹配器,实现位于 serviceaccountmatcher.go:

  • 每个模式必须是namespace:name形式,且恰好包含一个冒号(多于一个或缺少冒号都会报错);
  • 命名空间与名称两个部分都支持 Glob 语法:*匹配任意字符序列、?匹配单个字符、[...]匹配字符集合;
  • 空字符串模式会被静默跳过;没有任何有效模式时返回一个恒为false的匹配器;
  • 多个模式之间是"或"的关系,任一命中即放行。

该行为在 serviceaccountmatcher_test.go 中有大量用例覆盖,例如:

模式请求方namespace:name结果
ns:sans:sa放行(精确匹配)
ns:sans:sa-extra拒绝(不做子串匹配)
ns-*:sa-*ns-foo:sa-bar放行(前缀通配)
ns-?:sans-A:sa放行(?匹配单字符)
ns-?:sans-AB:sa拒绝(?不匹配多字符)
ns:sa-[abc]ns:sa-b放行(字符类)
ns:sa-[abc]ns:sa-d拒绝(字符类不命中)

修复方案落地:如何配置自定义允许的控制器账号

1.4.2 修复的核心是把 Tekton 等已知 CI 控制器补进内置名单;而面对自建控制器或私有 CI,Dapr 提供了可配置的扩展点。

环境变量方式

注入器通过 config.go 中的envconfig读取环境变量:

  • ALLOWED_SERVICE_ACCOUNTS:以逗号分隔的额外允许 ServiceAccount 列表,格式为namespace:name,当前版本支持 Glob 通配;
  • ALLOWED_SERVICE_ACCOUNTS_PREFIX_NAMES:已弃用(Deprecated),其"尾缀*前缀匹配"语义已被ALLOWED_SERVICE_ACCOUNTS的 Glob 能力取代;若仍配置,会打印ALLOWED_SERVICE_ACCOUNTS_PREFIX_NAMES is deprecated; use ALLOWED_SERVICE_ACCOUNTS instead的警告日志(见 injector.go)。

这两项环境变量与内置AllowedServiceAccountInfos会在NewInjector中被合并为同一批匹配模式(injector.go)。

Helm 方式

在 Helm 安装时,可通过dapr_sidecar_injector子 chart 的 values 配置(values.yaml):

dapr_sidecar_injector: allowedServiceAccounts: "" allowedServiceAccountsPrefixNames: ""

对应模板会将值注入 Deployment 环境变量(dapr_sidecar_injector_deployment.yaml),chart 的 README.md 给出了三种典型写法:

  • my-ns:my-sa:精确匹配单个 ServiceAccount;
  • my-ns:*:放行某命名空间下的全部 ServiceAccount;
  • team-*:deploy-*:前缀通配,匹配多个团队/多个部署账号。

例如,为自建的 GitLab Runner(命名空间gitlab)放行:

dapr_sidecar_injector: allowedServiceAccounts: "gitlab:gitlab-runner"

或放行某个命名空间下所有控制器账号:

dapr_sidecar_injector: allowedServiceAccounts: "ci-runners:*"

匹配失败时的降级行为

结合 handler_test.go 中的用例(如TestSidecarInjectUserInfoNotMatchesServiceAccountPrefixTestSidecarInjectDefaultServiceAccountNearMissDenied),可以确认以下行为细节:

  • 精确名单不做子串匹配:kube-system:deployment-controller放行,但kube-system:deployment-controller-extra会被视为未授权(见TestSidecarInjectDefaultServiceAccountNearMissDenied,handler_test.go);
  • 未授权请求虽然 HTTP 返回 200、Pod 被放行,但不会注入 sidecar,并计入失败注入指标(RecordFailedSidecarInjectionCount),便于通过 Prometheus 监控发现"该注入而未注入"的 Pod(注入器指标定义见 metrics.go)。

测试与验证:如何在仓库中复现与确认

仓库内已为这套机制准备了完整的单元测试,可作为验证与回归依据:

  • handler_test.go:通过httptest直接向handleRequest发起 AdmissionReview 请求,覆盖成功注入、错误 Content-Type、非 Pod 类型、组不匹配、UID 匹配/不匹配、ServiceAccount 前缀匹配、内置名单精确匹配与"近似名拒绝"等十余个场景;
  • injector_test.go:TestAllowedControllersServiceAccountUID使用 fake Kubernetes Client 创建tekton-pipelines:tekton-pipelines-controller等 ServiceAccount,验证 UID 白名单的查询与解析逻辑(含配置有效/无效账号的用例);
  • serviceaccountmatcher_test.go:针对 Glob 匹配器本身的纯函数测试,覆盖通配符、字符类、非法模式报错、空模式恒拒绝等边界情况。

若要亲手验证,可在仓库根目录执行:

go test ./pkg/injector/service/...

升级与排障建议

围绕 #3709 这类"准入 Webhook 误伤",给出如下实操建议:

  1. 遇到denied the request: service account '...' not on the list of allowed controller accounts时,先定位请求方身份:报错中的system:serviceaccount:<namespace>:<name>即为创建 Pod 的控制器账号,确认该控制器是否需要创建 Dapr 注入的 Pod;
  2. 区分两类诉求:若该控制器创建的 Pod 根本不需要 Dapr(无dapr.io/enabled注解),则注入器本应直接放行;若确实需要注入,则应将账号加入ALLOWED_SERVICE_ACCOUNTS
  3. 优先使用通配而非逐个枚举:对于 CI 这类控制器账号动态变化的场景,ci-*:runner-*之类的 Glob 模式比维护精确名单更稳健;
  4. 升级到包含本修复的版本:1.4.2 将tekton-pipelines:tekton-pipelines-controller纳入内置允许名单,同时保持 1.4.1 对kubectl debug(#3699)的修复不回归;后续版本进一步将拒绝行为调整为"放行但不注入",从机制上消除了单点故障风险;
  5. 监控注入失败指标:即使 Pod 被放行,也要通过RecordFailedSidecarInjectionCount对应的注入失败指标关注"静默未注入"的 Pod,避免业务在无 sidecar 状态下运行。

总结

Dapr 1.4.2 通过将 Tekton Pipeline 控制器账号纳入 Sidecar 注入器允许名单,解决了 #3709 中"准入 Webhook 阻断 Pod 创建"的问题,是 1.4.1 引入白名单机制后的一次重要收敛。围绕这一修复,本文从 pkg/injector/service/injector.go、handler.go、serviceaccountmatcher.go 出发,还原了允许名单、身份校验链与 Glob 匹配机制的实现全貌,并给出了通过ALLOWED_SERVICE_ACCOUNTS/allowedServiceAccounts自定义放行规则的完整配置路径。理解这条准入链路的判定逻辑,是你在任何集群化 CI/CD 场景下排查 Dapr sidecar 注入问题的基础。

【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/dapr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 21:56:39

CAIL法律NLP实战:基于BERT的多任务模型构建与调参

简介&#xff1a;这份资源收录了中国法研杯司法人工智能挑战赛CAIL2018至2020年参赛源码与项目说明&#xff0c;面向具备一定Python和深度学习基础的算法学习者、竞赛参与者以及计算机相关专业学生。压缩包共1595个文件&#xff0c;以971个py源码文件、155个json配置、123个txt…

作者头像 李华
网站建设 2026/9/12 21:56:24

MIPI与SerDes技术解析:智能视觉系统数据传输核心

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 21:55:33

4G模组挂载为网卡:Linux下Socket网络通讯实战指南

1. 先把方案定下来&#xff1a;4G模组上网的几种路子作为常年和嵌入式Linux打交道的工程师&#xff0c;我在很多项目里都碰到过同一个需求&#xff1a;板子放在野外机房、车上或者偏远站点&#xff0c;没有网线&#xff0c;没有WiFi&#xff0c;唯一能联网的办法就是插一张SIM卡…

作者头像 李华
网站建设 2026/9/12 21:55:20

CMSIS-6:嵌入式开发的源码静态工程范式重构

1. CMSIS-6不是升级补丁&#xff0c;而是嵌入式开发范式的结构性重置CMSIS-6这个编号本身就有误导性。很多人第一反应是“CMSIS-5的下一个版本”&#xff0c;就像Linux内核从5.x升到6.x那样平滑过渡。但实际完全不是——CMSIS-6是一次彻底推倒重来的架构重构&#xff0c;它不再…

作者头像 李华
网站建设 2026/9/12 21:55:18

STM32驱动MLX90614红外测温:SMBus时序、PEC校验与发射率修正实战

简介&#xff1a;一款面向毕业设计与课程实训的STM32红外测温项目源码&#xff0c;聚焦MLX90614非接触测温模块的驱动开发与软硬件联调&#xff0c;适合电子、通信、自动化等专业学生及嵌入式入门开发者使用。代码按HARDWARE、SYSTEM、CORE、USER等目录分层&#xff0c;包含完整…

作者头像 李华
网站建设 2026/9/12 21:55:04

Python+微信小程序构建家电维修系统实战

1. 项目概述&#xff1a;Python微信小程序构建家电维修系统这个家电维修售后系统本质上是一个连接用户、维修师傅和商家的三方平台。用户通过微信小程序提交报修订单&#xff0c;维修师傅接单处理&#xff0c;商家管理库存和配件&#xff0c;而Python后端负责协调整个业务流程。…

作者头像 李华