# 第二十一章:SPIFFE 联邦与跨域信任 > "在多云多集群的世界里,信任不应该止步于一个集群的边界。" ```{mermaid} mindmap root((SPIFFE 联邦)) 联邦信任 Bundle Endpoint 单向/双向信任 跨域验证 多集群 同 Trust Domain 不同 Trust Domain Nested SPIRE Service Mesh Istio + SPIRE Envoy SDS Consul Connect K8s 集成 CSI Driver Workload Registrar 生产实践 命名规范 高可用 监控告警 ``` ## 21.1 为什么需要联邦信任 ``` 场景:多集群、多云、多组织 ┌─────────────────┐ ┌─────────────────┐ │ AWS 集群 │ │ GCP 集群 │ │ Trust Domain: │ 联邦 │ Trust Domain: │ │ aws.example.com │◀──────▶│ gcp.example.com │ │ │ │ │ │ ┌────────────┐ │ │ ┌────────────┐ │ │ │ Service A │─┼─────────┼─│ Service B │ │ │ │ spiffe:// │ │ mTLS │ │ spiffe:// │ │ │ │ aws.../a │ │ │ │ gcp.../b │ │ │ └────────────┘ │ │ └────────────┘ │ └─────────────────┘ └─────────────────┘ 没有联邦:Service A 无法验证 Service B 的 SVID(不同 Trust Domain) 有了联邦:两个 Trust Domain 交换 Trust Bundle,互相信任 ✅ ``` ## 21.2 Trust Domain 联邦 ### Bundle Endpoint 每个 SPIRE Server 可以暴露一个 Bundle Endpoint,发布自己的 Trust Bundle: ``` ┌──────────────────┐ ┌──────────────────┐ │ SPIRE Server A │ │ SPIRE Server B │ │ aws.example.com │ │ gcp.example.com │ │ │ │ │ │ Bundle Endpoint │◀────────│ 获取 A 的 Bundle│ │ /bundle │ │ │ │ │────────▶│ Bundle Endpoint │ │ 获取 B 的 Bundle│ │ /bundle │ └──────────────────┘ └──────────────────┘ 联邦建立后: - A 的 Agent 拥有 B 的 Trust Bundle → 可以验证 B 的 SVID - B 的 Agent 拥有 A 的 Trust Bundle → 可以验证 A 的 SVID ``` ### SPIRE Server 联邦配置 ```text # SPIRE Server A 配置 server { trust_domain = "aws.example.com" # 暴露 Bundle Endpoint federation { bundle_endpoint { address = "0.0.0.0" port = 8443 } } } # 联邦关系配置 plugins { BundlePublisher "aws_s3" { plugin_data { bucket = "spire-bundles" region = "us-east-1" } } } ``` ```bash # 建立联邦关系 # Server A 信任 Server B spire-server bundle set \ -id spiffe://gcp.example.com \ -path /path/to/gcp-bundle.json # Server B 信任 Server A spire-server bundle set \ -id spiffe://aws.example.com \ -path /path/to/aws-bundle.json # 创建联邦注册项 spire-server entry create \ -spiffeID spiffe://aws.example.com/service-a \ -parentID spiffe://aws.example.com/agent/node1 \ -selector k8s:sa:service-a \ -federatesWith spiffe://gcp.example.com # 允许被 GCP 域验证 ``` ## 21.3 多集群场景 ### 场景 1:同一 Trust Domain 多集群 ``` ┌─────────────────┐ ┌─────────────────┐ │ Cluster 1 │ │ Cluster 2 │ │ Trust Domain: │ 共享 │ Trust Domain: │ │ example.com │ 同一 │ example.com │ │ │ CA │ │ │ SPIRE Server 1 │◀──────▶│ SPIRE Server 2 │ │ (共享 DataStore)│ │ (共享 DataStore) │ └─────────────────┘ └─────────────────┘ 方案:共享数据库(PostgreSQL),多个 Server 实例 优点:无需联邦配置,天然互信 缺点:数据库成为单点 ``` ### 场景 2:Nested SPIRE(嵌套部署) ``` ┌─────────────────────────────────────────┐ │ Root SPIRE Server │ │ spiffe://example.com │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Nested Server│ │ Nested Server│ │ │ │ Cluster A │ │ Cluster B │ │ │ │ spiffe:// │ │ spiffe:// │ │ │ │ example.com │ │ example.com │ │ │ │ /cluster-a │ │ /cluster-b │ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────┘ Nested SPIRE: - 子 Server 从父 Server 获取自己的 SVID - 子 Server 为自己集群的工作负载签发 SVID - 所有 SVID 共享同一 Trust Domain - 适合大规模多集群部署 ``` ## 21.4 与 Service Mesh 集成 ### Istio + SPIRE ```yaml # Istio 配置使用 SPIRE 作为 CA apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: meshConfig: caCertificates: - spiffeBundleUrl: "https://spire-server:8443" values: pilot: env: PILOT_CERT_PROVIDER: spiffe global: caAddress: "spire-server:8081" ``` ### Envoy SDS 集成 SPIRE Agent 内置 SDS(Secret Discovery Service)服务器,Envoy 可以直接从 Agent 获取证书: ```yaml # Envoy 配置 static_resources: clusters: - name: service-b type: STRICT_DNS transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext common_tls_context: tls_certificate_sds_secret_configs: - name: "spiffe://example.org/service-a" sds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: spire-agent validation_context_sds_secret_config: name: "spiffe://example.org" sds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: spire-agent ``` ## 21.5 Kubernetes 集成 ### SPIFFE CSI Driver 自动将 SVID 挂载到 Pod 的文件系统: ```yaml apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: my-app:latest volumeMounts: - name: spiffe mountPath: /run/spire/sockets readOnly: true volumes: - name: spiffe csi: driver: "csi.spiffe.io" readOnly: true ``` ### Kubernetes Workload Registrar 自动为 Kubernetes 工作负载创建 SPIRE 注册项: ```yaml # 通过 Pod 注解自动注册 apiVersion: v1 kind: Pod metadata: name: web-server annotations: spiffe.io/spiffe-id: "spiffe://example.org/ns/production/sa/web-server" spec: serviceAccountName: web-server containers: - name: web image: web-server:latest ``` ## 21.6 生产环境最佳实践 ### Trust Domain 命名规范 ``` 推荐格式:{env}.{org}.{tld} 示例: prod.example.com — 生产环境 staging.example.com — 预发布环境 dev.example.com — 开发环境 路径规范: /ns/{namespace}/sa/{service-account} — K8s 工作负载 /region/{region}/service/{name} — 按区域 /cluster/{cluster}/app/{name} — 按集群 ``` ### 高可用部署 ``` ┌─────────────────────────────────────────┐ │ SPIRE Server 集群(3节点) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │Server 1 │ │Server 2 │ │Server 3 │ │ │ │ (Leader)│ │(Follower)│ │(Follower)│ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ └───────────┼───────────┘ │ │ │ │ │ ┌───────▼───────┐ │ │ │ PostgreSQL │ │ │ │ (高可用集群) │ │ │ └───────────────┘ │ └─────────────────────────────────────────┘ ``` ### 监控指标 | 指标 | 说明 | 告警阈值 | |------|------|---------| | SVID 签发延迟 | 签发 SVID 的耗时 | > 5s | | SVID 轮换失败 | 自动轮换失败次数 | > 0 | | Agent 连接数 | 连接到 Server 的 Agent 数 | 低于预期 | | 注册项数量 | 活跃的注册项总数 | 异常变化 | | CA 证书过期 | 根 CA 证书剩余有效期 | < 30 天 | ## 21.7 小结 - **联邦信任** 通过 Bundle Endpoint 交换 Trust Bundle,实现跨域互信 - **Nested SPIRE** 适合大规模多集群部署,共享 Trust Domain - **Istio + SPIRE** 集成提供 Service Mesh 级别的自动 mTLS - **SPIFFE CSI Driver** 和 **Workload Registrar** 简化 Kubernetes 集成 - 生产部署需要关注:高可用、监控告警、Trust Domain 命名规范、灾难恢复