3. SPIRE 架构:SPIRE Server、SPIRE Agent、节点与工作负载注册

SPIRE(SPIFFE Runtime Environment)是 SPIFFE 规范的生产级参考实现。在服务网格的版本回滚场景中,SPIRE 负责为每个工作负载实例颁发唯一的 SPIFFE ID,并确保该身份在节点迁移、Pod 重启或版本切换时仍然可信。理解 SPIRE 的架构组件及其注册流程,是构建版本差异校验护栏的基础。

3.1 核心组件与职责

SPIRE 采用两层架构:SPIRE Server 作为全局身份控制面,SPIRE Agent 作为节点级身份代理。两者通过 gRPC 通信,共同完成节点和工作负载的身份注册与证书签发。

组件 部署位置 核心职责 关键数据
SPIRE Server 集群控制面(K8s 或物理机) 管理 SPIFFE 信任域、签发 X.509-SVID 和 JWT-SVID、维护节点和工作负载注册条目 信任域 CA 私钥、注册条目数据库、吊销列表
SPIRE Agent 每个节点(K8s Node 或 VM) 验证节点身份、代理工作负载的 CSR 请求、缓存 SVID、提供 Workload API 节点证书、Agent 私钥、工作负载 SVID 缓存
Workload API Agent 上的 UDS(Unix Domain Socket) 供工作负载进程获取 SVID 和信任包 —
版本回滚关键点: SPIRE Server 是身份策略的单一权威源。当服务网格执行回滚时,Server 必须能够区分旧版本和新版本工作负载的注册条目,避免回滚后的工作负载拿到错误的 SVID。

3.2 SPIRE 架构交互流程

下图展示了 SPIRE Server、SPIRE Agent 与工作负载之间的身份注册与 SVID 签发流程:

SPIRE 架构组件交互流程 SPIRE 架构:Server / Agent / 工作负载交互 SPIRE Server 信任域 CA 注册条目数据库 SVID 签发 吊销管理 SPIRE Agent 节点身份验证 CSR 代理 SVID 缓存 Workload API 工作负载 Envoy / 业务容器 调用 Workload API 获取 SVID mTLS 通信 节点认证 SVID 下发 Workload API SVID 返回 说明: SPIRE Agent 是工作负载与 Server 之间的可信代理。工作负载不直接与 Server 通信, 而是通过 Agent 暴露的 Unix Domain Socket 获取 SVID,降低 Server 负载并增强安全性。

3.3 节点注册流程

节点注册是工作负载注册的前提。SPIRE Agent 启动后,必须首先向 SPIRE Server 证明自己的节点身份。Kubernetes 环境下,节点注册通常基于 PSAT(Projected Service Account ) 或 JWT-SVID 方式。

  1. Agent 启动:读取配置文件中的 join_ 或节点凭证。
  2. 节点挑战:Agent 向 Server 发起节点认证请求,附带节点凭证(如 K8s Node 的 SA )。
  3. Server 验证:Server 调用节点验证器(Node Attestor)验证凭证有效性,确认节点身份。
  4. 节点注册:验证通过后,Server 在注册条目数据库中创建或更新节点条目,并下发节点 SVID。
  5. Agent 就绪:Agent 持有节点 SVID,开始监听 Workload API 的 UDS 套接字。
版本回滚场景提示: 节点注册条目通常包含节点名称、节点所属集群、节点标签等属性。在回滚时,如果节点标签发生变化(例如从 v2 回滚到 v1),SPIRE Server 需要根据最新的注册条目重新评估节点身份,确保 Agent 拿到正确的节点 SVID。

3.4 工作负载注册流程

工作负载注册是 SPIRE 的核心能力。每个工作负载(如 Envoy sidecar、业务容器)通过一组 选择器(Selector) 来定义身份。选择器是 SPIRE 区分不同版本工作负载的关键机制。

选择器类型 K8s 示例 版本差异校验用途
k8s:ns k8s:ns:default 区分命名空间
k8s:sa k8s:sa:reviews-sa 区分服务账户
k8s:container-image k8s:container-image:reviews:v1.2.3 直接区分版本镜像
k8s:label k8s:label:version:v1 通过标签区分版本
unix:uid unix:uid:1000 非 K8s 环境

工作负载注册的典型步骤:

  1. 定义注册条目:管理员通过 spire-server entry create 命令或 API 创建注册条目,指定 SPIFFE ID、父节点 ID、选择器集合。
  2. Agent 匹配:SPIRE Agent 定期扫描节点上的进程/容器,根据选择器匹配工作负载。
  3. CSR 请求:匹配成功后,Agent 代表工作负载向 Server 发起证书签名请求(CSR)。
  4. Server 签发:Server 验证 CSR 来源(通过节点 SVID 签名),签发 SVID 并返回给 Agent。
  5. 工作负载获取:工作负载通过 Workload API 获取 SVID,用于 mTLS 通信。
# 创建注册条目示例:为 reviews 服务 v1 版本注册 SPIFFE ID
spire-server entry create \
  --parentID spiffe://example.local/spire/agent/k8s_psat/node-worker-1 \
  --spiffeID spiffe://example.local/ns/default/sa/reviews-sa/v1 \
  --selector k8s:ns:default \
  --selector k8s:sa:reviews-sa \
  --selector k8s:label:version:v1

3.5 版本差异校验中的注册条目管理

在服务网格回滚护栏场景中,SPIRE 的注册条目管理需要支持 多版本共存 和 版本切换。以下是关键设计原则:

  • 版本化 SPIFFE ID:在 SPIFFE ID 路径中嵌入版本信息,例如 spiffe://example.local/ns/default/sa/reviews/v1 和 .../v2,使身份与版本绑定。
  • 选择器版本标签:使用 K8s 标签选择器(如 version: v1)区分不同版本的工作负载,避免依赖容器镜像名。
  • 注册条目优先级:当同一工作负载匹配多个注册条目时,SPIRE 根据条目创建时间或显式优先级决定使用哪个条目。
  • 回滚时的条目更新:回滚操作应触发注册条目的更新或切换,确保回滚后的工作负载获得正确的 SPIFFE ID。
常见陷阱: 如果注册条目中的选择器只匹配容器镜像名,而回滚时镜像 tag 从 v2 变回 v1,但镜像 digest 未变,SPIRE 可能无法正确区分版本。建议始终使用显式的版本标签选择器,而非仅依赖镜像名。

3.6 SPIRE 架构在回滚护栏中的角色总结

下表总结了 SPIRE 各组件在版本差异校验中的具体职责:

组件 回滚前 回滚中 回滚后
SPIRE Server 维护 v1 和 v2 的注册条目 接收回滚指令,更新注册条目优先级 确保 v1 工作负载获得正确 SVID
SPIRE Agent 缓存 v1 和 v2 的 SVID 检测工作负载版本变化,重新匹配选择器 为回滚后的工作负载重新签发 SVID
Workload API 提供当前版本的 SVID 在回滚期间保持 SVID 有效 提供回滚后版本的 SVID

通过 SPIRE 的注册条目机制,服务网格可以在回滚时精确控制每个工作负载实例的身份,从而在版本差异校验中提供可信的身份基础。