External Secrets Operator 企业密钥同步
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| API | Application Programming Interface | 应用程序编程接口 |
| ARN | Amazon Resource Name | AWS 资源名称,用于唯一标识资源 |
| AWS | Amazon Web Services | 亚马逊云服务 |
| CMK | Customer Master Key | AWS KMS 旧称,现称 KMS key;其他云须按产品定义理解 |
| CRD | Custom Resource Definition | Kubernetes 自定义资源定义 |
| ESO | External Secrets Operator | 将外部秘密系统中的值同步到 Kubernetes 的控制器 |
| GitOps | GitOps | 以 Git 保存期望状态、由自动化持续协调实际状态的运维方式 |
| GKE | Google Kubernetes Engine | Google 托管 Kubernetes 服务 |
| HA | High Availability | 高可用 |
| IRSA | IAM Roles for Service Accounts | 通过 Kubernetes 服务账号关联 AWS IAM 角色 |
| JSON | JavaScript Object Notation | 一种结构化数据格式 |
| KMS | Key Management Service | 密钥管理服务 |
| RBAC | Role-Based Access Control | 基于角色的访问控制 |
| SA | Service Account | 服务账号,供程序或工作负载使用的身份 |
场景:orders 从 AWS Secrets Manager 读取专属数据库连接配置,Git 中只有引用。前置:基线、IRSA。ESO 把值写入 Kubernetes Secret,因此仍需 etcd 加密、Secret RBAC、备份加密;它不是“密钥永不进入集群”。
控制器与租户身份#
控制器不持有全账户读密钥权限;每个 namespace 的 SecretStore 通过指定 SA 取角色。建立 orders/eso-orders SA 的 IRSA,策略仅允许指定 Secret ARN 的 secretsmanager:GetSecretValue/DescribeSecret,使用 CMK 时另授指定 key 的 kms:Decrypt 并核对 key policy。
helm repo add external-secrets https://charts.external-secrets.io
helm repo update
helm search repo external-secrets/external-secrets --versions
export ESO_VERSION='REPLACE_CHART_VERSION'
helm show values external-secrets/external-secrets --version "$ESO_VERSION" > eso-defaults.yaml保存 eso-values.yaml,再安装:
installCRDs: true
replicaCount: 2
leaderElect: true
webhook:
replicaCount: 2
certController:
replicaCount: 2helm upgrade --install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace --version "$ESO_VERSION" -f eso-values.yaml --wait --timeout 10m
kubectl -n external-secrets get pods按该 Chart schema 检查 HA、webhook 证书和 API Server 网络;平台控制谁能写 SecretStore/ExternalSecret,以及 ESO 请求 SA token 的权限。准入策略限制 secretRef 的命名和云资源范围。AWS provider
Hands-on:同步订单配置#
云中已有 Secret JSON 属性 DATABASE_URL,指向预生产数据库;由密钥管理员设置值,不在命令/文档中展示。保存 orders-secret.yaml,替换 ARN/区域,使用已安装 CRD 支持的 v1:
apiVersion: v1
kind: ServiceAccount
metadata:
name: eso-orders
namespace: orders
annotations:
eks.amazonaws.com/role-arn: REPLACE_ORDERS_SECRET_ROLE_ARN
---
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata: {name: orders-aws, namespace: orders}
spec:
provider:
aws:
service: SecretsManager
region: REPLACE_REGION
auth:
jwt:
serviceAccountRef: {name: eso-orders}
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata: {name: orders-runtime, namespace: orders}
spec:
refreshPolicy: Periodic
refreshInterval: 5m
secretStoreRef: {name: orders-aws, kind: SecretStore}
target:
name: orders-runtime
creationPolicy: Owner
deletionPolicy: Retain
data:
- secretKey: DATABASE_URL
remoteRef:
key: REPLACE_FULL_SECRET_ARN
property: DATABASE_URLkubectl apply --dry-run=server -f orders-secret.yaml
kubectl apply -f orders-secret.yaml
kubectl -n orders wait --for=condition=Ready secretstore/orders-aws --timeout=2m
kubectl -n orders wait --for=condition=Ready externalsecret/orders-runtime --timeout=2m
kubectl -n orders get secret orders-runtime -o custom-columns=NAME:.metadata.name,VERSION:.metadata.resourceVersion不输出 .data 验收;运行真实业务数据库读写,查审计身份。deletionPolicy: Retain 处理云端值删除场景;creationPolicy: Owner 带 ownerReference,删除 ExternalSecret 仍可能垃圾回收目标 Secret,GitOps prune 要单独保护。
轮换、拒绝与恢复演练#
- 通过数据库原生流程建立新凭据,保持短暂新旧并存;更新 Secrets Manager 版本,等待 ExternalSecret refreshTime/Secret resourceVersion 更新。
- 环境变量不会热更新:
kubectl -n orders rollout restart deployment/orders-api,等 rollout 成功并跑订单链路;worker 同样处理,最后撤销旧凭据。 - 用其他租户 Store 读该 Secret 必须失败;临时撤销测试角色权限时 ESO 应告警,现有 Secret 不应被盲删。
- 回退需要把云端版本、数据库账号状态与 Pod 同时协调,不能仅恢复一个旧 Kubernetes Secret。
监控同步错误、凭据过期、过久未刷新、KMS 拒绝。GKE 使用 Google Secret Manager provider + Workload Identity;Vault 场景见 Vault 集成。删除环境前先停消费者、再撤销云角色和密钥,保留审计记录。
撤权后的状态不能只看 Secret 是否存在#
使用独立预生产角色与合成 Secret 演练:先确认正常同步,再由管理员撤销该角色的目标 Secret 读取权限。等待实际刷新周期后查看:
kubectl -n orders get externalsecret orders-runtime -o jsonpath='{.status.refreshTime}{"\n"}{range .status.conditions[*]}{.type}{"="}{.status}{" reason="}{.reason}{"\n"}{end}'
kubectl -n orders get events --field-selector involvedObject.name=orders-runtime --sort-by=.metadata.creationTimestamp
kubectl -n orders get secret orders-runtime -o custom-columns=NAME:.metadata.name,VERSION:.metadata.resourceVersion预期同步出现权限错误与告警;缓存的 Kubernetes Secret 可能仍存在,已有应用可能继续用旧凭据。Ready=True 的旧观察结果不能证明撤权无效,需结合刷新时间和新事件。读取 .data 不属于验收步骤。
如果真实凭据已泄漏,应在数据库/外部系统撤销并按需终止旧连接,再完成新 Secret 同步与消费者更新;只撤云端读取权限无法收回已复制的值。演练结束恢复仅本次撤销的授权,确认刷新恢复和实际业务通过。轮换与凭证有效性。