Vault EKS and Agent Integration

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
API Application Programming Interface 应用程序编程接口
AWS Amazon Web Services 亚马逊云服务
CA Certificate Authority 证书颁发机构
CLI Command-Line Interface 命令行接口
CSI Container Storage Interface 容器存储接口
EKS Elastic Kubernetes Service AWS 托管 Kubernetes 服务
ESO External Secrets Operator 将外部秘密系统中的值同步到 Kubernetes 的控制器
JWKS JSON Web Key Set JSON Web 密钥集,常用于验证令牌签名
JWT JSON Web Token 一种携带声明的令牌格式
OIDC OpenID Connect 基于 OAuth 2.0 的身份认证协议
RBAC Role-Based Access Control 基于角色的访问控制
SAN Subject Alternative Name 证书主题备用名称,用于声明域名或 IP
SDK Software Development Kit 软件开发工具包
TTL Time To Live 存活时间;具体指缓存有效期或记录过期时间

1. 方案#

Vault 位于集群外,通过 EKS ServiceAccount 的短期 JWT 验证身份,Vault Agent 渲染数据库凭据到 Pod 内存卷。应用不取得 Vault token,也不把数据库密码同步成 Kubernetes Secret。

本例使用 JWT auth 校验 EKS issuer/JWKS,不是使用 TokenReview 的 Kubernetes auth。两种方式不要混配。JWT auth

前提:已完成 动态数据库,存在 orders-app policy、database/creds/orders-read;EKS 可访问 Vault,Vault 可访问 EKS OIDC discovery/JWKS,应用网络可访问数据库。

2. 绑定 EKS 身份#

先用 AWS CLI 确认实际集群:

export VAULT_EKS_NAME=production
export VAULT_EKS_REGION=ap-southeast-1
VAULT_EKS_ISSUER=$(aws eks describe-cluster --name "$VAULT_EKS_NAME" --region "$VAULT_EKS_REGION" --query 'cluster.identity.oidc.issuer' --output text)

vault auth enable -path=eks-jwt jwt
vault write auth/eks-jwt/config oidc_discovery_url="$VAULT_EKS_ISSUER" bound_issuer="$VAULT_EKS_ISSUER"

保存 orders-jwt-role.json:

{
  "role_type": "jwt",
  "user_claim": "sub",
  "bound_subject": "system:serviceaccount:orders:orders-api",
  "bound_audiences": ["vault"],
  "token_policies": ["orders-app"],
  "token_ttl": "5m",
  "token_max_ttl": "10m"
}
vault write auth/eks-jwt/role/orders-api @orders-jwt-role.json

issuer + subject + audience 一起约束身份;测试和生产集群分别建 auth mount。JWT auth 不实时检查 Pod 是否已删除,被盗 JWT 在过期前仍可能登录;短 token TTL 与紧急撤销需配套。若要求实时 TokenReview,改用 Kubernetes auth,并设计 reviewer token 的安全获取、权限与续期。

3. 准备 namespace、CA 和 Agent 配置#

kubectl create namespace orders
kubectl -n orders create serviceaccount orders-api
kubectl -n orders create configmap vault-ca --from-file=ca.crt=/secure/platform/vault-ca.crt

CA 证书不是私钥。保存 agent.hcl,替换 vault.internal 为证书 SAN 覆盖的实际地址:

pid_file = "/tmp/vault-agent.pid"

vault {
  address = "https://vault.internal:8200"
  ca_cert = "/etc/vault-ca/ca.crt"
}

auto_auth {
  method "jwt" {
    mount_path = "auth/eks-jwt"
    config = {
      path                     = "/var/run/vault-jwt/token"
      role                     = "orders-api"
      remove_jwt_after_reading  = false
    }
  }
}

template {
  destination          = "/vault/secrets/database.json"
  perms                = "0640"
  error_on_missing_key = true
  contents = <<EOT
{{- with secret "database/creds/orders-read" -}}
{"username": {{ .Data.username | toJSON }}, "password": {{ .Data.password | toJSON }}}
{{- end -}}
EOT
}
kubectl -n orders create configmap orders-vault-agent --from-file=agent.hcl

投射 JWT 由 kubelet 轮换,Agent 不删除它。Agent 负责重新认证、lease 生命周期和模板更新,但不会自动修改应用进程的环境变量。JWT auto-auth、Agent templates

4. 部署验证 Pod#

保存为 orders-vault-demo.yaml。consumer 仅验证受限文件可读,不输出凭据,也不是实际订单应用。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-vault-demo
  namespace: orders
spec:
  replicas: 1
  selector:
    matchLabels:
      app: orders-vault-demo
  template:
    metadata:
      labels:
        app: orders-vault-demo
    spec:
      serviceAccountName: orders-api
      automountServiceAccountToken: false
      securityContext:
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: vault-agent
          image: hashicorp/vault:2.1.1
          command: ["vault", "agent", "-config=/etc/vault-agent/agent.hcl"]
          securityContext:
            runAsNonRoot: true
            runAsUser: 100
            runAsGroup: 1000
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          resources:
            requests: {cpu: 50m, memory: 64Mi}
            limits: {cpu: 250m, memory: 256Mi}
          volumeMounts:
            - {name: config, mountPath: /etc/vault-agent, readOnly: true}
            - {name: ca, mountPath: /etc/vault-ca, readOnly: true}
            - {name: jwt, mountPath: /var/run/vault-jwt, readOnly: true}
            - {name: secrets, mountPath: /vault/secrets}
        - name: consumer
          image: busybox:1.37.0
          command: ["sh", "-c", "while true; do sleep 60; done"]
          securityContext:
            runAsNonRoot: true
            runAsUser: 1000
            runAsGroup: 1000
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          resources:
            requests: {cpu: 10m, memory: 16Mi}
            limits: {cpu: 100m, memory: 32Mi}
          readinessProbe:
            exec:
              command: ["sh", "-c", "test -s /vault/secrets/database.json"]
            periodSeconds: 5
          volumeMounts:
            - {name: secrets, mountPath: /vault/secrets, readOnly: true}
      volumes:
        - name: config
          configMap:
            name: orders-vault-agent
        - name: ca
          configMap:
            name: vault-ca
        - name: jwt
          projected:
            sources:
              - serviceAccountToken:
                  path: token
                  audience: vault
                  expirationSeconds: 600
        - name: secrets
          emptyDir:
            medium: Memory
            sizeLimit: 8Mi
kubectl apply -f orders-vault-demo.yaml
kubectl -n orders rollout status deployment/orders-vault-demo
kubectl -n orders logs deployment/orders-vault-demo -c vault-agent --tail=50
kubectl -n orders exec deployment/orders-vault-demo -c consumer -- sh -c 'test -r /vault/secrets/database.json && echo credentials-file-ready'

验收成功标志是文件生成且不暴露值;应用实际访问数据库仍需单独验证。文件存在不是凭据仍有效的证明,生产 readiness 应验证当前凭据和必要数据库访问。

5. 企业应用接入#

把 consumer 替换为订单服务镜像,使用固定 digest;实现“文件更新 → 解析新凭据 → 新连接池健康检查 → 排空旧连接池”。Agent 原子替换文件,文件监听要处理 rename/inode 变化;仅启动时读一次文件不够。

其他方式 适用场景 取舍
Vault Agent Injector 团队希望通过 Pod annotation 统一注入 需要管理 webhook、模板与失败策略
Vault Secrets Operator / ESO 应用只能读取 Kubernetes Secret secret 会进入 Kubernetes API/etcd,配置加密和 RBAC
CSI provider 文件挂载集成 核对凭据续期、刷新和应用重载能力
应用 SDK 应用需要精确 lease 控制 自己处理认证、重试、续期与撤销

限制只有 Agent 能挂载身份 JWT,业务容器只读凭据文件;Pod 创建权限本身能影响 workload 身份,RBAC、准入策略和 NetworkPolicy 同样重要。

6. 故障与清理#

  • 换成其他 namespace/ServiceAccount,预期 Vault 登录被拒绝。
  • 阻断实验 Pod 到 Vault 的网络,观察现有凭据有效期和续期告警;应用不得无期限使用旧密码。
  • 撤销测试 lease,验证连接池能恢复或明确报错,不在日志打印密码。
  • 查看 Agent 续期不等于文件每次都会变化;同一凭据续期时 username/password 可能不变。

清理本次 Deployment、ConfigMap、ServiceAccount 和测试 namespace;只删除本次专用资源。Pod 删除不保证已有 Vault token/数据库 lease 立即失效,按测试记录主动撤销或验证到期回收。生产 auth mount 不因一次实验结束而整体 disable。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭