跳到主要内容
版本:1.8.0

外部数据库

使用 Helm 安装的 AISIX Enterprise 控制面可以使用 Chart 随附的 PostgreSQL 实例,也可以使用由 DBA 团队管理的外部 PostgreSQL 数据库。外部数据库连接角色只需要拥有控制面数据库,不需要 SUPERUSER、CREATEROLE 或 BYPASSRLS。不支持其它数据库引擎。

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。

cp-api 同时提供控制台,并将控制台账号和登录会话存储在同一个数据库中。控制台本身不持有数据库连接。

PostgreSQL 要求​

  • PostgreSQL 14 或更高版本。
  • 一个由控制面连接角色拥有的空数据库。
  • 一个拥有该数据库的登录角色,可以是 NOSUPERUSER、NOCREATEROLE 和 NOBYPASSRLS。cp-api 和 dp-manager 都以该角色连接。
  • 不需要 PostgreSQL 扩展。UUID 使用内置的 gen_random_uuid()。

为什么数据库所有权就足够​

首次启动时,cp-api 会准备数据库 schema。拥有数据库后,它可以创建 public 和 auth schema、表、索引和函数,并在之后对它们执行 migration。在 PostgreSQL 默认权限下,数据库 owner 可以在 public 中创建对象,因此标准集群不需要额外 schema grant。

AISIX Enterprise 不使用 PostgreSQL 行级安全(Row-Level Security)。cp-api 不会创建额外的数据库角色,也不会创建行级安全策略,处理请求时也不会切换角色,因此连接角色不需要角色管理或绕过行级安全的权限。组织之间的隔离由控制面自身的查询保证。

创建数据库和角色​

以数据库管理员身份执行一次,使用能够创建角色和数据库的账号。控制面连接角色本身除了拥有自己的数据库之外,不需要其他权限。

-- 1) 控制面使用的专用登录角色,不需要任何特殊属性。
CREATE ROLE aisix LOGIN PASSWORD 'change-me-to-a-strong-password'
NOSUPERUSER NOCREATEROLE NOBYPASSRLS;

-- 2) 由该角色拥有的专用数据库。
CREATE DATABASE aisix_cloud OWNER aisix;

你可以自行选择角色名、密码和数据库名。数据库所有权让 aisix 可以在首次启动时创建 public 对象并添加 auth schema。

Chart 渲染的连接 URL 中不包含密码。每个控制面组件会从 Kubernetes Secret 读取密码,并在启动时对其进行百分号编码后拼入 URL,因此密码可以包含 +、/、= 等字符。参见 部署 AISIX Enterprise 控制面。

如果 DBA 加固了 public schema,例如撤销了默认 CREATE 权限,请连接到新数据库后显式授予 schema 访问权限:

\c aisix_cloud
GRANT USAGE, CREATE ON SCHEMA public TO aisix;

连接控制面到数据库​

使用 Helm 时,请按照AISIX Enterprise 配置中的说明设置 externalDatabase.* values,并设置 postgresql.builtin=false。Chart 会根据这些值为控制面服务构造连接 URL。两个服务都以 externalDatabase.username 连接。

控制面只通过一个数据库 URL 连接。请让 twoDSN.enabled 保持默认值 false。该值为 true 时,Helm 首先要求设置 twoDSN.existingSecret,或设置非空且不以 CHANGE_ME 开头的 twoDSN.servingPassword;通过该检查后,Chart 会以 database.admin_url 渲染第二个数据库 URL,cp-api 随后会拒绝以 on-premises 模式启动,原因写在它的 Pod 日志中。不使用 Chart 时,只为 cp-api 设置 database.url(AISIX_CLOUD_DATABASE_URL);如果同时设置了 database.admin_url(AISIX_CLOUD_ADMIN_DATABASE_URL),cp-api 会拒绝启动。仍设置了该项的部署请参见从 1.7.0 或更早版本升级。

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

信任私有数据库 CA​

externalDatabase.sslmode 接受 libpq 的各个模式。require 只加密连接,不校验服务器身份;verify-ca 还会校验服务器证书是否由受信任的证书颁发机构签发;verify-full 在此基础上再校验证书中的主机名与所连接的主机一致。通过不受你控制的网络访问托管数据库时,建议使用 verify-full。

默认情况下,verify-ca 和 verify-full 只信任镜像系统信任库中的证书颁发机构。大多数托管 PostgreSQL 服务(例如 Amazon RDS、Google Cloud SQL 和 Azure Database for PostgreSQL)使用自己的 CA 签发服务器证书,因此在把该 CA 提供给控制面之前,连接会以 certificate signed by unknown authority 失败。

把服务商的 CA 证书包存入控制面所在命名空间的 Secret。以下命令以命名空间 aisix 中的 release aisix-cp 为例,请替换为实际 release 和命名空间:

kubectl create secret generic pg-ca \
--namespace aisix --from-file=ca.crt=./rds-ca.pem

然后在 values 文件中引用它:

values.yaml
postgresql:
builtin: false
externalDatabase:
sslmode: verify-full
sslRootCert:
existingSecret: pg-ca
# 仅当证书包存放在 ca.crt 以外的 key 下时需要设置。
key: ca.crt

Chart 会把证书包以只读方式挂载到 cp-api 和 dp-manager 中,两者在打开的每个数据库连接上都把它用作 libpq 的 sslrootcert,包括 dp-manager 内嵌的配置存储。配置了 CA 后,require 也会按照 libpq 的语义用它校验服务器证书。postgresql.builtin=true 时该设置会被忽略。

轮换 CA 时,先更新 Secret,再重启这两个工作负载,使其读取新的证书包:

kubectl rollout restart deployment/aisix-cp-api deployment/aisix-cp-dpm \
--namespace aisix

不使用 Chart 时,把证书包挂载到各组件中,并在 cp-api 和 dp-manager 的配置文件中设置 database.ssl_root_cert,或设置环境变量 AISIX_CLOUD_DATABASE_SSL_ROOT_CERT 和 AISIX_DPMGR_DATABASE_SSL_ROOT_CERT,取值为证书包的路径。

控制面会创建什么​

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

  • 用于控制面表的 public schema,例如 organizations、environments、models、调用方 API Key 和预算,由你的角色拥有;
  • 用于认证表的 auth schema,例如 users 和 sessions;
  • 少数维护用户账号记录的函数,只有你的角色可以执行。

它不会创建任何数据库角色或行级安全策略。

数据库权限检查清单​

与 DBA 团队评审数据库角色时,可以使用以下清单:

要求作用
LOGIN允许控制面服务以该角色连接数据库。
数据库所有权允许 cp-api 创建和修改 schema、表、索引和函数。
USAGE, CREATE ON SCHEMA public仅在 public schema 被加固时需要。
不需要 SUPERUSER、CREATEROLE 或 BYPASSRLS这些属性都不需要。

验证数据库设置​

控制面启动后,以管理员身份连接数据库,确认两个 schema 都已创建:

SELECT nspname FROM pg_namespace WHERE nspname IN ('public', 'auth');
-- 预期结果:两行

排查启动错误​

可以根据启动错误信息定位缺失的数据库能力。

permission denied for schema public

该角色无法在 public schema 中创建对象。请确认数据库所有权。如果 schema 被锁定,请显式授予 schema 访问权限:

\c aisix_cloud
GRANT USAGE, CREATE ON SCHEMA public TO aisix;

database.admin_url is set by ..., but deployment.mode is on-premises (...), which connects through database.url alone ...

部署仍配置了第二个特权数据库 URL,而 AISIX Enterprise 不使用它。请把 database.url 设置为 database.admin_url 的值(即拥有数据库的角色),并删除 database.admin_url。使用 Helm 时,设置 twoDSN.enabled=false。

an on-premises control plane does not use row-level security, but an earlier release left it on tables this database role does not own ...

从 1.7.0 或更早版本升级的数据库中,有表由其他角色持有。参见由其他角色持有的表。

下一步​

数据库和角色准备完成后,请返回 部署 AISIX Enterprise 控制面,配置控制面使用外部数据库。

完整的 Helm values 请参见AISIX Enterprise 配置。

如需规划数据库容量、监控数据库,以及了解控制面自动完成的维护,请参见数据库运维。