JDC Vault 不可变备份库
开启后,SupKube 会用自己的机器身份向 JDC Vault 申领一个 WORM(一次写入、多次读取)保护的对象存储库,并自动写出一个指向它的 Velero 存储位置,让备份直接落进不可篡改的库里。
前置条件
- SupKube 版本
0.9.1-alpha.9或更新(本功能随feat/vault-backup-target合入主线)。 - 可访问的 JDC Vault 服务,以及签发机器身份令牌的 Keycloak realm。
- Vault 侧租户必须已有一个 MinIO 订阅。没有订阅时申领会直接失败,错误信息为
no MinIO subscription for this tenant; create one first,需由 Vault 管理员先创建(POST /subscriptions且provider=minio)。 - 一个带外创建好的 Secret,存放机器客户端的 OIDC client secret。
它与普通存储位置的区别
| 维度 | 普通存储位置 | JDC Vault 备份库 |
|---|---|---|
| 谁创建 | 您在界面上手工填写 | SupKube 启动时或调用 API 自动申领 |
| 凭据来源 | 您自己准备并填入 | Vault 按机器身份下发,随申领刷新 |
| 不可变保护 | 取决于您所用对象存储是否开了对象锁 | 由 Vault 库的不可变天数强制 |
| Velero 资源名 | 您自取 | 默认 vault-supkube |
这个能力是加性的:它只管理自己那一个命名的存储位置与凭据 Secret,不会改动或删除您已有的任何存储位置。
启用
在 values.yaml 中打开 vault 配置块:
vault:
enabled: true
baseURL: http://jdc-vault-backend.jdc-vault.svc.cluster.local:8080
tokenURL: https://keycloak.example.com/auth/realms/jumborca/protocol/openid-connect/token
clientID: jdc-vault-supkube
clientSecretRef:
name: supkube-vault-oidc
key: JDC_VAULT_CLIENT_SECRET
provisionOnStart: true
client secret 必须带外先创建好,Chart 不会替您生成:
kubectl -n supkube create secret generic supkube-vault-oidc \
--from-literal=JDC_VAULT_CLIENT_SECRET='<从 Keycloak 取得的 client secret>'
装上或升级:
helm upgrade --install supkube supkube/supkube \
-n supkube --create-namespace \
-f values.yaml
配置项说明
| 配置项 | 对应环境变量 | 说明 |
|---|---|---|
vault.enabled | — | 总开关,默认 false。关闭时下列环境变量完全不注入 |
vault.baseURL | JDC_VAULT_BASE_URL | JDC Vault 后端地址 |
vault.tokenURL | JDC_VAULT_TOKEN_URL | Keycloak realm 的 token 端点 |
vault.clientID | JDC_VAULT_CLIENT_ID | 机器客户端 ID,默认 jdc-vault-supkube |
vault.clientSecretRef | JDC_VAULT_CLIENT_SECRET | 从哪个 Secret 的哪个 key 读 client secret |
vault.provisionOnStart | VAULT_PROVISION_ON_START | 为 true 时后端启动即自动申领,无需手工调 API |
四个 JDC_VAULT_* 环境变量缺一不可,少任何一个都视为该功能未启用:路由不注册,启动也不会自动申领。
以下三项没有对应的 values 字段,需要改默认名时直接在 Deployment 上加环境变量:
| 环境变量 | 默认值 | 含义 |
|---|---|---|
VAULT_BSL_NAME | vault-supkube | 生成的 Velero 存储位置名 |
VAULT_BSL_SECRET | vault-supkube-creds | 存放 S3 凭据的 Secret 名 |
VAULT_BUCKET_NAME | supkube-velero | 在 Vault 侧申领的库名 |
认证方式
SupKube 使用 OAuth2 客户端凭据模式(client_credentials)以自己的机器身份访问 Vault,落在它自己的租户下,不共享任何管理员令牌,也不借用登录用户的身份。
申领过程做了什么
无论是启动时自动执行还是手工调用 API,动作完全一致且幂等:
- 在 Vault 侧查找本租户的 MinIO 订阅,找不到就中止并报错。
- 查找名为
supkube-velero的库;不存在则新建,已存在则刷新其 S3 凭据。 - 在 Velero 所在命名空间写出凭据 Secret(
cloud这个 key,内容是 AWS INI 格式)。 - 写出
BackupStorageLocation,provider 为aws,并按 S3 兼容方式配置:s3Url、region、s3ForcePathStyle: true。
重复执行只会更新这两个对象,不会产生重复资源。
启动时自动申领的重试行为
provisionOnStart: true 时,后端在启动后于后台执行,最多重试 5 次、每次间隔 15 秒、单次超时 60 秒。5 次都失败即放弃,且不会影响后端本身启动——SupKube 照常提供服务,只是没有这个存储位置。
因此若 Vault 暂时不可达,后端不会崩溃,但也不会无限重试;排除故障后请按下一节手工触发一次。
手工触发申领
curl -X POST https://supkube.example.com/api/v1/vault/provision \
-H "Authorization: Bearer <您的令牌>"
该接口是 admin 专属,editor 与 viewer 调用会被拒绝。它会创建备份基础设施,因此不对低权限角色开放。
成功返回申领结果:
{
"status": "provisioned",
"target": {
"bslName": "vault-supkube",
"secretName": "vault-supkube-creds",
"bucket": "supkube-velero-a1b2c3",
"endpoint": "https://vault-minio.example.com",
"region": "us-east-1",
"namespace": "velero"
}
}
若 Vault 侧出错,接口返回 502 并带上原始错误信息。
vault.enabled=false(或四个环境变量没配全)时,这个路由根本不存在,请求会得到 404 而不是 403。
验证方法
确认存储位置已生成并可用:
kubectl get backupstoragelocation -A | grep vault-supkube
kubectl -n supkube get secret vault-supkube-creds
veleroChart 已把 Velero 收口进 release 命名空间(默认 supkube),存储位置与凭据 Secret 都在那里。用 -A 可以避免猜错。
存储位置的 PHASE 变为 Available 即表示 Velero 能正常连上该库。
查看启动自动申领的结果:
kubectl -n supkube logs deploy/supkube-backend | grep '\[vault\]'
成功时会看到类似 [vault] provisioned on start: bsl=vault-supkube bucket=... endpoint=...;
失败时会看到 [vault] provision-on-start attempt N/5 failed: ...,错误原因就在该行末尾。
生成之后,这个存储位置在界面「存储位置」列表里与其他条目一样可见,创建备份策略时可直接选用。