工作负载证明器

概述

工作负载证明器(WorkloadAttestor)用于识别连接到 Workload API 的工作负载,生成选择器用于匹配注册条目。

Unix

识别 Unix 进程属性。

配置

plugins {
    WorkloadAttestor "unix" {
        plugin_data {
            # 发现可执行文件路径
            discover_workload_path = true
            
            # 工作负载大小限制(用于哈希计算)
            workload_size_limit = 33554432  # 32MB
        }
    }
}

生成的选择器

选择器

描述

示例

unix:uid

用户 ID

unix:uid:1000

unix:gid

组 ID

unix:gid:1000

unix:user

用户名

unix:user:appuser

unix:group

组名

unix:group:appgroup

unix:supplementary_gid

附加组 ID

unix:supplementary_gid:100

unix:supplementary_group

附加组名

unix:supplementary_group:docker

unix:path

可执行文件路径

unix:path:/usr/bin/myapp

unix:sha256

可执行文件 SHA256

unix:sha256:abc123...

注册条目示例

# 按用户
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector unix:uid:1000

# 按路径
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector unix:path:/opt/myapp/bin/myapp

# 按 SHA256(更安全)
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector unix:sha256:abc123def456...

Kubernetes

识别 Kubernetes Pod 属性。

配置

plugins {
    WorkloadAttestor "k8s" {
        plugin_data {
            # Kubelet 配置
            kubelet_read_only_port = 10255
            
            # 跳过 Kubelet 验证(不推荐用于生产)
            skip_kubelet_verification = false
            
            # 节点名称环境变量
            node_name_env = "MY_NODE_NAME"
            
            # 轮询配置
            max_poll_attempts = 60
            poll_retry_interval = "500ms"
            
            # 禁用容器选择器
            disable_container_selectors = false
        }
    }
}

生成的选择器

选择器

描述

示例

k8s:ns

命名空间

k8s:ns:default

k8s:sa

服务账户

k8s:sa:myapp

k8s:pod-uid

Pod UID

k8s:pod-uid:abc123

k8s:pod-name

Pod 名称

k8s:pod-name:myapp-xyz

k8s:pod-label

Pod 标签

k8s:pod-label:app:web

k8s:pod-owner

Pod 所有者

k8s:pod-owner:Deployment:myapp

k8s:pod-owner-uid

所有者 UID

k8s:pod-owner-uid:def456

k8s:pod-image

容器镜像

k8s:pod-image:myregistry/myapp:v1

k8s:pod-image-count

镜像数量

k8s:pod-image-count:2

k8s:pod-init-image

Init 容器镜像

k8s:pod-init-image:busybox

k8s:pod-init-image-count

Init 镜像数量

k8s:pod-init-image-count:1

k8s:container-name

容器名称

k8s:container-name:app

k8s:container-image

容器镜像

k8s:container-image:myapp:v1

k8s:node-name

节点名称

k8s:node-name:node-1

注册条目示例

# 按命名空间和服务账户
spire-server entry create \
    -spiffeID spiffe://example.org/frontend \
    -parentID spiffe://example.org/node \
    -selector k8s:ns:production \
    -selector k8s:sa:frontend-sa

# 按 Pod 标签
spire-server entry create \
    -spiffeID spiffe://example.org/api \
    -parentID spiffe://example.org/node \
    -selector k8s:ns:production \
    -selector k8s:pod-label:app:api \
    -selector k8s:pod-label:version:v2

# 按容器镜像(更精确)
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/node \
    -selector k8s:ns:production \
    -selector k8s:container-image:myregistry.io/myapp@sha256:abc123

Kubelet 访问配置

Agent 需要访问 Kubelet API:

# Agent DaemonSet
apiVersion: apps/v1
kind: DaemonSet
spec:
  template:
    spec:
      containers:
        - name: spire-agent
          env:
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName

Docker

识别 Docker 容器属性。

配置

plugins {
    WorkloadAttestor "docker" {
        plugin_data {
            # Docker socket 路径
            docker_socket_path = "unix:///var/run/docker.sock"
            
            # 容器 ID 前缀长度
            # container_id_cgroup_matchers = [...]
        }
    }
}

生成的选择器

选择器

描述

示例

docker:label

容器标签

docker:label:app:web

docker:image_id

镜像 ID

docker:image_id:sha256:abc123

docker:env

环境变量

docker:env:APP_ENV:production

注册条目示例

# 按标签
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector docker:label:com.example.app:myapp

# 按镜像 ID
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector docker:image_id:sha256:abc123def456

Systemd

识别 Systemd 单元属性。

配置

plugins {
    WorkloadAttestor "systemd" {
        plugin_data {}
    }
}

生成的选择器

选择器

描述

示例

systemd:id

单元 ID

systemd:id:myapp.service

systemd:fragment_path

单元文件路径

systemd:fragment_path:/etc/systemd/system/myapp.service

注册条目示例

spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/myagent \
    -selector systemd:id:myapp.service

组合使用

可以同时启用多个工作负载证明器:

plugins {
    WorkloadAttestor "k8s" {
        plugin_data {
            node_name_env = "MY_NODE_NAME"
        }
    }
    
    WorkloadAttestor "unix" {
        plugin_data {
            discover_workload_path = true
        }
    }
}

注册条目可以组合不同证明器的选择器:

# 组合 k8s 和 unix 选择器
spire-server entry create \
    -spiffeID spiffe://example.org/myapp \
    -parentID spiffe://example.org/node \
    -selector k8s:ns:production \
    -selector k8s:sa:myapp \
    -selector unix:user:appuser

选择器匹配规则

匹配逻辑

  • 注册条目的所有选择器必须匹配(AND 逻辑)

  • 工作负载可以有额外的选择器(不影响匹配)

  • 选择越多越精确,但管理更复杂

最佳实践

建议

  1. 最小权限: 使用最精确的选择器

  2. 镜像哈希: 在生产环境使用镜像 SHA256 而非标签

  3. 组合选择器: 使用多个选择器增加安全性

  4. 避免通配: 不要使用过于宽泛的选择器

  5. 定期审计: 审查注册条目确保符合安全策略