4. 部署第一个SPIRE环境

在理解了 SPIFFE ID 的命名规则与 SPIRE 的架构分工之后,接下来要做的第一件事,是让一个真实可运行的 SPIRE 环境出现在你面前。本节的目标很明确:在一台单节点主机或一个容器编排环境里,安装 SPIRE Server 与 SPIRE Agent,配置一个基础信任域,启动两者,并最终验证节点身份与工作负载身份都能被正确签发。完成之后,你会得到一条可复用的最小闭环:Server 签发节点身份 → Agent 通过节点身份获得 SVID → Agent 为工作负载签发 SVID。

4.1 先确定信任域与拓扑

信任域(Trust Domain)是 SPIFFE ID 的根,所有身份都形如 spiffe://<trust_domain>/...。本节示例统一使用 example.org 作为信任域,这是官方文档中常见的示例值,实际生产环境应替换为你自己的域名。单节点部署时,Server 与 Agent 可以运行在同一台主机上,通过 Unix Domain Socket 通信;容器环境中,Server 通常以独立容器运行,Agent 以 DaemonSet 或每节点一个容器的方式运行,通过挂载的 socket 目录与工作负载通信。

需要提前明确两个关键路径:Server 的数据目录(存放 CA 证书、数据库、注册条目)和 Agent 的 socket 路径。本节示例中,Server 数据目录为 /opt/spire/data/server,Agent 数据目录为 /opt/spire/data/agent,Agent 对外暴露的 Workload API socket 为 /run/spire/sockets/agent.sock。这些路径在后续配置中会反复出现,务必保持一致。

4.2 安装与初始化 SPIRE Server

以 Linux 单节点为例,从官方发布包解压后,目录中会包含 spire-server、spire-agent 两个二进制文件以及示例配置。首先初始化 Server 的配置与数据目录:

mkdir -p /opt/spire/data/server /opt/spire/conf/server
cp conf/server/server.conf /opt/spire/conf/server/server.conf

编辑 server.conf,核心字段如下(示例值,需按实际环境调整):

trust_domain = "example.org"
bind_address = "0.0.0.0"
bind_port = "8081"
data_dir = "/opt/spire/data/server"
log_level = "DEBUG"
ca_subject = "CN=example.org"

其中 ca_subject 是自签名 CA 的主题,bind_port 是 Server 对外提供节点 attestation 与注册 API 的端口。配置完成后,启动 Server:

spire-server run -config /opt/spire/conf/server/server.conf

首次启动时,Server 会自动生成自签名 CA 证书与密钥,并写入 data_dir。观察日志中是否出现 Starting SPIRE Server 以及 CA initialized 之类的信息,即可判断 Server 已就绪。此时 Server 还没有任何注册条目,Agent 也无法通过节点 attestation。

4.3 为 Agent 创建节点注册条目

Agent 要获得自己的节点 SVID,必须先由 Server 为其创建一条节点注册条目(node entry)。节点 attestation 方式有多种,单节点环境最直接的是 join_token。先生成一个一次性加入令牌:

spire-server token generate -spiffeID spiffe://example.org/agent/node1

命令会输出一个形如 a1b2c3d4-... 的令牌。随后用该令牌创建节点条目:

spire-server entry create \
  -node \
  -spiffeID spiffe://example.org/agent/node1 \
  -selector unix:uid:0

这里 -node 表示创建的是节点条目,-selector unix:uid:0 表示该节点上以 root 运行的 Agent 可以通过 attestation。选择器是 SPIRE 的核心机制:Server 不直接信任 Agent 的声明,而是根据 Agent 提供的证据(如 UID、容器镜像、K8s ServiceAccount)匹配注册条目中的选择器,匹配成功才签发 SVID。

4.4 配置并启动 SPIRE Agent

Agent 的配置需要指向 Server 地址、信任域、数据目录以及 Workload API socket 路径:

trust_domain = "example.org"
server_address = "127.0.0.1"
server_port = "8081"
data_dir = "/opt/spire/data/agent"
socket_path = "/run/spire/sockets/agent.sock"

启动 Agent 时,通过 -joinToken 传入刚才生成的令牌:

spire-agent run \
  -config /opt/spire/conf/agent/agent.conf \
  -joinToken a1b2c3d4-...

Agent 启动后会先向 Server 发起节点 attestation,成功后获得节点 SVID,并开始监听 Workload API socket。日志中应能看到 Node attestation successful 与 Workload API listening。如果 attestation 失败,常见原因是令牌已过期、选择器不匹配或 Server 地址端口不通。

SPIRE 单节点部署:信任域 example.org 的身份签发链路 SPIRE Server trust_domain = example.org bind_port = 8081 data_dir = /opt/spire/data/server 自签名 CA CN=example.org SPIRE Agent server_address = 127.0.0.1:8081 data_dir = /opt/spire/data/agent socket = /run/spire/sockets/agent.sock 节点 SVID spiffe://example.org/agent/node1 节点注册条目(node entry) spiffeID: spiffe://example.org/agent/node1 selector: unix:uid:0 工作负载 通过 Workload API 获取 SVID ① 节点 attestation(join_token) ② 签发节点 SVID ③ 匹配选择器 ④ 工作负载 attestation 关键验证点 • Server 日志:CA initialized • Agent 日志:attestation successful

4.5 验证节点身份与工作负载身份

Agent 启动成功后,先用 Server 的 CLI 查看节点条目是否已生效:

spire-server entry show

输出中应包含刚才创建的节点条目,且 Parent ID 为空(节点条目没有父条目)。接着验证 Agent 是否已获得节点 SVID:

spire-agent api fetch x509 -socketPath /run/spire/sockets/agent.sock

如果返回中包含 spiffe://example.org/agent/node1 的证书链,说明节点身份签发成功。接下来创建工作负载注册条目,让一个具体进程也能拿到 SVID。假设工作负载以 UID 1000 运行,选择器为 unix:uid:1000:

spire-server entry create \
  -parentID spiffe://example.org/agent/node1 \
  -spiffeID spiffe://example.org/workload/web \
  -selector unix:uid:1000

再次执行 spire-agent api fetch x509,此时应能看到两个 SVID:一个是 Agent 自身的节点 SVID,另一个是工作负载的 SVID。两者的 Parent ID 不同,前者为空,后者指向节点条目。这个差异是判断“节点身份”与“工作负载身份”是否分层正确的关键依据。

验证顺序建议:先确认 Server 的 CA 已初始化,再确认 Agent 节点 attestation 成功,最后确认工作负载条目被匹配。任何一步失败,后续步骤都不会产生有效 SVID。日志级别设为 DEBUG 可以快速定位是令牌、选择器还是网络端口的问题。

4.6 容器环境下的差异

如果使用 Docker 或 Kubernetes,核心逻辑不变,但有三处需要调整。第一,Server 与 Agent 通常分属不同容器,server_address 要改为容器网络中的服务名或 IP,而不是 127.0.0.1。第二,Agent 的 Workload API socket 必须通过 volume 挂载到工作负载容器中,否则工作负载无法访问。第三,节点 attestation 方式可以从 join_token 换成 k8s_psat 或 docker,选择器也相应改为 k8s:ns:default、k8s:sa:web 或 docker:label:...。这些选择器直接决定了哪些工作负载有资格获得身份,是后续章节要深入展开的重点。

4.7 常见启动失败与排查方向

实际部署中,最常见的失败是 Agent 报 node attestation failed。此时先检查令牌是否已被使用或过期,再检查 entry show 中节点条目的选择器是否与 Agent 实际提供的证据一致。其次是 connection refused,通常意味着 Server 未启动、端口未监听或防火墙拦截。最后是 socket 权限问题:Workload API socket 默认只允许特定 UID 访问,如果工作负载以非预期 UID 运行,会看到 permission denied。把这三类问题按“令牌 → 网络 → 权限”的顺序排查,绝大多数启动故障都能在几分钟内定位。

完成本节后,你已经拥有一个可签发节点身份与工作负载身份的最小 SPIRE 环境。下一步要做的,是把注册条目从手工创建推进到自动化管理,并让更多真实工作负载接入这条身份链路。