第二十一章:SPIFFE 联邦与跨域信任

“在多云多集群的世界里,信任不应该止步于一个集群的边界。”

        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 联邦配置

# 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"
        }
    }
}
# 建立联邦关系
# 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

# 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 获取证书:

# 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 的文件系统:

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 注册项:

# 通过 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 DriverWorkload Registrar 简化 Kubernetes 集成

  • 生产部署需要关注:高可用、监控告警、Trust Domain 命名规范、灾难恢复