外部数据库
默认情况下,私有化部署控制面会包含一个 PostgreSQL 数据库。如果希望改用 DBA 团队管理的数据库,请禁用随包数据库实例,并配置控制面连接到你的数据库。
本指南介绍私有化控制面的 PostgreSQL 外部数据库路径。控制面连接角色不需要 PostgreSQL 超级用户权限。该部署路径暂不支持其它数据库引擎。
控制面后端服务会共享同一个数据库:
cp-api:控制面 API Server,启动时会执行 schema migration。dp-manager:数据面管理器,连接同一个数据库,但不执行 migration。
PostgreSQL 要求
- PostgreSQL 14 或更高版本。
- 一个由控制面连接角色拥有的空数据库。
- 一个带
CREATEROLE和BYPASSRLS权限、但不是SUPERUSER的登录角色。 - 不需要 PostgreSQL 扩展。UUID 使用内置的
gen_random_uuid()。
为什么控制面需要这些权限
首次启动时,cp-api 会准备数据库 schema,并创建一个内部低权限角色。连接角色需要足够权限来完成该引导过程,以及执行共享控制面操作。
每项权限都有明确用途:
- 数据库所有权允许
cp-api创建public和authschema、表、索引、函数和行级安全策略。在 PostgreSQL 默认权限下,数据库 owner 可以在public中创建对象,因此标准集群不需要额外 schema grant。 - **
CREATEROLE**允许cp-api创建和 配置内部角色cp_api_app。该角色用于带行级安全的租户范围查询。你不需要手动创建这个角色。 - **
BYPASSRLS**允许共享控制面操作在必要时跨组织读取数据,包括调用方 token 认证、计费 webhook、后台预算聚合器和dp-manager操作。
租户范围请求仍会切换到 cp_api_app,该角色既不是 SUPERUSER,也没有 BYPASSRLS。因此,控制面连接角色需要特定 PostgreSQL 能力,但不需要超级用户权限。
创建数据库和角色
以数据库管理员身份执行一次。请使用能够创建角色、创建数据库并授予 BYPASSRLS 的账号。控制面连接角色本身不需要是超级用户。
-- 1) 为控制面创建专用登录角色,不是超级用户。
CREATE ROLE aisix LOGIN PASSWORD 'change-me-to-a-strong-password'
NOSUPERUSER CREATEROLE BYPASSRLS;
-- 2) 创建由该角色拥有的专用数据库。
CREATE DATABASE aisix_cloud OWNER aisix;
你可以自行选择角色名、密码和数据库名。数据库所有权让 aisix 可以在首次启动时创建 public 对象并添加 auth schema。
请使用 URL 安全的密码,因为密码会嵌入 PostgreSQL 连接 URL 中。+、/、= 等字符如果没有百分号编码,可能破坏 DSN。建议使用 URL 安全值,例如 openssl rand -hex 24。参见私有化部署。
如果 DBA 加固了 public schema,例如撤销了默认 CREATE 权限,请连接到新数据库后显式授予 schema 访问权限:
\c aisix_cloud
GRANT USAGE, CREATE ON SCHEMA public TO aisix;
不要预先创建 cp_api_app 角色。控制面会在 migration 期间创建并配置该角色,同时校验它的属性。提前创建该角色,尤其是属性不一致时,可能导致 migration 安全检查失败。
连接控制面到数据库
使用 Helm 时,请按照私有化部署配置中的说明设置 externalDatabase.* values,并设置 postgresql.builtin=false。Chart 会根据这些值为控制面服务构造连接 URL。
对于 Docker Compose 部署,服务会从环境变量读取标准 PostgreSQL 连接 URL。请让每个服务使用同一个角色和数据库:
AISIX_CLOUD_DATABASE_URL="postgres://aisix:<url-encoded-password>@db.internal.example.com:5432/aisix_cloud?sslmode=require"
AISIX_DPMGR_DATABASE_URL="postgres://aisix:<url-encoded-password>@db.internal.example.com:5432/aisix_cloud?sslmode=require"
AISIX_CLOUD_DATABASE_URL:由cp-api和 Dashboard 读取,其中cp-api会在启动时执行 migration。AISIX_DPMGR_DATABASE_URL:由dp-manager读取。如果全新集群中cp-api仍在执行 migration,schema 尚未就绪,dp-manager会重试最多约 2 分钟。
当数据库通过不完全受控的网络访问时,请设置 sslmode=require,或使用更严格的模式,例如 verify-full。
控制面会创建什么
首次成功启动时,cp-api 会在你准备的数据库中构建完整 schema;之后每次启动都会以幂等方式重新执行相同步骤:
- 用于控制面表的
publicschema,例如 organizations、environments、models、caller API keys 和 budgets,由你的角色拥有; - 用于认证表的
authschema,例如 users 和 sessions; cp_api_app角色,属性为NOSUPERUSER NOBYPASSRLS NOINHERIT NOLOGIN,只被授予控制面表的 CRUD 权限,以及少数非敏感身份列的读写权限;- 将每个租户表限定到单个组织的行级安全策略。
连接角色会自动成为 cp_api_app 的成员,因此可以在每个请求中切换到该角色。你不需要手动授予该成员关系。
数据库权限检查清单
与 DBA 团队评审数据库角色时,可以使用以下清单:
| 要求 | 作用 |
|---|---|
LOGIN | 允许控制面服务以该角色连接数据库。 |
| 数据库所有权 | 允许 cp-api 创建和修改 schema、表、索引、函数和 RLS 策略。 |
CREATEROLE | 允许 cp-api 创建并管理内部 cp_api_app 角色。 |
BYPASSRLS | 允许跨组织控制面路径和 dp-manager 在共享连接上读取所需数据。 |
不是 SUPERUSER | 将角色权限控制在 PostgreSQL 超级用户以下。 |
验证数据库设置
控制面启动后,以管理员身份连接数据库并确认引导结果。
内部角色存在且权限正确受限:
SELECT rolname, rolsuper, rolbypassrls, rolcanlogin
FROM pg_roles WHERE rolname = 'cp_api_app';
-- 期望结果:cp_api_app | f | f | f
两个 schema 已创建:
SELECT nspname FROM pg_namespace WHERE nspname IN ('public', 'auth');
-- 期望结果:两行
排查启动错误
可以根据启动错误信息定位缺失的数据库能力。
cp-api database role must be SUPERUSER or have BYPASSRLS ...
连接角色缺少 BYPASSRLS。请以数据库管理员身份授予:
ALTER ROLE aisix BYPASSRLS;
permission denied for schema public
该角色无法在 public schema 中创建对象。请确认数据库所有权。如果 schema 被锁定,请显式授予 schema 访问权限:
\c aisix_cloud
GRANT USAGE, CREATE ON SCHEMA public TO aisix;
permission denied to create role
连接角色缺少 CREATEROLE。请以数据库管理员身份授予:
ALTER ROLE aisix CREATEROLE;
permission denied to set role "cp_api_app"
授予 cp_api_app 成员关系的 migration 可能没有完成。请检查 cp-api 启动日志中是否有更早的 migration 错误。
下一步
数据库和角色准备完成后,请返回私有化部署,配置控制面使用外部数据库。
完整的 Docker Compose 环境变量和 Helm values 请参见私有化部署配置。