K8s Secrets 管理:使用 External Secrets 对接 Vault

在 Kubernetes 中直接使用原生 Secrets 存在安全风险(如 Base64 编码非加密、etcd 存储明文)。External Secrets Operator (ESO) 提供了安全解决方案:将敏感信息存储在专业密钥管理系统(如 HashiCorp Vault),按需同步至 Kubernetes。以下是完整实现流程:


1. 核心组件作用
  • HashiCorp Vault:集中化密钥管理,支持动态密码、加密存储、细粒度权限控制。
  • External Secrets Operator:K8s 控制器,监听 ExternalSecret 对象并自动从 Vault 拉取密钥。
  • 同步流程
    graph LR
    Vault[(HashiCorp Vault)] --> ESO[External Secrets Operator]
    ESO -->|创建| K8s_Secret[Kubernetes Secret]
    K8s_Secret --> Pod[应用 Pod]
    


2. 前置条件
  • 已部署 HashiCorp Vault(云托管或自建)
  • Kubernetes 集群版本 ≥ 1.16
  • kubectlhelm 已安装

3. 部署 External Secrets Operator

通过 Helm 快速部署:

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets \
  external-secrets/external-secrets \
  -n external-secrets --create-namespace

验证安装:

kubectl get pods -n external-secrets


4. 配置 Vault 访问权限
(1) 在 Vault 中启用 Kubernetes 认证
vault auth enable kubernetes
vault write auth/kubernetes/config \
  token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
  kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

(2) 创建策略并绑定角色

示例策略 eso-policy.hcl

path "secret/data/*" {
  capabilities = ["read"]
}

应用策略:

vault policy write eso-policy eso-policy.hcl
vault write auth/kubernetes/role/eso-role \
  bound_service_account_names=external-secrets \
  bound_service_account_namespaces=external-secrets \
  policies=eso-policy \
  ttl=1h


5. 在 Kubernetes 中配置访问

创建 SecretStore 资源(指向 Vault):

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "https://vault.example.com"  # Vault 地址
      path: "secret"                       # 密钥路径
      version: "v2"                        # KV 引擎版本
      auth:
        kubernetes:
          role: "eso-role"                 # Vault 角色
          serviceAccountRef:
            name: external-secrets         # ESO 使用的 ServiceAccount


6. 同步密钥到 Kubernetes

创建 ExternalSecret 资源(示例同步数据库密码):

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: "5m"     # 每 5 分钟同步一次
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: db-secret        # 生成的 K8s Secret 名称
  data:
  - secretKey: password    # Kubernetes Secret 的键
    remoteRef:
      key: secret/data/db  # Vault 中的路径
      property: password    # Vault 密钥字段


7. 验证结果
  • 检查同步的 Secret:
    kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
    

  • 在 Pod 中使用:
    env:
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: db-secret
            key: password
    


8. 高级特性
  • 自动轮转:Vault 动态密钥更新后,ESO 自动更新 K8s Secret。
  • 多集群同步:一个 Vault 实例支持多个 Kubernetes 集群。
  • 访问控制:通过 Vault 策略限制不同命名空间的访问权限。

安全建议

  1. 为生产环境启用 Vault TLS 证书认证
  2. 限制 ESO 的 ServiceAccount 权限(RBAC)
  3. 使用 Vault 命名空间隔离不同环境

通过此方案,敏感信息完全脱离 Kubernetes 存储系统,实现集中化管理动态安全控制

更多推荐