跳到主要内容

外部数据库

使用 Helm 安装的 AISIX Cloud 控制面可以使用 Chart 随附的 PostgreSQL 实例,也可以使用由 DBA 团队管理的外部 PostgreSQL 数据库。外部数据库连接角色需要特定数据库权限,但不需要 SUPERUSER。不支持其它数据库引擎。

Docker Compose 必须使用随包 PostgreSQL

在线和离线 Docker Compose 部署包不支持外部数据库。其 Compose 文件会将控制面服务的数据库 URL 指向随包提供的 postgres 服务,且不会在 .env 中提供覆盖项。控制面必须连接外部 PostgreSQL 数据库时,请使用 Helm。

控制面服务会共享同一个数据库:

  • cp-api:控制面 API Server,启动时会执行 schema migration。
  • dp-manager:数据面管理器,连接同一个数据库,但不会执行控制面应用的 migration。其内嵌 Kine 后端会管理自己的存储 schema。在全新数据库中,如果应用 schema 尚未就绪,dp-manager 会重试最多约两分钟,等待 cp-api 完成 migration。
  • 控制台:控制面用户界面,将身份认证数据存储在同一个数据库中。

PostgreSQL 要求

  • PostgreSQL 14 或更高版本。
  • 一个由控制面连接角色拥有的空数据库。
  • 一个带 CREATEROLEBYPASSRLS 权限、但不是 SUPERUSER 的登录角色。
  • 不需要 PostgreSQL 扩展。UUID 使用内置的 gen_random_uuid()

为什么控制面需要这些权限

首次启动时,cp-api 会准备数据库 schema,并创建一个内部低权限角色。连接角色需要足够权限来完成该引导过程,以及执行共享控制面操作。

每项权限都有明确用途:

  • 数据库所有权允许 cp-api 创建 publicauth schema、表、索引、函数和行级安全策略。在 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。参见 On-Premises 安装

如果 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。

当数据库通过不完全受控的网络访问时,请设置 sslmode=require,或使用更严格的模式,例如 verify-full

控制面会创建什么

首次成功启动时,cp-api 会在你准备的数据库中构建完整 schema。之后启动时,它会应用尚未执行的 migration,并跳过已经完成的一次性 migration:

  • 用于控制面表的 public schema,例如 organizations、environments、models、调用方 API Key 和预算,由你的角色拥有;
  • 用于认证表的 auth schema,例如 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 错误。

下一步

数据库和角色准备完成后,请返回 On-Premises 安装,配置控制面使用外部数据库。

完整的 Helm values 请参见私有化部署配置