为 sandbox 接入 OpenBao External Secrets
yaml / yaml (pull_request) Successful in 17s
terraform / validate (pull_request) Successful in 49s

This commit is contained in:
2026-09-18 17:34:53 +00:00
parent 90ba945d85
commit e0e629794b
23 changed files with 306 additions and 18 deletions
@@ -0,0 +1,42 @@
# Sandbox External Secrets Operator
本目录在 sandbox 集群部署独立的 External Secrets Operator `2.8.0`,并通过
`ClusterSecretStore/openbao` 读取 OpenBao KV v2 中共享的 OpenSandbox API key。它不复用
homelab 集群的 ESO Pod、ServiceAccount 或 Kubernetes auth backend。
OpenBao 的 `auth/kubernetes-sandbox`、对应 role、policy、sandbox API 地址与公开 CA
完全由 `infrastructure/openbao/terraform/` 管理。CA 文件提交到 Git 是刻意设计:CA
是公开信任材料,版本化后集群重建造成的 trust root 变化会产生可审计的 Terraform diff。
ESO 使用 TokenRequest 生成短期 ServiceAccount JWT。OpenBao 未配置长期
`token_reviewer_jwt`,而是使用登录 JWT 调用 sandbox TokenReview;因此
`external-secrets` ServiceAccount 仅额外绑定内建 `system:auth-delegator`。
## 部署顺序
1. 在 OpenBao 写入 OpenSandbox API key:
```bash
openssl rand -hex 32 | bao kv put kv/k8s/opensandbox-api api_key=-
```
2. 在 `infrastructure/openbao/terraform` 执行 `terraform plan` 和 `terraform apply`,
创建 `kubernetes-sandbox` auth mount、backend config、role 与只允许读取
`kv/k8s/opensandbox-api` 的最小权限 policy。
3. 合并 Flux 变更。依次等待 `flux-system/external-secrets-operator`、
`flux-system/external-secrets` Ready,再等待 `flux-system/opensandbox` 滚动完成。
operator 与配置拆成两个 Flux Kustomization,确保全新集群先安装 CRD,再声明
`ClusterSecretStore`;不要为了减少目录而把两层重新合并。
## 验收
```bash
kubectl get clustersecretstore openbao
kubectl -n opensandbox-system get externalsecret opensandbox-api-key
kubectl -n opensandbox-system get secret opensandbox-api-key
```
只检查 Secret 是否存在及 key 名,不输出 `data`。`ClusterSecretStore` 或
`ExternalSecret` 不 Ready 时,先检查 `auth/kubernetes-sandbox`,不要临时创建静态
Bao token Secret。
@@ -0,0 +1,13 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sandbox-external-secrets-token-review
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: external-secrets
namespace: external-secrets
@@ -0,0 +1,18 @@
---
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: openbao
spec:
provider:
vault:
server: https://bao.ad.ddupan.top:8200
path: kv
version: v2
auth:
kubernetes:
mountPath: kubernetes-sandbox
role: external-secrets
serviceAccountRef:
name: external-secrets
namespace: external-secrets
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- auth-delegator.yaml
- clustersecretstore.yaml
@@ -0,0 +1,35 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: external-secrets
namespace: external-secrets
spec:
chart:
spec:
chart: external-secrets
interval: 1h
sourceRef:
kind: HelmRepository
name: external-secrets
version: 2.8.0
driftDetection:
mode: enabled
install:
crds: CreateReplace
strategy:
name: RetryOnFailure
retryInterval: 5m
interval: 30m
releaseName: external-secrets
targetNamespace: external-secrets
timeout: 10m
upgrade:
crds: CreateReplace
strategy:
name: RetryOnFailure
retryInterval: 5m
valuesFrom:
- kind: ConfigMap
name: external-secrets-values
valuesKey: values.yaml
@@ -0,0 +1,8 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- repository.yaml
- values.yaml
- helmrelease.yaml
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets
@@ -0,0 +1,9 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: external-secrets
namespace: external-secrets
spec:
interval: 1h
url: https://charts.external-secrets.io
@@ -0,0 +1,31 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: external-secrets-values
namespace: external-secrets
data:
values.yaml: |
replicaCount: 1
webhook:
replicaCount: 1
resources:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
certController:
replicaCount: 1
resources:
requests: {cpu: 10m, memory: 32Mi}
limits: {memory: 128Mi}
resources:
requests: {cpu: 10m, memory: 64Mi}
limits: {memory: 256Mi}
serviceAccount:
create: true
name: external-secrets
installCRDs: true