将 Agent Sandbox 的 API Key 存储后端由默认的 Secret 切换为云数据库 RDS MySQL,适用于多租户或 Key 数量较多的生产环境。
背景信息
ack-sandbox-manager 支持 Secret 和 MySQL 两种 API Key 存储后端,由 keyStorage.mode 配置项控制,取值为 secret(默认)或 mysql。Secret 后端在开发测试和 Key 数量较少的场景下已可满足需求;如果需要在多租户或 Key 数量较多的生产环境中使用,可切换为 RDS MySQL,此时数据规模不再受单个 Secret 大小限制。
|
对比项 |
Secret(默认) |
MySQL |
|
外部依赖 |
无 |
需要 MySQL 实例,并配置 DSN 和 |
|
存储位置 |
|
外部 MySQL 数据库。 |
|
Key 存储形式 |
存储可恢复的 API Key 原文。 |
仅存储 |
|
容量 |
受 Kubernetes 单个 Secret 1 MiB 上限约束。 |
不受单个 Secret 大小限制,容量取决于数据库实例。 |
|
读写方式 |
每次增删均更新整个 Secret,记录增多后读写开销上升。 |
按 Key 哈希查询,读写开销相对稳定。 |
|
多副本 |
多个副本共享同一个 Secret。 |
多个副本共享同一个数据库。 |
|
适用场景 |
开发测试、单租户或 Key 数量较少的场景。 |
生产环境、多租户或 Key 数量较多的场景。 |
根据集群中的 API Key 总数选择后端:
-
不超过 500 条:可以使用 Secret。
-
501~1000 条:建议规划迁移至 MySQL。
-
超过 1000 条:应使用 MySQL,避免 Secret 因接近 1 MiB 上限而写入失败。
适用范围
-
已完成 Agent Sandbox 多租户管理配置,安装
ack-sandbox-manager(v0.6.7 及以上版本)并启用 API Key 鉴权。具体操作,请参见多租户管理。
创建并配置 RDS MySQL 实例
API Key 存储属于数据量小、以哈希点查为主的 OLTP(Online Transaction Processing,联机事务处理)负载。购买 RDS MySQL 实例前,可展开下方选型建议规划实例配置。
-
访问 RDS 购买页面,创建 RDS MySQL 实例。建议选择与 ACS 集群相同的地域和 VPC,并参考上方选型建议配置实例。
-
创建数据库和账号。在 RDS 实例的数据库管理和账号管理页面中完成以下操作。具体操作,请参见创建账号。
-
创建一个数据库,例如
e2b。 -
创建一个普通数据库账号,并记录账号名和密码。
-
授予该账号对目标数据库的读写(DDL+DML)权限。
-
-
配置 IP 白名单。
sandbox-manager等控制面组件的访问流量从控制面交换机发出,因此需要将控制面交换机网段加入 RDS 白名单。 -
在 RDS 实例的数据库连接页面中,记录内网地址和内网端口,例如:
rm-******************.mysql.rds.aliyuncs.com:3306 -
手动初始化表结构。执行 OpenKruise 社区提供的 mysql-schema.sql 脚本初始化数据库表结构:
mysql -h <RDS内网地址> \ -P <端口> \ -u <数据库账号> \ -p \ <数据库名> < mysql-schema.sql该脚本会创建
teams和team_api_keys表,并初始化内置的adminTeam。admin API Key 的哈希无需迁移,ack-sandbox-manager启动时会根据当前hashPepper自动计算并写入team_api_keys。
配置 MySQL 存储后端
-
登录容器计算服务控制台,进入目标集群。
-
在组件管理页面找到
ack-sandbox-manager,单击配置。 -
配置以下参数:
配置项
配置值或说明
keyStorage.mode设置为
mysql。keyStorage.mysql.dsnMySQL 数据源名称(Data Source Name,DSN),描述连接目标数据库的账号、密码、地址、端口及连接参数,格式见下方示例。
keyStorage.mysql.hashPepper用于计算 API Key 哈希的长期密钥。
-
按以下格式填写 DSN:
<账号>:<密码>@tcp(<RDS内网地址>:<端口>)/<数据库名>?charset=utf8mb4&parseTime=true&loc=Local示例:
e2b_user:********@tcp(rm-******************.mysql.rds.aliyuncs.com:3306)/e2b?charset=utf8mb4&parseTime=true&loc=Local使用以下命令生成一个 32 字节(256 bit)的随机字符串作为
hashPepper。openssl rand -hex 32命令输出为 64 个十六进制字符,直接作为
keyStorage.mysql.hashPepper的取值。重要请长期、安全地保存
hashPepper,不要将其与数据库密码设置为相同的值。更换该值后,现有租户 API Key 将无法通过鉴权,需要重新签发。 -
保存配置。
ack-sandbox-manager将自动重启并连接 RDS MySQL。当
keyStorage.mode设置为mysql时,如果未配置 DSN 或hashPepper,组件将启动失败。
验证配置
-
确认
ack-sandbox-managerPod 正常运行:kubectl get pods -n sandbox-system -l component=sandbox-manager预期输出:
NAME READY STATUS RESTARTS AGE sandbox-manager-79b7449778-xxx 2/2 Running 0 78m sandbox-manager-79b7449778-yyy 2/2 Running 0 79m sandbox-manager-79b7449778-zzz 2/2 Running 0 78m -
创建、查询并删除一个临时 API Key,以验证 MySQL 后端可正常读写。执行前请根据实际环境替换以下变量:
-
BASE_URL:ack-sandbox-gateway对外访问地址。 -
ADMIN_KEY:ack-sandbox-manager配置的 admin API Key。
以下脚本依赖 jq(命令行 JSON 处理器)解析响应,执行前请确认本地已安装。
BASE_URL="https://api.your.domain.com" ADMIN_KEY="your-admin-key" TEST_KEY_ID=$( curl -fsS -X POST \ -H "X-API-KEY: ${ADMIN_KEY}" \ -H "Content-Type: application/json" \ -d '{"name":"mysql-storage-verification"}' \ "${BASE_URL}/api-keys" | jq -r '.id' ) echo "Created: ${TEST_KEY_ID}" curl -fsS \ -H "X-API-KEY: ${ADMIN_KEY}" \ "${BASE_URL}/api-keys" | jq -e --arg id "${TEST_KEY_ID}" \ 'any(.[]; .id == $id)' >/dev/null && echo "Query OK" curl -fsS -X DELETE \ -H "X-API-KEY: ${ADMIN_KEY}" \ "${BASE_URL}/api-keys/${TEST_KEY_ID}" && echo "Deleted: ${TEST_KEY_ID}"预期输出:
Created: 4f2ab49a-aced-4830-b5da-5d382xxxxxxx Query OK Deleted: 4f2ab49a-aced-4830-b5da-5d382xxxxxxx -
迁移已有 API Key(可选)
切换到 MySQL 后端后,如果原 Secret 后端中已有 API Key 需要在新后端继续使用,可以使用 OpenKruise 社区提供的 migrate_secret_keys_to_mysql.py 脚本生成 MySQL 迁移 SQL。迁移脚本会:
-
通过
kubectl读取e2b-key-storeSecret。 -
使用与
keyStorage.mysql.hashPepper相同的值计算 API Key 的 HMAC-SHA256 哈希。 -
生成建表 DDL,以及 Team 和 API Key 的 Upsert 语句。
-
保留原有 Team、Key 名称、创建信息和配额配置。
迁移开始后,请暂停调用 POST /api-keys 和 DELETE /api-keys/{id},直至完成数据导入,避免迁移期间产生的数据变更丢失。
-
校验 Secret 数据:
python3 migrate_secret_keys_to_mysql.py \ --namespace sandbox-system \ --dry-run该命令会解析 Secret 中的所有条目,校验
id、name、key等字段的合法性,检查 Team 元数据是否一致以及原始 Key 是否唯一,任何一项不通过都会中止迁移,避免生成不完整的 SQL。 -
通过隐藏输入设置
hashPepper(值必须与已配置的keyStorage.mysql.hashPepper完全一致),并生成迁移 SQL:read -rsp "请输入 hashPepper: " E2B_KEY_HASH_PEPPER echo export E2B_KEY_HASH_PEPPER python3 migrate_secret_keys_to_mysql.py \ --namespace sandbox-system \ --output e2b_key_migration.sql -
将迁移 SQL 导入 RDS MySQL:
mysql -h <RDS内网地址> \ -P <端口> \ -u <数据库账号> \ -p \ <数据库名> < e2b_key_migration.sql -
清理环境变量和迁移文件:
unset E2B_KEY_HASH_PEPPER rm -f e2b_key_migration.sql
生成 SQL 时使用的 hashPepper 必须与已配置的 keyStorage.mysql.hashPepper 完全一致,否则迁移后的 API Key 无法通过鉴权。