1. 问题现象与初步诊断
最近在Kubernetes集群中部署Kubewarden策略服务器时,遇到了一个棘手的问题——策略服务器因Rekor密钥错误而崩溃。具体表现为PolicyServer Pod不断重启,日志中持续出现类似如下的错误信息:
error verifying Rekor entry: failed to verify signature: failed to verify signature on entry: verifying tlog entry: verifying checkpoint: error verifying checkpoint: error verifying root hash: invalid root hash这个错误直接导致整个策略服务器无法正常工作,所有依赖该服务器的准入控制策略都无法执行。作为集群安全的关键组件,这种崩溃会严重影响集群的安全防护能力。
从错误信息可以明确看出,问题与Sigstore项目中的Rekor组件有关。Rekor是Sigstore的透明日志服务,负责记录所有软件制品的签名元数据。Kubewarden在验证策略时,会通过Rekor来验证策略镜像的签名记录。当Rekor的信任链(TUF元数据)验证失败时,就会抛出上述错误。
2. Rekor与TUF信任机制解析
要理解这个问题的本质,我们需要先了解Sigstore的信任机制。Sigstore使用The Update Framework (TUF)来管理其组件的信任根。TUF是一个用于软件更新系统的安全框架,它通过多层签名和周期性密钥轮换来保证元数据的安全性。
在Sigstore架构中:
- Rekor作为透明日志服务,会定期发布包含所有记录摘要的检查点(checkpoint)
- 这些检查点由Rekor的私钥签名,并通过TUF元数据链进行验证
- 客户端(如Kubewarden)会从TUF仓库获取最新的信任根,用于验证Rekor提供的数据
当这个信任链中的任何一个环节出现问题(如密钥不匹配、元数据过期或被篡改),就会导致验证失败。在我们的案例中,错误信息明确指出了"invalid root hash",说明TUF根哈希验证失败。
3. 问题根因分析
经过深入排查,我们发现导致这个问题的可能原因包括:
3.1 TUF元数据过期或不同步
Sigstore的TUF元数据有一定的有效期(通常为几个月)。如果客户端长时间没有更新本地缓存的TUF元数据,可能会导致使用过期的根密钥进行验证。特别是在以下场景:
- 集群网络策略限制了对外部TUF仓库的访问
- 节点时间不同步,导致客户端认为TUF元数据已过期
- 本地缓存被意外清除或损坏
3.2 使用了自定义/私有Sigstore实例
如果集群配置为使用私有Sigstore实例(而非默认的public good实例),但未正确配置相应的ClientTrustConfig,就会导致Kubewarden仍然尝试使用默认的信任根去验证私有实例的数据,从而引发密钥不匹配。
3.3 Rekor实例密钥轮换未正确传播
Sigstore组件会定期进行密钥轮换以增强安全性。如果Rekor实例完成了密钥轮换,但客户端没有及时获取新的TUF元数据,就会使用旧密钥验证新签名,导致验证失败。
4. 解决方案与实施步骤
针对上述根因,我们提供以下解决方案:
4.1 强制更新TUF元数据
对于使用默认Sigstore实例的情况,最简单的解决方法是强制Kubewarden更新本地的TUF元数据:
- 首先删除PolicyServer Pod,触发重建:
kubectl -n kubewarden delete pod -l app=kubewarden-policy-server- 验证新Pod日志,确认是否成功获取最新TUF元数据
如果问题依旧,可以尝试清除整个集群的TUF缓存。对于使用containerd作为容器运行时的集群:
# 在每个节点上执行 sudo rm -rf /var/lib/containerd/io.containerd.content.v1.content/ingest/* sudo systemctl restart containerd4.2 配置私有Sigstore实例的正确方法
如果使用私有Sigstore实例,必须正确配置ClientTrustConfig。以下是详细步骤:
- 准备ClientTrustConfig JSON文件。假设私有实例的TUF根位于https://private-sigstore.example.com/tuf/metadata:
{ "sigstore": { "mirror": "https://private-sigstore.example.com", "root": "/path/to/custom-root.json", "tufCachePath": "/tmp/tuf" } }- 在kubewarden命名空间创建ConfigMap:
kubectl -n kubewarden create configmap client-trust-config --from-file=config.json=client-trust-config.json- 修改PolicyServer配置,添加volume挂载:
apiVersion: policies.kubewarden.io/v1alpha2 kind: PolicyServer metadata: name: default spec: image: ghcr.io/kubewarden/policy-server:v1.7.0 volumes: - name: client-trust-config configMap: name: client-trust-config volumeMounts: - mountPath: /config name: client-trust-config env: - name: CLIENT_TRUST_CONFIG_FILE value: /config/config.json4.3 处理密钥轮换场景
对于密钥轮换导致的问题,需要确保:
- 所有客户端能够访问TUF仓库获取最新元数据
- 在密钥轮换过渡期,配置客户端同时信任新旧密钥
- 监控TUF元数据的有效期,提前规划密钥轮换
可以通过以下命令验证当前使用的TUF根信息:
kubectl -n kubewarden exec <policy-server-pod> -- \ curl -s https://tuf-rekor.sigstore.dev/root.json | jq .signed5. 验证与监控
实施解决方案后,需要进行全面验证:
- 检查PolicyServer Pod日志,确认不再出现Rekor验证错误
- 测试策略执行功能,确保准入控制正常工作
- 设置监控告警,捕获类似验证错误
建议在集群中部署以下监控指标:
kubewarden_policy_server_verify_duration_seconds:策略验证耗时kubewarden_policy_server_errors_total:按错误类型分类的错误计数kubewarden_policy_server_tuf_updates_total:TUF元数据更新次数
6. 预防措施与最佳实践
为避免类似问题再次发生,建议采取以下预防措施:
- 定期更新策略服务器:保持Kubewarden组件为最新版本,确保包含最新的TUF信任根
- 网络访问控制:确保策略服务器Pod能够访问所需的Sigstore端点:
- rekor.sigstore.dev (或私有实例地址)
- tuf-rekor.sigstore.dev (或私有TUF仓库)
- fulcio.sigstore.dev
- 时间同步:确保所有节点时间与NTP服务器同步,防止证书验证问题
- 缓存管理:监控containerd或其它运行时的缓存使用情况,防止缓存损坏
- 私有实例维护:如果使用私有Sigstore实例,建立规范的密钥轮换流程和回滚机制
对于生产环境,我强烈建议:
- 使用固定的PolicyServer版本而非latest标签
- 在非生产环境测试所有Sigstore配置变更
- 建立密钥轮换的演练流程
- 配置详细的日志收集和分析,便于快速定位验证问题
7. 深度技术细节:Kubewarden的验证流程
理解Kubewarden内部的验证流程有助于更好地诊断类似问题。当策略服务器加载一个策略时,会执行以下验证步骤:
- 镜像拉取:从OCI仓库获取策略镜像
- 签名验证:检查镜像的cosign签名
- Rekor记录验证:
- 获取与签名对应的Rekor记录
- 验证记录中包含的签名信息
- 检查Rekor记录的完整性证明
- TUF信任链验证:
- 获取最新的TUF根元数据
- 验证Rekor发布的检查点签名
- 检查时间戳和快照元数据
- 策略执行:所有验证通过后,加载并执行策略
这个流程中,步骤4的TUF验证是最容易出问题的环节,特别是在网络受限环境或使用私有实例时。Kubewarden默认使用硬编码在二进制中的初始信任根,但需要定期从TUF仓库更新元数据以跟踪密钥轮换。
8. 高级故障排除技巧
当标准解决方案无效时,可以尝试以下高级排查方法:
- 调试模式:以调试模式运行策略服务器,获取更详细的日志
env: - name: RUST_LOG value: "debug"- 手动验证TUF链:使用cosign工具手动验证当前环境是否能正确处理TUF元数据
cosign verify --rekor-url https://rekor.sigstore.dev \ --certificate-identity-regexp '.*' \ --certificate-oidc-issuer-regexp '.*' \ <policy-image>- 检查TUF缓存:如果使用containerd,检查节点上的TUF缓存内容
sudo find /var/lib/containerd -name '*.json' -exec grep -l 'tuf' {} \;- 网络策略检查:确认NetworkPolicy没有阻止策略服务器访问所需端点
kubectl -n kubewarden describe networkpolicy- 临时禁用验证:在测试环境可以临时禁用验证(不推荐生产使用)
env: - name: KUBEWARDEN_DISABLE_SIGNATURE_VERIFICATION value: "true"在实际运维中,我发现最有效的排查方法是逐步隔离问题:
- 首先确认是普遍性问题还是特定节点问题
- 检查网络连通性和DNS解析
- 验证时间同步状态
- 检查运行时缓存完整性
- 最后才考虑Sigstore配置本身的问题