Skip to main content

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
note

这个能力是加性的:它只管理自己那一个命名的存储位置与凭据 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.baseURLJDC_VAULT_BASE_URLJDC Vault 后端地址
vault.tokenURLJDC_VAULT_TOKEN_URLKeycloak realm 的 token 端点
vault.clientIDJDC_VAULT_CLIENT_ID机器客户端 ID,默认 jdc-vault-supkube
vault.clientSecretRefJDC_VAULT_CLIENT_SECRET从哪个 Secret 的哪个 key 读 client secret
vault.provisionOnStartVAULT_PROVISION_ON_START为 true 时后端启动即自动申领,无需手工调 API

四个 JDC_VAULT_* 环境变量缺一不可,少任何一个都视为该功能未启用:路由不注册,启动也不会自动申领。

以下三项没有对应的 values 字段,需要改默认名时直接在 Deployment 上加环境变量:

环境变量默认值含义
VAULT_BSL_NAMEvault-supkube生成的 Velero 存储位置名
VAULT_BSL_SECRETvault-supkube-creds存放 S3 凭据的 Secret 名
VAULT_BUCKET_NAMEsupkube-velero在 Vault 侧申领的库名

认证方式​

SupKube 使用 OAuth2 客户端凭据模式(client_credentials)以自己的机器身份访问 Vault,落在它自己的租户下,不共享任何管理员令牌,也不借用登录用户的身份。

申领过程做了什么​

无论是启动时自动执行还是手工调用 API,动作完全一致且幂等:

  1. 在 Vault 侧查找本租户的 MinIO 订阅,找不到就中止并报错。
  2. 查找名为 supkube-velero 的库;不存在则新建,已存在则刷新其 S3 凭据。
  3. 在 Velero 所在命名空间写出凭据 Secret(cloud 这个 key,内容是 AWS INI 格式)。
  4. 写出 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

该接口是 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 并带上原始错误信息。

note

vault.enabled=false(或四个环境变量没配全)时,这个路由根本不存在,请求会得到 404 而不是 403。

验证方法​

确认存储位置已生成并可用:

kubectl get backupstoragelocation -A | grep vault-supkube
kubectl -n supkube get secret vault-supkube-creds
命名空间不是 velero

Chart 已把 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: ...,错误原因就在该行末尾。

生成之后,这个存储位置在界面「存储位置」列表里与其他条目一样可见,创建备份策略时可直接选用。

相关文档​