1 K8s 安全要回答什么
订单 API 已经能在 Kubernetes(下文简称 K8s)中运行:Deployment 维持副本,Service 提供稳定入口,Pod 连接数据库并输出日志。接下来要问的是:谁能修改这些对象,程序能访问哪些集群资源,遭到入侵后影响会扩散到哪里,以及我们凭什么确认限制生效。服务可用只说明请求能完成,不能说明每条访问路径都有合适的边界。
先区分业务请求与管理请求。顾客查询订单,通常经过业务入口到达应用,再由应用访问数据库;运维人员执行 kubectl,则向 API Server 发出管理请求。ServiceAccount 令牌主要用于访问 K8s API,不能直接替代顾客登录凭证。反过来,顾客通过应用登录,也不应因此获得修改 Deployment 的能力。把这 2 条路径混在一起,容易在错误的位置配置权限。
本课采用这样的场景:命名空间 shop 中有订单 API,应用需要连接订单数据库,但正常处理订单时不需要读取 K8s API。另有排障人员需要查看该命名空间的 Pod 状态。前者应减少集群凭证暴露,后者应获得明确的读取权限。发布人员、排障人员和应用进程承担不同职责,即使它们服务于同一个业务,也不应共享管理员身份。

可以从 5 个问题检查部署。身份回答“你是谁”;授权回答“你能操作什么”;准入回答“这次对象变更是否符合要求”;网络边界回答“哪些连接允许建立”;运行时与可观测性回答“程序实际做了什么,异常能否被发现”。这些控制相互补充。例如,拒绝应用读取 Secret,并不会自动阻止它通过网络访问数据库;限制数据库连接,也不会收回已经授予应用的集群管理权限。
安全目标不宜写成“保证集群绝对安全”。更可执行的目标是:订单 API 默认不持有集群 API 凭证,排障身份只能读取指定资源,跨服务连接按依赖开放,异常权限变更能够追溯。这样才有对象、动作和验证方法。命名空间可以组织对象和划定部分策略作用范围,但它本身不保证网络隔离,也不等同于完整的租户安全边界。
本课先覆盖应用团队能够理解和核对的控制。控制面证书体系、内核隔离实现和复杂攻击技术留给后续专题。入门阶段更重要的能力,是把实际需求翻译成可检查的限制,并知道每种限制没有覆盖哪里。
2 RBAC、ServiceAccount 与鉴权边界
访问 API Server 时,先认证,再授权。认证确认请求对应哪个身份,例如某位使用企业登录的运维人员,或某个命名空间中的 ServiceAccount。授权检查该身份是否可以对目标资源执行指定动作。RBAC 是 K8s 常用的授权机制,其核心是规则与绑定:规则定义能力,绑定把能力交给身份。请求通过授权后,对需要准入处理的请求,还会继续接受准入检查。
Role 在指定命名空间中声明权限。例如,允许读取 shop 中的 Pod,不代表可以读取另一个命名空间的 Pod。RoleBinding 把角色授予用户、组或 ServiceAccount。ClusterRole 可以描述集群范围资源的权限,也能保存可复用的命名空间资源规则;通过 RoleBinding 引用它时,相应权限仍受绑定所在命名空间约束。ClusterRoleBinding 则在集群范围授予其引用的角色权限,使用时必须明确为什么需要这个范围。
规则通常需要核对 apiGroups、resources、verbs,有些场景还会用到 resourceNames。Pod 属于核心 API 组,因此 apiGroups 使用空字符串。get 表示读取指定对象,list 表示列出对象,watch 表示持续接收变化。它们不是“读权限”这个模糊词的自动组合。读取 Pod 日志需要考虑 pods/log 子资源;进入容器通常涉及 pods/exec 子资源,不能仅凭“都是排障”就与状态读取打包授予。

ServiceAccount 是供工作负载使用的集群身份,属于某个命名空间。Pod 可以通过 serviceAccountName 选择它。如果应用不访问 K8s API,通常应关闭服务账号令牌的自动挂载。关闭挂载不等于删除身份,也不等于网络断开;它减少的是容器中可直接取用的 API 凭证。若应用确实要调用 API,应创建专用账号,再只授予所需资源和动作。
这里还要避免把云平台 IAM 与 K8s RBAC 当作同一套规则。应用访问对象存储可能使用云身份,访问 K8s API 则接受集群的认证和授权。某些环境可以建立身份联动,但授权边界仍需分别核对。拥有集群中的 ServiceAccount,不自动意味着可以读取云存储;拥有云账号权限,也不说明可以修改某个命名空间里的工作负载。
RBAC 权限通常是叠加的,不能指望再创建一个“较小的 Role”抵消已有的大权限。某个身份同时绑定只读角色和管理员角色时,实际能力仍包含管理员权限。因此最小权限检查必须查看所有相关绑定及组成员关系。更隐蔽的是间接权限:能够创建工作负载、选择高权限 ServiceAccount 或挂载敏感数据,有时也能获得原本没有直接授予的能力。
交互中应先判断身份和命名空间,再看角色规则,最后合并所有有效绑定。不要看到 Role 名称含有 reader 就结束检查,名称只是说明文字,真正执行的是规则。也不要把“可以读取 Pod”理解为“只能看无害信息”:对象字段、镜像地址和环境配置也可能暴露部署细节,日志中还可能含有业务敏感信息。
3 准入控制、策略与运行时防护
授权解决了谁有资格提交操作,却没有完整描述一个工作负载可以长成什么样。假设发布身份允许创建 Deployment,它提交的 Pod 模板可能要求以特权方式运行,也可能挂载宿主机目录。RBAC 可以允许“创建 Deployment”,但一般不直接表达“可以创建普通容器,不能创建带这些危险字段的容器”。准入控制在对象写入前补上这类检查。
准入处理可以对请求进行修改,也可以验证并拒绝请求。修改型处理可能补充默认字段,验证型处理则检查最终对象是否符合策略。入门时可以把它理解为提交配置时的门禁:有提交资格,还要通过配置要求。读取对象的请求通常不经过这类写入准入过程,因此不能把准入当作保护所有 API 读取的通用过滤器。
Pod Security Admission 是理解基线策略的合适起点。它可以按命名空间实施 Pod Security Standards 中的要求,常见级别包括 privileged、baseline、restricted。这里的 privileged 表示不施加该套限制,不能因为名称出现“安全标准”就把它当作推荐目标。restricted 对运行用户、权限提升、能力和其他字段有更严格的要求,具体要求与集群采用的版本有关。
实际迁移可以先收集告警和审计反馈,再在试验命名空间启用强制拒绝,确认业务可运行后扩大范围。warn 提醒提交者,audit 提供审计标注,enforce 才承担阻止不合规 Pod 的作用。不同工作负载控制器的提交与最终创建 Pod 是不同阶段,验收应观察最终 Pod 是否被允许创建,以及控制器的事件和状态,不能只看 Deployment 提交成功。

策略需要落到字段。例如,应用容器通常应设置 allowPrivilegeEscalation 为 false,按需要丢弃 Linux capabilities,并使用符合环境要求的 seccomp 配置。能够以非 root 用户运行的应用,应在镜像与安全上下文中明确落实。只读根文件系统可减少容器内随意写入,但应用需要临时目录时,要为它提供明确的可写卷。只增加限制而没有验证启动与健康检查,可能把安全变更变成可用性故障。
运行时防护关注容器已经启动之后的活动,例如异常进程、可疑文件访问或不符合预期的外连。容器并不是天然完美的隔离边界,还依赖节点、内核、运行时与配置共同工作。应用团队应减少特权容器、宿主机目录和不必要的主机命名空间共享,同时与平台团队明确节点修补责任。复杂检测规则和内核机制不在本课展开。
还需记住时间边界。更新准入策略通常不会自动修复已经运行的 Pod;收紧某项配置,也不代表旧副本已经替换。安全发布需要检查现有对象,安排替换,并观察最终状态。策略例外应说明业务原因、责任人和到期条件,避免用一个永久宽松的命名空间承载所有“暂时不能改”的应用。
4 动手:核对一次最小权限角色绑定
下面把“排障身份可以读取 shop 中的 Pod 状态”变成可复核的配置。练习仅在有权限使用的测试命名空间进行。示例假设 shop 已存在;用于执行命令的身份需要有创建这些对象及进行身份模拟的适当权限。创建 ServiceAccount 是为了让练习的主体清晰可见,不表示真实排障人员必须使用应用账号登录。
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-status-reader
namespace: shop
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-status-reader
namespace: shop
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-status-reader
namespace: shop
subjects:
- kind: ServiceAccount
name: pod-status-reader
namespace: shop
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-status-reader
将配置保存为 pod-status-reader.yaml,再提交到测试集群。RoleBinding 的 metadata.namespace 决定绑定作用的位置,subjects 中的 namespace 则用来定位服务账号。这 2 个字段含义不同,核对时不能只确认名字拼写相同。roleRef 指向授予的角色;要换到另一角色时,应按受控变更流程处理,而不是假设可以任意修改已有引用。
kubectl apply -f pod-status-reader.yaml
kubectl auth can-i list pods -n shop --as=system:serviceaccount:shop:pod-status-reader
kubectl auth can-i delete pods -n shop --as=system:serviceaccount:shop:pod-status-reader
kubectl auth can-i get secrets -n shop --as=system:serviceaccount:shop:pod-status-reader
kubectl auth can-i list pods -n default --as=system:serviceaccount:shop:pod-status-reader
在没有额外授权的前提下,预期依次是 yes、no、no、no。这组检查同时覆盖允许项、危险动作、敏感资源和跨命名空间范围。只做第 1 项,只能证明该操作被允许,不能证明权限已经足够小。若结果与预期不同,应先核对当前集群上下文、主体名称及全部绑定,再检查是否存在其他授权机制带来的权限。
这里的 --as 是身份模拟,不是创建或取得目标账号的令牌。命令执行者若没有模拟权限,检查可能因模拟被拒而失败,这与目标角色是否允许读取 Pod 是不同的问题。身份模拟也不等于完整复现实际登录中的所有组信息;实际用户或复杂身份场景,还应通过获准的真实认证路径验证。

can-i 检查回答授权问题,不证明网络可达、业务正常或准入策略接受对象。因此记录结果时,应写“该身份获准列出 shop 的 Pod”,而不要写成“安全测试通过”。练习结束后,可删除本次创建的绑定、角色和账号,避免测试对象变成长期无人维护的权限入口。业务验收还应补充一次真实只读调用,并确认审计记录能够定位到预期主体。
5 网络策略与密钥挂载取舍
订单 API 不需要 K8s API 权限,仍需要接收入口流量并连接数据库。NetworkPolicy 用来描述选中 Pod 的允许连接,必须有支持其执行的网络插件才会产生预期效果。只创建策略对象而没有执行能力,可能得到“配置存在、流量照通”的假象。验证应从真实流量结果入手,同时向平台确认支持的规则范围。
NetworkPolicy 按命名空间中的 Pod 标签选择目标,并分别处理 ingress 入站与 egress 出站。当 Pod 在某个方向被策略隔离后,该方向仅允许匹配规则的流量;多个适用策略的允许规则通常取并集。因此,新增一条较窄规则不一定能收紧已有宽规则。没有适用隔离策略的方向,也不能因为另一个方向已限制就被视为受保护。
对订单 API,可以先列出业务依赖:接受入口组件转来的业务请求,连接订单数据库,按环境访问 DNS 和遥测接收端。再建立默认拒绝与必要放行规则。若源 Pod 的出站和目标 Pod 的入站都受到隔离,连接要同时满足两端规则。数据库在集群外时,目标地址、地址转换和网络插件能力可能影响规则含义,需要在实际环境验证,不能照抄一个 Pod 选择器就宣告完成。

标签是网络规则的重要输入,也会成为权限设计的一部分。若任意发布者都能修改关键标签,原本按标签划分的信任范围就可能被绕开。namespaceSelector 与 podSelector 的组合也要读懂:放在同一个规则项中通常表示共同匹配,拆成不同规则项则可能扩大允许集合。网络策略主要面向网络层连接,不能替代业务登录、接口鉴权和传输加密。
Secret 则用于承载密码、令牌等敏感值。其数据常见的 Base64 表示只是编码,不是加密。还需要核对存储时加密、API 读取权限、备份保护和日志脱敏。订单 API 需要数据库密码,不意味着它需要 get 或 list 所有 Secret;由平台把指定 Secret 挂载给容器,与应用自行调用 API 搜索 Secret,是不同的权限需求。
在挂载方式上,环境变量接入简单,但运行中的进程通常不会自动得到后续 Secret 更新,需要安排重启或其他更新机制。卷挂载有利于程序按文件读取;普通 Secret 卷的更新存在传播延迟,应用仍要支持重新读取,使用 subPath 挂载时也不能期待自动获得更新。无论哪种方式,能在容器中读取秘密的进程通常就能取得明文,挂载方式不是防止应用自身泄露的保险箱。
滑块把“应用依赖范围”作为输入,展示从无 API 需求到指定读取需求时,应增加哪些明确配置。它不把宽权限包装成性能优化,也不输出虚构的安全分数。选择应依据实际功能:不需要 API 就关闭令牌挂载;确实需要时使用专用账号与有限权限;短期兼容遗留程序则记录例外、观测使用情况并制定收缩计划。
数据库凭证还要有轮换与撤销路径。可以先准备新凭证,让应用加载并验证连接,再撤销旧凭证,同时确认连接池行为和失败告警。仅仅更新 Secret 对象并不代表旧密码已经失效,轮换完成应以数据库端和应用端证据共同确认。
6 常见坑:cluster-admin 图省事
最常见的失误不是完全没有配置 RBAC,而是为了解决一次报错,把身份绑定到 cluster-admin,然后再也没有收回。这个内置角色拥有非常广泛的集群权限。对一个只需要读取 Pod 状态的工具而言,它扩大了可修改的对象与作用范围,也让工具漏洞、错误脚本或令牌泄露更容易变成集群级事故。
遇到 Forbidden,应先读清主体、资源、动作和命名空间。工具需要 Pod 日志,就核对 pods/log;需要观察 Deployment,就核对相应 API 组与资源。不要从“读取 Pod 仍报错”直接跳到管理员权限。有些报错发生在启动发现阶段,有些来自真正的业务功能,应该区分必要功能与可关闭的附加行为,再决定授权。
另一个坑是使用通配符。例如 resources 或 verbs 中的星号会把范围扩大到当前及未来符合条件的资源或动作。现在看起来没有敏感对象,不代表以后也没有。只读权限也不必然低风险:能够读取所有 Secret 的只读账号,可能直接获得访问数据库或外部系统的凭证。最小权限关注数据敏感性和可造成的影响,不只区分“读”和“写”。

不要把 default ServiceAccount 当成团队共享权限容器。一个命名空间里多个应用若都使用它,后来给它增加权限,可能同时影响许多未参与变更的 Pod。更清楚的做法是按工作负载职责分配账号,并检查现有 Pod 实际引用的身份。删除某个 RoleBinding 后,也要核对其他绑定,避免把“删掉了这条”误认为“相关能力已经完全消失”。
紧急处置可以有临时提权,但应使用可追溯的主体,写明作用范围、到期时间和撤销责任人。若流程没有自动到期机制,就必须安排可执行的回收步骤,不能只在文档里写“临时”。审计日志应覆盖敏感权限变更与相关调用,并选择合适的记录级别,避免为了排障把 Secret 正文或令牌写进日志。
收紧权限也要照顾业务连续性。先在测试环境验证必要操作,再逐步替换绑定,观察明确的拒绝与业务指标。如果靠一次没有报错的发布就认定权限足够,定时任务、故障恢复和少见的轮换流程可能在之后才失败。可以按业务周期收集使用证据,但“曾经用过”仍不等于“永远需要”,每项权限都应能解释用途。
7 案例:挂载服务账号令牌被滥用
考虑一个教学案例。订单 API 使用 default ServiceAccount,容器中自动挂载了访问集群 API 的令牌。为了方便早期调试,这个账号又被授予读取 shop 中所有 Secret 的权限。后来应用出现可读取进程可访问文件的漏洞,攻击者拿到令牌,并从可达的网络位置调用 API。漏洞是入口,过量授权和可用凭证则把影响扩大了。
攻击者先读取挂载文件,再以服务账号身份发起请求。API Server 认证成功后,按已有 RBAC 规则允许其读取 Secret。数据库凭证随后泄露,攻击路径从应用容器延伸到数据系统。整个过程中,请求可能在认证和授权层都属于“合法身份被允许的操作”,所以不能把没有认证失败日志当成没有攻击的证据。
交互逐步展示每个必要条件:应用文件读取漏洞、容器可取用的令牌、API 网络可达、读取 Secret 的权限以及数据库凭证仍有效。任何条件变化都可能影响后续路径,但不能把一个控制宣传成覆盖所有分支。例如,关闭令牌自动挂载可以阻断这条凭证来源,却不能阻止攻击者读取本来就挂载给应用的数据库密码。
排查先确定受影响的 Pod、命名空间、ServiceAccount 与时间窗口,再查看该主体的敏感 API 调用、权限绑定变化和数据库异常访问。业务日志未必包含 API 调用,网络记录也未必能说明读取了哪个资源,因此需要把审计事件、工作负载状态和数据系统日志关联起来。只看到源地址时还要考虑代理和地址转换,避免把地址直接等同于某个操作者。
处置需要同时限制继续访问与保护数据。可以隔离受影响工作负载、撤销多余授权、停止使用已暴露的凭证并轮换数据库密码,同时保留必要证据。具体顺序取决于业务影响和现场流程。不能因为令牌带有有效期就等待它自然过期;令牌类型、对象绑定和撤销机制存在差异,应由平台确认并通过实际拒绝结果验证处置生效。
恢复时,订单 API 改用专用账号并关闭令牌自动挂载,数据库凭证只提供给需要它的容器,业务漏洞得到修复,网络依赖按需放行。随后复查新 Pod 的实际挂载与身份,确认旧权限已经回收,数据库旧凭证不能再用。仅修改 Deployment 模板还不够,要确认旧副本已经退出服务。
复盘应把责任落实为可验证的改进:发布前检查账号与权限,新增敏感绑定触发复核,秘密读取异常能够告警,凭证轮换有演练记录。根因描述也应区分漏洞入口、权限放大与检测缺口。这样才能解释事故为什么扩大,而不是只留下“加强安全意识”这样的口号。
8 把身份与策略写进集群安全方案
集群安全方案应从访问关系开始写。对订单 API,列出发布身份、排障身份、应用身份和平台管理身份,分别写明能访问什么对象、执行什么动作、在哪个范围内有效。应用没有调用 K8s API 的需求,也是一项需要落地的结论:专用账号、关闭自动挂载,并检查不存在其他注入凭证的路径。
每条要求都要配证据。RBAC 用规则、绑定和允许/拒绝检查证明;准入策略用不合规测试对象的拒绝结果及合规工作负载的启动结果证明;网络策略用实际允许与拒绝的连接测试证明;密钥轮换用新凭证成功、旧凭证失效和应用恢复结果证明。不要用“已部署某组件”替代控制效果,因为配置存在与实际执行之间可能有缺口。
方案还应交代资源归属。平台负责哪些集群级策略和审计能力,应用团队负责哪些容器安全上下文、依赖清单与日志脱敏,数据团队如何配合数据库账号轮换。责任边界有助于发现空白,例如大家都以为别人维护审计留存,最后没有可用证据。这里不需要罗列复杂组织结构,只要每项关键控制都有明确维护者。
策略例外要与正常要求一起管理。若某个遗留任务暂时需要较宽权限,应写清具体动作、涉及资源、补偿限制、到期条件与替代计划。不能只标记“历史原因”。例外更新时要重新评估,不能随着应用版本发布自动无限续期。对于跨命名空间或集群级权限,尤其应说明为什么命名空间内的角色不能满足需求。
验收要兼顾正常路径与拒绝路径。订单能够创建,说明业务依赖可能齐全;测试账号无法读取 Secret、应用无法连接未授权目标,才能为限制提供另一侧证据。测试应使用专门的测试数据与获准环境,避免把真实秘密打印出来充当成功证明。记录命令、对象版本、时间和结果即可,不必在报告中保存凭证正文。
最后给方案安排复查触发条件:新增外部依赖、修改服务账号、增加角色绑定、调整 Pod 安全要求或升级网络插件时,都可能改变原有结论。定期复查也应关注闲置账号、无人负责的例外和长期未轮换的凭证。安全方案是一套随部署更新的约束与证据,不是上线当天签完字就结束的说明书。
9 从K8s 安全走向Helm 与应用交付(C34)
前面的控制已经落实为不少对象和字段:ServiceAccount、Role、RoleBinding、NetworkPolicy、Secret 引用,以及 Pod 模板中的安全上下文。手工维护时容易出现环境差异,例如测试环境关闭令牌挂载,生产模板却遗漏;或者角色规则更新了,绑定仍然指向旧角色。下一课的 Helm 与应用交付,将讨论如何把相关配置组织成可重复生成、审阅和升级的交付单元。
Helm 能帮助管理配置,但不会自动判断权限是否合理。模板中写着 cluster-admin,渲染后仍然是宽权限;values 允许任意开启特权模式,也可能把危险选项传播到多个环境。安全检查应面向渲染后的实际清单,确认资源范围、身份引用和最终字段,而不只阅读默认参数。部署结果仍需要集群中的策略和运行证据来验证。
交付身份自身也需要权限边界。发布工具能够安装应用,不代表它应管理整个集群的角色绑定。若交付包含集群级资源,应说明由谁安装、如何审核,以及普通应用发布是否需要重复修改这些资源。不要为了让安装命令一次成功,就把所有权限集中到长期使用的自动化凭证上。
升级与回滚还会带来时间上的问题。应用版本回退,不应无意恢复已经撤销的高权限配置;秘密值也不宜直接写入可广泛读取的参数文件。进入 C34 前,先带上本课的权限清单、网络依赖、准入要求和验收证据。后续讨论交付时,就能问清每次变更究竟增加了哪些能力,以及失败后怎样恢复到经过验证的状态。
放进方案里
订单 API 部署在 shop 命名空间,使用独立 ServiceAccount。正常业务不调用 K8s API,因此关闭服务账号令牌自动挂载,并在发布后检查实际 Pod。排障身份通过命名空间内的 RoleBinding 获得 Pod 状态读取权限;日志读取按职责单独评估,不授予 Secret 读取、容器执行或集群管理权限。权限验收同时记录允许读取状态、拒绝删除 Pod、拒绝读取 Secret 与拒绝跨命名空间访问的结果。
工作负载遵循约定的 Pod 安全基线,明确运行用户、权限提升限制与必要的可写目录。策略先在测试环境验证,生产执行时检查最终 Pod 状态及拒绝事件。网络插件须支持所用 NetworkPolicy;订单 API 只接受入口组件的业务连接,并按实际依赖放行数据库、DNS 与遥测流量。验收包含必要连接成功和未授权连接失败,标签变更纳入发布审阅。
数据库凭证由指定 Secret 提供给所需容器,业务日志不得记录明文。方案写明应用加载更新的方式,以及新凭证验证、旧凭证撤销和连接池恢复的步骤。平台团队负责集群审计与基线维护,应用团队负责账号引用、依赖清单和脱敏,数据库维护者负责凭证撤销。异常 Secret 读取与敏感绑定变更应可追溯,并按已约定渠道触发处置。
每次变更账号、角色、网络依赖或安全上下文,都重新检查渲染清单与实际状态。例外需记录具体范围、责任人和到期条件;紧急提权要有回收证据。发生凭证暴露时,按隔离、收回权限、撤销相关凭证与确认恢复的流程处置,并保留必要审计证据。交付验收以可观察的业务结果和拒绝结果为依据。验收记录须注明集群、命名空间、测试主体和策略版本;审计样本应能关联该主体读取指定资源的请求与授权结果,且不包含令牌或 Secret 正文。
10 小结:下一步Helm 与应用交付(C34)
K8s 安全需要把身份、授权、准入、网络、秘密与运行时观察连接起来。身份可信不代表权限合理,配置提交成功不代表 Pod 合规,策略对象存在也不代表流量已经受限。每项要求都应有作用范围、维护者和验证证据。
继续前可以自测:订单 API 不访问集群 API 时,为什么仍应检查令牌挂载?给账号增加只读 Role,为什么不能抵消已有管理员权限?Secret 更新后,怎样证明旧凭证确实失效?如果能够分别从凭证暴露、权限叠加与轮换证据回答,就可以带着这些约束进入 C34,把安全要求纳入 Helm 与应用交付。