跳到主要内容
版本:Dev

升级 AISIX Enterprise

AISIX Enterprise 分两部分升级:控制面,以及承载流量的 AISIX 网关。两者按固定顺序独立升级,在逐台升级网关期间可以运行不同发布版本。支持的升级路径和具体流程取决于安装方式;各版本变更请参阅发布说明。

更改控制面前,请将数据库、密钥、部署配置和匹配的软件一起准备为恢复集。参见备份与恢复。对于 OKD 部署,请先完成 OKD 中的检查,再执行升级。

AISIX Enterprise 支持的升级路径​

AISIX Enterprise 支持的升级最低版本为 0.12.0。运行 0.12.0 或更高版本的 AISIX Enterprise 部署,可以直接升级到任何更新版本,包括当前版本。

版本可以跳过。从 0.12.0 直接升级到当前版本是受支持的,不需要逐个经过中间版本。决定升级是否受支持的是下限,而不是跨度:只要来源版本不低于 0.12.0,就可以一步升级到任意更新的目标版本。

升级下限只有在某个版本明确宣布上调时才会变化,不会随着新版本发布而静默抬高,因此今天受支持的部署会一直受支持,直到有版本公告说明为止。从较旧的部署规划跨版本升级前,请先查看目标版本的发布说明。

低于 0.12.0 的部署需要分两步升级:先升级到 0.12.0 与目标版本之间的某个版本,让它启动并完成数据库迁移,然后再升级到目标版本。

兼容性例外是按功能划分的,而不是按版本划分:升级过程中可能出现差异的,始终是某一项具体配置,而不是版本组合本身。这里有两种不同的差异。一种是网关版本无法加载的配置,它会让该网关丢掉整个资源——在 0.12.0 与当前版本之间不存在这样的配置,因此控制面能够保存的每一份配置,都能作为完整资源在下限以上的每个网关版本上加载。另一种是网关版本不认识的配置,这是升级期间的常见情况:资源照常加载并生效,只是这一项配置在该网关上不起作用,直到它被升级。

AISIX Enterprise 升级顺序与混合版本窗口​

先升级控制面,再升级网关。 控制面能够识别升级下限及以上的每个网关版本;网关不一定能够识别比自身更新的控制面。

在这两步之间,部署处于混合版本状态:控制面已是新版本,网关仍是旧版本。这个窗口由升级下限限定,而不是由时间限定。只要每台网关都不低于 0.12.0,这个窗口可以持续到你需要的任何时长——分批推进的机群升级、刻意滞后一周的灰度环境、按自己维护窗口升级的网关,都可以。整个期间网关照常承载流量。

环境的 Data planes 视图会逐实例显示网关版本,便于识别尚未升级的实例。控制面版本显示在控制台左侧导航底部,也可以通过 GET /api/config/public 获取;参见验证安装。

保存作用域内某些网关不认识的配置项是允许的。响应会给出字段名、第一个能够识别该字段的受支持网关版本,以及有多少台网关会忽略它。如果当前没有任何受支持版本能够识别该字段,响应也会明确说明。控制台会在保存后显示同一条警告。在依赖该配置项之前请先阅读警告:被忽略的限制类配置在这些网关上并不生效。

配置到达网关后,控制台还会显示各网关上报的信息。环境概览会区分被忽略的字段和整个资源被拒绝的情况,Data planes 则把受影响节点标记为 Limitations 或 Incompatible。这些运行时信号能够发现最初保存配置后才注册或发生回滚的网关。验证流程参见资源投射。

在网关侧,aisix_config_partially_compatible_resources 统计的是携带了本网关版本不认识的字段的资源数量。在窗口期内它可能不为零,网关升级完成后应回落到零。配置健康类指标参见指标参考。

跳过的每个版本,其升级说明依然适用​

跳过一个版本,跳过的是它的发布说明,而不是它带来的行为变化。一次跨越多个版本的升级,其间每个版本的升级说明都对你适用,并且要按顺序阅读——从你当前版本的下一个版本开始,一直读到目标版本,由旧到新。

升级说明记录的是升级前需要做的事:含义发生变化的配置项、开始生效的 Helm 取值、需要复核的告警表达式。被跳过版本中的说明,不会因为后续版本的说明而失效。

从更早的版本升级到 1.0.0 之前,还要完成升级到 1.0.0 时复核已有安全护栏。它不是一条升级说明,而是一份升级前检查清单:它要求你在控制面以新版本启动之前,先找出并停用受影响的语义安全护栏。

从 1.6.x 或更早版本升级:统一的 SSRF 防护设置​

cp-api 现在用一个服务端请求伪造(SSRF)防护设置控制它向所提供 URL 发起的全部出站调用,不再按调用类型各设一个开关。该设置覆盖的范围参见私有网络访问。

已移除的 Helm 配置项已移除的变量已移除的配置键
api.playgroundAllowPrivateIPsAISIX_PLAYGROUND_ALLOW_PRIVATE_IPSoutbound.playground_allow_private_ips
api.notifyAllowPrivateURLsAISIX_CLOUD_NOTIFY_ALLOW_PRIVATE_URLSoutbound.notify_allow_private_urls
api.mcpSpecAllowPrivateURLsAISIX_CLOUD_MCP_SPEC_ALLOW_PRIVATE_URLSoutbound.mcp_spec_allow_private_urls
api.guardrailTestConnectionAllowInsecureAISIX_GUARDRAIL_TEST_CONNECTION_ALLOW_INSECUREoutbound.guardrail_test_connection_allow_insecure

取代它们的是 Helm Chart 中的 api.outbound.ssrfProtection.enabled 和 api.outbound.ssrfProtection.allowedHosts、环境变量 AISIX_CLOUD_SSRF_PROTECTION_ENABLED 和 AISIX_CLOUD_SSRF_PROTECTION_ALLOWED_HOSTS,以及配置文件中的 outbound.ssrf_protection.enabled 和 outbound.ssrf_protection.allowed_hosts。true 表示开启防护。未设置时跟随部署模式,on-premises 下关闭,因此从未设置过这些旧开关的控制面行为不变。

仍设置了已移除开关的 values 文件、.env 或配置文件可以正常安装和启动。cp-api 会忽略这些值,并在启动时为每一项打印一条 removed setting 警告,指明替代设置为 outbound.ssrf_protection。如果你曾把其中任何一项设为 false 以拒绝私有目标,请在升级前设置 api.outbound.ssrfProtection.enabled=true 或 AISIX_CLOUD_SSRF_PROTECTION_ENABLED=true,并把必须保持可达的内部主机列入允许的主机。防护不再按调用类型分别选择。

使用 helm upgrade --reuse-values 从 Chart 1.5.0 升级的 Helm Release,会把该 Chart 中 api.playgroundAllowPrivateIPs 和 api.notifyAllowPrivateURLs 的默认值 false 作为显式值保留,使 Playground 和预算通知无法访问私有地址。这些值现在会被忽略,因此除非设置 api.outbound.ssrfProtection.enabled=true,这类 Release 会从拒绝私有目标变为允许访问。

Playground 和通知投递现在与 cp-api 的其他出站调用一样,会经过 cp-api 环境中的 HTTPS_PROXY 或 HTTP_PROXY,除非 NO_PROXY 覆盖该主机。

从 1.5.x 或更早版本升级:控制台、访问与控制台部署方式的变化​

1.5.x 之后的版本将控制台登录移入 cp-api,由 cp-api 直接提供控制台,不再使用单独的控制台服务,并以 on-premises 部署模式运行控制面。从 1.5.x 或更早版本升级控制面之前,请先了解以下变化。

危险

如果待升级的控制面中有多个组织,升级后控制台会一直被锁定,直到某个 Owner 保留一个组织并永久删除其他所有组织。开始前请先阅读将多个组织合并为一个,并备份数据库。

现有会话失效​

升级前版本的会话不会保留,因此升级后所有用户都需要重新登录一次。账号和密码保持不变,使用原来的邮箱地址和密码即可登录。回滚到升级前的版本同样会让所有用户退出登录。

移除 Google 和 GitHub 登录​

控制台只提供邮箱和密码登录。只使用过 Google 或 GitHub 登录的用户没有密码,升级后无法登录。目前这类用户无法自助恢复访问:密码重置邮件只会发送给已有密码的账号。请在升级前确认有哪些这样的用户。

社交登录相关设置不再生效:Helm Chart 中的 api.oauthEnabled 和 secrets.oauth.*,以及 AISIX_CLOUD_OAUTH_ENABLED、AISIX_GOOGLE_OAUTH_* 和 AISIX_GITHUB_OAUTH_* 变量。

已移除的设置​

以下设置不再被读取。仍设置了它们的 values 文件或 .env 可以正常安装和启动,你可以将其删除:

Helm 配置项变量说明
secrets.betterAuthSecretBETTER_AUTH_SECRET、BETTER_AUTH_URL会话不再使用共享密钥签名。只要仍可能回滚到升级前的版本,就请保留该值,因为 1.5.x 及更早版本启动时需要它。
api.jwtAudienceAISIX_CLOUD_JWT_AUDIENCE控制台不再使用会话 JWT。
—AISIX_AUTH_REQUIRE_EMAIL_VERIFICATION已移除。
ui.image.*、ui.replicaCount、ui.resources 及其他 ui 工作负载配置项AISIX_UI_IMAGE不再有控制台镜像或工作负载。
—AISIX_CLOUD_DASHBOARD_URLcp-api 直接从自己的镜像中提供控制台文件。

控制台由 cp-api 提供​

不再有 aisix-cp-ui 镜像、控制台 Pod 或控制台容器。控制台文件随 cp-api 镜像发布,因此请从镜像同步列表和允许列表中移除 aisix-cp-ui。

  • Helm。 helm upgrade 会删除控制台 Deployment。<release>-ui Service 会保留,名称、类型、端口和 nodePort 都不变,但现在转发到 cp-api,因此仍指向它的反向代理或 NodePort 可以继续工作。新的配置请指向 cp-api Service。
  • Docker Compose。 Compose 文件中移除了 ui 服务,run.sh 会在升级时删除旧的 ui 容器。
  • 可信源站。 额外的登录源站现在使用 api.trustedOrigins。1.5.0 安装说明中放在 ui.extraEnvVars 里的 AISIX_TRUSTED_ORIGINS 条目仍会传给 cp-api;方便时请将其迁移到 api.trustedOrigins。
  • 语言。 Helm 中的 ui.defaultLocale 和 Docker Compose 中的 AISIX_DASHBOARD_LOCALE 仍然设置控制台语言,现在也决定邮件语言。如果你是直接在 1.5.x 的控制台容器上设置 AISIX_DASHBOARD_LOCALE,请改为在 cp-api 上设置 ui.defaultLocale 或 AISIX_CLOUD_DEFAULT_LOCALE。
  • 私有数据库 CA。 控制台不再连接数据库,因此 1.5.x 中为私有 PostgreSQL CA 配置的 ui.extraVolumes、ui.extraVolumeMounts 和 NODE_EXTRA_CA_CERTS 不再适用。请改用 externalDatabase.sslRootCert 把 CA 提供给 cp-api 和 dp-manager,参见信任私有数据库 CA。

原先在路径中携带 ID 的页面,现在改为通过查询参数传递 ID,例如 /environments/<page>?env=<id> 取代 /environments/<id>/<page>。团队、MCP 服务器工具和邀请页面也以同样方式变化。cp-api 会将旧链接(包括升级前已发出的邀请链接)重定向到新格式。

可以发送邮件​

控制面现在可以通过 SMTP 中继发送邀请邮件和密码重置邮件。在配置中继之前,邮件功能保持关闭,参见配置邮件(SMTP)。未配置时,邀请卡片不再提示邮件已发送,而是显示链接,由你转交给受邀者。

仅能通过邀请注册​

任何人都不能再自行注册。尚无账号的人需要管理员发出邀请,并通过邀请中的链接注册,参见邀请成员。已有账号及其密码不变。如果控制台以外的客户端过去只凭邮箱地址为受邀者注册,现在必须以 invitationToken 发送邀请 Token。

不能再创建组织​

任何人都无法通过控制台或 API 创建新组织。Owner 现在可以删除组织,但部署中的最后一个组织除外。包含多个组织的控制面必须先缩减为一个组织,控制台才能重新使用,参见将多个组织合并为一个。

将多个组织合并为一个​

一个 AISIX Enterprise 控制面仅服务一个组织,但 1.5.x 及更早版本允许任何人创建组织,因此升级后的控制面可能包含多个组织。在仍有多个组织时,用户无法访问控制台:每个页面都会重定向到 /consolidate,控制台请求会返回 403,错误码为 ORG_CONSOLIDATION_REQUIRED。Admin Token 仍可使用,网关流量不受影响。

危险

合并会永久删除除保留组织之外的所有组织(包括你不是成员的组织)及其中的全部内容:它们的环境及其中的模型、调用方 API Key 和其他资源,其成员的组织成员关系,以及用量和审计记录。连接到这些环境的所有网关证书都会被吊销,这些网关将与控制面断开。此操作无法撤销。如果有人需要这些组织中的数据,请在合并之前备份数据库。

任何至少是一个组织 Owner 的用户,都可以使用密码登录后执行合并:

  1. 使用密码登录。控制台会打开 Keep one organization 页面。
  2. 选择要保留的组织。只有你是 Owner 的组织可供选择。
  3. 核对将被删除的组织。页面会按名称和标识列出控制面上的其他所有组织。
  4. 输入要保留组织的标识,然后选择 Delete。按钮上会显示将被删除的组织数量。

每个被删除的组织都与 Owner 删除组织时的处理方式相同:对它的访问立即终止,其存储的数据(如用量和审计记录)随后在后台移除。

当只剩一个组织时,锁定立即解除,控制台会打开你保留的组织。本次合并会记录在该组织的审计日志中,资源类型为 organization,操作为 consolidate。

不是任何组织 Owner 的用户会看到一个页面,提示需由组织 Owner 登录并完成合并。

有密码的用户账号会保留。没有密码且只属于被删除组织的账号(例如直接创建或通过 SCIM 预配的成员)会随这些组织一起删除。有密码且只属于被删除组织的用户仍可登录,但不再属于任何组织,会看到联系管理员的提示,直到被邀请加入剩下的组织。系统不会自动把任何人加入保留的组织。

如果合并中途停止,已删除的组织不会恢复,控制台仍保持锁定。再次执行合并即可删除剩余的组织。

计费功能消失​

计费页面、组织套餐以及角色目录中的 billing 权限都已移除。

管理员保持不变​

升级后的控制面保留现有的账号、组织、Owner 和 Admin,他们照常登录。由于数据库中已有用户,即使部署包的 .env 或 Chart 现在可能带有首个管理员设置,cp-api 也不会创建首个管理员。现有的 Owner 和 Admin 负责邀请新成员,并可以为成员启用登录或重置密码。

默认允许访问私有地址的出站连接​

Playground、预算通知、MCP spec_url 获取以及护栏连接测试,现在默认可以访问私有、内部和回环地址。如需继续拒绝,请开启 SSRF 防护,参见私有网络访问。

使用 helm upgrade --reuse-values 从 Chart 1.5.0 升级的 Helm Release,仍会带着该 Chart 中 api.playgroundAllowPrivateIPs 和 api.notifyAllowPrivateURLs 的默认值 false,但这两个值已不再读取,因此 Playground 和预算通知现在也会访问私有地址。参见从 1.6.x 或更早版本升级。

组织恢复需要全新安装​

向空数据库执行未鉴权导入的方式已移除,向已在使用中的部署导入的方式也已移除。备份文件现在只能恢复到全新安装的控制面,并由其首个管理员在修改初始密码之后执行。脱敏恢复也不再为恢复出的账号设置密码 aisix-repro,aisix-repro-<api_key_id> 也不再能通过鉴权:请改为为账号启用登录,并轮换调用方 API Key。参见组织备份与恢复。

升级部署包安装​

Docker Compose 部署包——在线快速安装包和离线包——升级方式相同:把新版本部署包解压覆盖到现有安装目录上,然后重新运行 run.sh。

请先创建完整的恢复集,其中必须包含 PostgreSQL 备份、匹配的主密钥与密钥来源、部署配置和软件版本。cp-api 首次以新版本启动时会迁移 schema,回滚依赖于恢复这套完整恢复集。

在线安装的升级方式是在包含安装目录的上级目录中重新运行一键脚本——它会拉取当前版本的部署包,解压覆盖到 aisix-self-hosted,然后执行 run.sh:

curl -sL "https://run.api7.ai/aisix-self-hosted/quickstart" | bash

内网隔离环境需要把离线包带进去,而离线包按 CPU 架构分别发布。请在能联网的机器上下载与离线主机匹配的那一个——下面的 URL 指向当前版本,同时还发布有 aisix-self-hosted-offline-<version>-linux-<arch>.tar.gz 形式的指定版本 URL:

curl -fSL "https://run.api7.ai/aisix-self-hosted/aisix-self-hosted-offline-latest-linux-amd64.tar.gz" \
-o aisix-self-hosted-offline-latest-linux-amd64.tar.gz

AArch64 主机请把 amd64 换成 arm64。不带架构后缀的 aisix-self-hosted-offline-latest.tar.gz 仍然继续发布,内容就是 linux/amd64 包。升级时请使用与该主机架构一致的部署包:run.sh 会在加载任何镜像之前拒绝架构不匹配的包,并打印正确的下载 URL。

在包含安装目录的上级目录中解压覆盖,而不是在安装目录内部:

cd /path/that/contains/aisix-self-hosted
tar -xzf aisix-self-hosted-offline-latest-linux-amd64.tar.gz
cd aisix-self-hosted
./run.sh

在 aisix-self-hosted 内部执行 tar 会解压出一个嵌套副本,原安装目录不会有任何变化。

部署包中不含 .env,因此这一步只替换 Compose 文件和脚本,你的密钥和数据卷保持原样。.env 中唯一属于部署包的取值是 AISIX_VERSION,它固定了所有镜像版本——包括控制台在生成 Docker 和 Compose 网关安装命令时使用的网关镜像。run.sh 会把它调整为与部署包一致,并打印所做的操作:

==> Upgrading AISIX Enterprise 1.0.0 -> 1.1.0.
AISIX_VERSION in .env now matches this package; your secrets are untouched.

run.sh 通常会打印上面的升级信息;如果 .env 中原本完全没有 AISIX_VERSION,则会打印 ==> Added AISIX_VERSION=<version> to .env (it had none).。日志中的产品名称前缀可能随部署包版本不同,不能仅凭某条字面日志未出现就判断未升级。请核对 .env 中的 AISIX_VERSION 已与目标部署包一致,并继续检查实际运行的镜像,以及 GET /api/config/public 返回的 cp_version 和 cp_commit。首先确认实际运行的镜像:

COMPOSE_PROJECT_NAME=aisix-self-hosted docker compose images

run.sh 从不改写单个镜像覆盖项 AISIX_API_IMAGE、AISIX_DPM_IMAGE 和 AISIX_CLOUD_DP_IMAGE,它们会继续覆盖 AISIX_VERSION。如果希望某个组件跟随部署包版本,请在升级前移除其覆盖项。参见 AISIX Enterprise 配置。

离线部署包还带有镜像,并在 images/MANIFEST 中列出本包自己的镜像归档。run.sh 只加载其中列出的归档。解压新部署包会把它的归档加入 images/,但不会删除先前版本的归档,因此新版本成功启动后,run.sh 会删除早期部署包的镜像归档,并在一行中列出删除了哪些:

==> Removed image archives of earlier packages from images/: docker.io_api7_aisix_1.5.0.tar.gz ...

如果启动失败,早期归档会保留,因为在离线主机上回滚时要加载的正是它们。只有按 AISIX 部署包镜像归档命名规则命名的文件才会被删除。你自己放在 images/ 中的其他归档会原样保留,但 run.sh 不再加载它们,请自行用 docker load -i 加载。

唯一需要避免的做法,是把新部署包解压到另一个目录。Compose 项目名属于部署包,因此新目录会接管同一个数据卷,而它旁边的 .env 却是全新生成的。此时 run.sh 会停下来而不是启动:只要发现这套栈的容器正运行在另一个目录下,它就会拒绝,与新目录的 .env 内容无关。请回到原目录升级;如果确实要迁移安装位置,请先在原目录执行 ./run.sh down,再把它的 .env 复制过去,然后运行新目录中的脚本。

使用 Helm 升级​

控制面 Chart 和网关 Chart 在每个发布版本中具有相同的 version 和 appVersion。请先升级控制面,在现有网关继续承载流量时验证控制面,再逐个升级网关 Release。

请安装 Helm 3.15 或更新的 Helm 3 版本、cURL 和 jq。安排控制面维护窗口,并为内置数据库或外部数据库创建完整恢复集。继续前,请验证恢复集中的数据库备份可以恢复。

以下命令使用 aisix-cp 作为控制面 Release 名称,aisix 作为命名空间,与安装 AISIX Enterprise一致。如果安装时使用了其他名称或命名空间,请使用相应值。运行 helm list -A 查找每个 Release 及其命名空间:控制面的 CHART 列为 aisix-cp-<version>,网关则为 aisix-<version>。名称或命名空间错误会导致 helm upgrade 失败,并显示 "<name>" has no deployed releases。

设置控制面 Release、命名空间、目标版本和超时:

export CP_NAMESPACE="aisix"
export CP_RELEASE="aisix-cp"
export TARGET_VERSION="<target-version>"
export CP_UPGRADE_TIMEOUT="35m"

该超时超过 Chart 默认的控制面启动预算。如果数据库迁移可能需要更长时间,请增大此值。

更改前,记录已安装控制面 Chart 和应用的版本:

helm list --namespace "$CP_NAMESPACE"
kubectl get pods --namespace "$CP_NAMESPACE"

刷新 Chart 仓库,并确认目标 Chart 可用:

helm repo add api7 https://charts.api7.ai
helm repo update
helm show chart api7/aisix-cp --version "$TARGET_VERSION"

使用自己维护的 values 文件,而非 --reuse-values。后者会将源 Chart 已解析的默认值带入目标版本,可能使新的默认值(包括探针预算)无法生效。

将示例指向为该 Release 维护的 values 文件:

export CP_VALUES_FILE="your-cp-values.yaml"

如果没有持续维护的文件,请使用严格权限,仅导出用户提供的 values:

export CP_VALUES_FILE="cp-values.yaml"

umask 077
touch "$CP_VALUES_FILE"
chmod 600 "$CP_VALUES_FILE"
helm get values "$CP_RELEASE" \
--namespace "$CP_NAMESPACE" \
-o yaml > "$CP_VALUES_FILE"

不要使用 helm get values --all 导出计算后的默认值。沿用源 Chart 的默认值可能使目标 Chart 的默认值无法生效。values 文件可能包含凭据,请将其视为敏感文件。

检查已安装 Release 是否固定了任一控制面镜像:

helm get values "$CP_RELEASE" \
--namespace "$CP_NAMESPACE" \
-o json \
| jq '{api_image_tag: (.api.image.tag // ""), dpm_image_tag: (.dpm.image.tag // ""), generated_gateway_image: (.api.dpImage // "")}'

空标签使用目标 Chart 的应用版本。如果标签固定了旧镜像,请从 values 文件中移除,或更新为目标版本。保留有意使用的自定义镜像仓库,并为自定义构建使用兼容目标版本的标签。

generated_gateway_image 控制控制台生成安装说明时所使用的网关镜像。Docker 和 Compose 说明使用完整值;Helm 说明将其仓库作为 image.repository,标签则由已安装的 api7/aisix Chart 版本决定。空值会跟随控制面版本。请清除或更新旧版本固定项,避免新建 Docker 或 Compose 安装启动旧镜像;只有有意使用兼容目标版本的自定义构建时才保留该值。

根据 Helm Release 标签解析控制面 API 的 Deployment 名称:

export CP_API_DEPLOYMENT="$(kubectl get deployment -n "$CP_NAMESPACE" \
-l "app.kubernetes.io/instance=$CP_RELEASE,app.kubernetes.io/component=api" \
-o jsonpath='{.items[0].metadata.name}')"

printf 'Control-plane API: %s\n' "$CP_API_DEPLOYMENT"

如果该值为空,请停止,并核实 Release 名称、命名空间和 Kubernetes 上下文。

更改 Release 前,请针对实际集群渲染升级结果。--dry-run=server 允许集群查询和 OpenAPI 校验,--hide-secret 则防止 Helm 将渲染出的 Secret 输出到终端或 CI 日志:

helm upgrade "$CP_RELEASE" api7/aisix-cp \
--namespace "$CP_NAMESPACE" \
--version "$TARGET_VERSION" \
--values "$CP_VALUES_FILE" \
--dry-run=server \
--hide-secret

此命令不会将渲染对象提交给 Kubernetes 准入控制。应将其视为渲染和 OpenAPI 检查,而非 SCC、配额或准入策略校验。解决所有报告的错误后再继续。

检查目标控制面渲染结果中的每个镜像:

helm template "$CP_RELEASE" api7/aisix-cp \
--namespace "$CP_NAMESPACE" \
--version "$TARGET_VERSION" \
--values "$CP_VALUES_FILE" \
| grep -E '^[[:space:]]+image:'

aisix-cp-api 和 aisix-cp-dpm 镜像应使用目标版本,或有意设置的、与目标版本兼容的自定义 tag。PostgreSQL 是独立版本化的 Chart 依赖。除非另有经过单独测试的数据库镜像方案要求使用其他 tag,否则请保留目标 Chart 渲染出的 PostgreSQL 镜像 tag。

升级控制面时不要使用 --atomic。新 API 会在启动时迁移数据库,而 Helm 自动回滚只改变 Kubernetes 对象,不会恢复完整恢复集。

helm upgrade "$CP_RELEASE" api7/aisix-cp \
--namespace "$CP_NAMESPACE" \
--version "$TARGET_VERSION" \
--values "$CP_VALUES_FILE" \
--wait \
--timeout "$CP_UPGRADE_TIMEOUT"

观察滚动更新。如果 API Pod 未就绪,请先描述未就绪的 Pod;若容器已启动,再读取日志:

kubectl rollout status -n "$CP_NAMESPACE" \
"deployment/$CP_API_DEPLOYMENT" \
--timeout="$CP_UPGRADE_TIMEOUT"

kubectl get pods -n "$CP_NAMESPACE" \
-l "app.kubernetes.io/instance=$CP_RELEASE,app.kubernetes.io/component=api"

kubectl describe pod -n "$CP_NAMESPACE" <non-ready-cp-api-pod>

kubectl logs -n "$CP_NAMESPACE" \
<non-ready-cp-api-pod> \
--all-containers \
--tail=300

数据库迁移失败、数据库不可达或缺少 Secret 都可能阻止 API 就绪。不要反复执行升级。若迁移无法完成,请按照回滚恢复完整的升级前恢复集。

API 应用数据库迁移期间,数据面管理器可能短暂记录缺少表的错误。它会自动重试。如果 API 就绪后错误仍持续,请进一步排查。

通过公开端点验证控制面版本。将 AISIX_CP 设置为现有 AISIX Cloud Admin API 的基础 URL,包含 /api 且不带结尾斜杠:

export AISIX_CP="YOUR_AISIX_CONTROL_PLANE_API_URL"

curl -fsS "$AISIX_CP/config/public" | jq '{cp_version, cp_commit}'

登录控制台,确认组织、环境、模型、服务提供方密钥和调用方 API Key 均存在。在每个环境的 Data planes 视图中,确认现有网关仍然健康。

控制面验证通过后,按照升级 Kubernetes 上的 AISIX 网关逐个升级受管网关。控制面和网关 Chart 应使用相同的 TARGET_VERSION。对于每个 Release,若其运行在另一集群,请切换 Kubernetes 上下文,并设置对应的 Release 名称和命名空间。该网关流程包含镜像与 values 检查、就绪门禁控制的滚动更新、流量验证和回滚步骤。

请保留完整恢复集,直到控制面与所有网关在变更策略规定的观察期内均运行正常。

将应用设置迁移到 Chart values​

两个 Chart 都把每项应用设置声明为显式的 value,并将其渲染成组件从 ConfigMap 读取的配置文件。密钥保留在 Kubernetes Secret 中,永远不会写入该文件。extraEnvVars 只用于系统级变量,例如 TZ。

如果某个 Chart 的早期版本通过 extraEnvVars 接收应用设置,这些设置在升级后仍然有效,因为环境变量会覆盖配置文件。但它同样会覆盖现在用于配置同一设置的 value,因此请把每项设置迁移到对应的 value,并删除该环境变量:

  • 控制面 Chart。 例如,AISIX_TRUSTED_ORIGINS 改为 api.trustedOrigins,AISIX_CLOUD_SSRF_PROTECTION_ENABLED 改为 api.outbound.ssrfProtection.enabled。完整列表参见 Helm 配置值。
  • 网关 Chart。 AISIX_<SECTION>__<KEY> 变量改为 config 下的同名键,例如 AISIX_OBSERVABILITY__LOG_LEVEL 对应 config.observability.log_level。由 Chart 根据自身 value 设置的键(例如监听器地址和控制面连接)在 config 下会被拒绝。Redis 的 URL、用户名和密码改为通过 configSecrets 或 rateLimit.redis 从 Secret 读取。参见设置其他网关配置。

覆盖 Chart 自身设置的变量(而不只是覆盖配置文件的变量)同样仍然有效,但这只是兼容途径。对于 1.5.0 版 Chart 已渲染的变量名,Chart 会把自己的条目保留在你的条目之前,因此容器中会出现两个同名条目。Helm 4 的 server-side apply 会拒绝重复的变量名,因此新安装要在 values.yaml 中通过对应的 value 或在 config 下设置该值,而不要使用 extraEnvVars。现有的这类覆盖也请迁移到 values。

删除 Chart 仍在渲染的变量名的覆盖需要运行两次 helm upgrade。已部署的 Pod 规格中该变量名出现两次,而新规格中只出现一次,因此第一次 Helm 3 升级会把两个条目都删除,第二次升级才会重新加上 Chart 自己的条目。这一限制从 1.5.0 版 Chart 起就存在。

第一次升级到会渲染配置文件的网关 Chart 时,即使没有修改任何 value,也会把每个网关 Pod 替换一次,因为 Pod 规格发生了变化:网关改为读取渲染出的文件,来自控制面的证书包改为以文件形式挂载。如果某个 release 的 extraEnvVars 设置了 AISIX_MANAGED__CP_CERT_PEM、AISIX_MANAGED__CP_KEY_PEM 或 AISIX_MANAGED__CP_CA_PEM,它会继续以环境变量形式接收证书包。

控制面升级后的索引构建​

一个版本可能会为控制面的大表添加索引,尤其是存放用量记录的 dpmgr_usage_events。cp-api 在数据库迁移完成后立即开始提供服务,之后在后台构建这些索引,因此构建期间控制台和向网关下发配置都可用。在控制面数据库角色上设置的 PostgreSQL statement_timeout 不会中断构建。

构建耗时与用量表的大小成正比。按测试部署的粗略参考,5000 万到 6000 万行的用量表大约需要 15 分钟,实际耗时取决于磁盘、缓存和数据库负载。新安装时表是空的,构建几乎立即完成。

cp-api 会逐个索引记录日志:先是 building index,然后是周期性的 index build progress,最后是 index built。全部完成后记录 background index build: every index is in place。在它们所依赖的索引建好之前,预算支出统计、用量与数据保留清理以及组织删除清理会等待。这期间请求仍会被记录,构建结束后预算支出会一次性补齐。

为 Overview 和 Usage 页面引入小时级用量汇总的升级,还会构建新的用量索引,汇总需要等待该索引完成。在索引建成前,两页面均显示零(包括升级后收到的流量),并提示历史用量正在回填。之后汇总会在后台补入升级前记录的用量;提示消失前,数值仍不完整。参见升级后的历史数据回填。

每个索引的构建都要扫描两遍表并写入预写日志(WAL),因此构建期间数据库的 I/O 和 CPU 负载会明显升高。在一次实测中,重建最大的用量索引约耗时 23 秒,写入约 180 MB 预写日志,PostgreSQL 的 CPU 接近上限,而用量写入和 Usage 页面的延迟没有可测量的变化。即便如此,用量表较大的部署仍建议在业务低峰期升级。

开始下一次升级之前,请等待日志中出现 background index build: every index is in place。如果更新的版本需要修改同一张表,它的迁移会一直等到上一次构建结束才能完成。

部署包安装​

./run.sh 会逐层启动整个栈,并自己等待每一层就绪,因此能说明是哪一步耗时较长。它首先停止新部署包要替换的所有容器,包括上一个版本的 dp-manager,确保新的 cp-api 迁移期间没有任何组件写数据库。然后启动 PostgreSQL 并等待它就绪,再启动 cp-api 并等待它就绪,最后启动 dp-manager 和其余服务。

正常启动不会额外打印任何内容。某一层耗时超过约 10 秒后,run.sh 每 30 秒打印一行:

  • cp-api is still migrating the database (…)。迁移耗时较长时,可能附带 It is waiting for a table lock another database session holds,./run.sh logs api 会给出该会话。
  • cp-api is still starting (…):迁移已完成,但升级后的首次启动仍在启动其余部分。
  • PostgreSQL is recovering from an unclean shutdown (…)。参见中断停止后的 PostgreSQL 恢复。

请让它继续运行。按 Ctrl-C 不会停止迁移,迁移会在容器内继续进行,但 dp-manager 只由 run.sh 启动,因此迁移完成后请再运行一次 ./run.sh。之后如需跟踪后台索引构建,请运行 ./run.sh logs api。

被其他会话持有的表锁​

每个迁移步骤最多等待 5 秒获取表锁,然后重试,而不是让该表上的所有读写排在一个长时间运行的事务之后。重试期间,cp-api 会记录 database migration is waiting for a table lock held by another session; retrying,并附上阻塞会话的进程 ID、应用名称、状态、事务开始时间和查询。常见原因是长时间运行的事务,或仍在运行上一个版本的控制面副本。结束该会话或等待它完成后,迁移会继续。

中断停止后的 PostgreSQL 恢复​

./run.sh stop 和 ./run.sh down 会给每个容器最多 2 分钟关闭,因为在大量写入之后,PostgreSQL 关闭时的检查点可能超过 Docker Compose 默认的 10 秒。用上一个部署包的 run.sh 执行的停止仍然只有 10 秒。

如果 PostgreSQL 的关闭被中断,下次启动时它会先重放日志,之后才接受连接;对于近期写入很多的数据库,这可能需要几分钟。数据不会丢失。run.sh 最多等待 30 分钟,恢复期间会打印 PostgreSQL is recovering from an unclean shutdown。如果恢复超过了这个等待时间,run.sh 会指出启动失败是由恢复导致的:请等待 ./run.sh logs postgres 显示 database system is ready to accept connections,然后再运行一次 ./run.sh。

窗口期内控制面会做哪些检查​

在网关尚未升级期间,控制面会依据其内置的已发布兼容性契约,检查你保存后将投射给近期有上报且已注册网关的每一份配置。

如果其中一台网关无法加载某份配置,保存请求会以 HTTP 422 失败,错误码为 DP_INCOMPATIBLE。响应中会指出网关版本、受影响的网关、字段路径以及 schema 给出的原因。此时不会写入任何内容,资源会保留之前的配置。这项检查由具体配置项触发,而不是由版本差异本身触发。请升级受影响的网关,或者在它们升级完成前先不要使用该配置项。

网关刚升级完成时,重启后的网关此前的注册记录最长还会被计入 5 分钟。如果在这段时间内保存被拒绝,而它指出的版本你已经升级过了,通常就是这条过期注册记录导致的;稍等片刻重试即可。

低于升级下限的网关完全不做检查。没有受支持的契约可供比对,因此保存会成功,响应中携带一条 below_floor 警告,给出受影响的网关数量、它们上报的版本,以及升级下限。请如实理解这条警告:这些网关已不在支持范围内,控制面无法告诉你它们能否加载你刚刚保存的内容。请把它们升级到 0.12.0 或更高版本。

如果网关上报的版本无法映射到控制面内置的兼容性契约,控制面也会跳过该网关。这包括自定义或本地构建,以及比控制面已知契约更新的网关版本。请直接验证这些网关,不要把未出现保存时警告当作兼容性证明。

升级下限闸门​

从低于下限的版本升级,会被直接拒绝而不是尝试执行,因为一个迁移到一半的数据库,比多做一步升级难恢复得多。

当数据库上一次由低于下限的版本运行时,cp-api 拒绝启动。错误信息会给出数据库中记录的版本、本版本能够升级的最低来源版本,以及覆盖开关。这项检查在任何迁移动作之前执行,因此被拒绝的启动不会改动数据库,它保持上一个版本留下的样子。正确做法是先升级到一个受支持的版本。

这项检查读取的是控制面从本版本起才写入的版本记录,因此它只能判断已经被带有该记录的版本运行过的数据库。被更早版本运行过的数据库没有这条记录,无从判断,因此不会被拒绝——在这一次升级中,只有部署包安装的 .env 检查能拦住你,而 Helm 安装完全没有闸门。请自行确认你是从哪个版本升上来的。

离线包和在线包在 run.sh 中拒绝同样的升级,并且发生在任何容器启动之前,同时给出两步做法:取一个介于 0.12.0 与目标版本之间的部署包,解压覆盖到安装目录并运行,等它完成迁移,然后再解压目标部署包并再次运行。

若仍要继续,请设置 AISIX_ALLOW_UNSUPPORTED_UPGRADE=1,值必须恰好为 1。请先创建完整恢复集——这会运行尚未针对如此旧版本验证过的迁移路径,恢复该恢复集是唯一的退路。

部署包安装在命令上设置:

AISIX_ALLOW_UNSUPPORTED_UPGRADE=1 ./run.sh

Helm 安装设置 api.allowUnsupportedUpgrade:

values.yaml
api:
allowUnsupportedUpgrade: true

把它加进你升级时使用的 values 文件,这样它才会真正生效:

helm upgrade aisix-cp api7/aisix-cp \
--namespace "$CP_NAMESPACE" \
-f your-cp-values.yaml

cp-api 和部署包的 run.sh 都读取这个环境变量,因此两条部署包升级路径使用同一个名字,而 Chart value 设置的是 cp-api 的同一项配置。升级完成后请把这个覆盖开关移除,以免后续某次不受支持的升级被静默放行。

回滚​

回滚按相反顺序进行:先网关,后控制面。

控制面回滚需要恢复完整的升级前恢复集,而非仅恢复镜像。新版本已经迁移 schema,在其上启动旧版本会让旧代码操作不认识的数据库。请一起恢复数据库、匹配的密钥与主密钥、部署配置,以及之前的软件版本。

对于部署包安装,当目录中的部署包版本低于 .env 记录的版本时,run.sh 会拒绝启动,因为这通常是误操作,例如重新下载了旧包,或将 latest URL 的内容下载到了更新的安装上。若确实需要回滚,请在恢复完整恢复集后明确确认:

AISIX_ALLOW_DOWNGRADE=1 ./run.sh

run.sh 结束时会打印部署的版本号。请核对这一行是否是你要回滚到的版本。

对于 Helm 安装,helm rollback 会将工作负载恢复到上一修订;请先恢复完整恢复集。

AISIX Enterprise 不支持的情况​

  • 从低于最低支持版本的版本一步升级。 请先升级到 0.12.0 与目标版本之间的某个版本,待其完成迁移后再升级。
  • 新增低于环境现有配置要求的旧网关。 混合版本窗口适用于正在向前升级的网关。不支持将旧网关接入已保存配置依赖更高版本的环境,该网关无法加载收到的配置。
  • 使用低于 0.12.0 的网关连接当前控制面。 此类网关超出支持范围,控制面无法保证它能加载哪些配置。
  • 先升级网关,再升级 AISIX Enterprise 控制面。 请先升级控制面,再升级其连接的网关。