集群升级如何设计安全验证证据链?
Kubernetes 控制面与节点版本偏移安全评估:准入、运行时与网络插件行为核验
集群升级期间最容易出现的误判,是把“组件能起来”当作“安全控制仍然有效”。控制面、新旧节点、容器运行时和网络插件可能短暂处于不同版本,API 服务器接受的 Pod 符合准入规则,但节点上的运行时默认值、内核限制和网络策略执行结果未必一致。策略对象和配置文件都还在,部分工作负载却已经失去预期保护——这种落差才是升级验证真正要防的东西。
验证证据链的起点不是测试,而是基线。升级前需要把“版本偏移是否被支持”和“安全行为是否一致”分开处理:前者依据官方版本偏移策略、升级路径和插件兼容性文档判断,后者只能在实际集群中测出来。节点处于 Ready 状态,不能作为升级安全的证据。
基线应覆盖四类对象。准入侧记录各 API 服务器实例的启动参数、准入配置、命名空间标签与豁免项;运行时侧记录节点版本、运行时版本与配置、kubelet 安全相关配置以及 RuntimeClass;网络侧记录 CNI 与策略引擎版本、节点覆盖情况;业务侧记录关键服务依赖、DNS、健康检查和流量基线。记录变更前的恢复方式时,含凭据的配置不应直接写进工单或普通日志。
准入验证要按实例做,而不是按集群做。Pod Security Admission 在 API 服务器侧执行,节点版本不同并不意味着准入决策分散在节点上。因此测试需覆盖每个 API 服务器实例的决策结果,再单独覆盖被接受的 Pod 在各节点上的实际运行效果。用服务端试运行验证预期允许和预期拒绝两类清单,记录请求身份、命名空间标签、响应与审计事件。负载均衡后的一次成功不能证明所有实例一致;同时要区分 PSA 拒绝与其他准入 Webhook 的拒绝,不能把所有失败都归因于同一处。
试运行只证明准入,不证明节点执行。对预期允许的测试 Pod,应实际部署到目标节点,比较最终结果而非 YAML。重点看三件事:显式 securityContext 与节点默认值分别表现如何;配置文件是否已被当前进程加载;容器内可观测的进程身份、能力集和 seccomp 状态。再设计本应被拒绝的最小操作作为功能性负例,排除镜像、用户权限和文件系统差异造成的假阳性。
网络策略的验证同理,创建对象不等于策略生效。在隔离命名空间中按新旧节点组合构造源与目标矩阵,分别测试允许与拒绝路径,覆盖实际使用的协议和端口,必要时区分入口与出口。判断拒绝是否有效前,先确认服务端正在监听、路由和名称解析正常——连接超时可能来自故障路由,而不是策略阻断。
分批升级时,把上述测试设为放行条件。每批完成后重跑对应节点组合的准入、运行时和网络用例,保存节点名称、组件版本、测试时间、请求身份与实测结果。出现预期拒绝被接受、受限流量可达或关键节点缺少策略执行能力时,暂停扩批,而不是因为业务暂时可用就继续推进。回滚同样要按组件分别定义并提前演练,控制面降级可能受版本与存储兼容性限制,不能默认可行。
证据链的价值在于可复核:每一批升级都能回答“谁在什么版本上、用什么请求、得到了什么结果、与基线差在哪里”。做到这一步,版本偏移才从一次兼容性检查,变成可追溯的安全控制一致性验证。

参与讨论
组件起来不等于安全有效,这个点太真实了