跳到主要内容
版本:Dev

在 OpenShift 或 OKD 上升级 AISIX Enterprise

AISIX Enterprise 分两个阶段升级:先升级由客户运维的控制面,再升级每一个已连接的 AISIX 网关。验证新控制面期间,现有网关继续处理流量,但只有网关集群也全部运行目标版本,产品升级才算完成。

本流程在升级期间保留 OpenShift 或 OKD PostgreSQL 安全上下文覆盖配置、Route 主机名和项目分配的身份,并假设控制面和网关均通过 Helm 安装。

对于通过安装包部署在宿主机上的控制面,请遵循升级使用安装包部署的控制面。该流程先升级宿主机控制面,再升级由它管理、通过 Helm 安装的 OpenShift 或 OKD 网关。

前提条件​

更改任一发布前:

  • 安装 Helm 3.15 或更高版本的 Helm 3、cURL 和 jq。
  • 配置 oc,使其能够在所有包含 AISIX 组件的项目中管理工作负载、Service、Secret 和 Route,读取 Pod 日志并运行 oc exec。
  • 如果 Route 证书尚未受信任,请取得入口 CA 证书。下方命令需要读取 openshift-config-managed 中 default-ingress-cert ConfigMap 的权限;也可以由集群管理员提供 CA 文件。
  • 阅读已安装版本之后每个版本的发布说明,按顺序应用必需的升级说明。
  • 创建并测试完整的控制面恢复集。
  • 确认网关负载均衡器会移除 /readyz 检查失败的 Pod。
  • 对于多副本网关,如果限制或缓存条目需要在副本间保持一致,请确认已配置共享 Redis。

完成特定版本准备​

创建并测试恢复集后,在运行 Helm 前完成所有适用的版本特定操作:

  1. 根据AISIX Enterprise 支持的升级路径确认源版本和目标版本,再从已安装版本的下一个版本开始,按从旧到新的顺序阅读发布说明。
  2. 从 1.0 之前的版本升级时,必须在新控制面启动前完成升级到 1.0.0 时审查现有安全护栏。
  3. 从 1.5 或更早版本升级时,请阅读登录、访问和控制台变更。完成启动前操作,识别每个组织及其用户,并决定保留哪个组织。在目标控制面启动并提供组织合并流程前,不要合并组织。

执行任何破坏性更改前,先完成恢复集。即使目标控制面不再读取旧版本的控制台身份验证密钥,在仍可能回滚期间也要保留它。

示例使用在 OpenShift 或 OKD 上部署 AISIX Enterprise中的默认发布名称和项目。请替换为实际部署使用的值:

export CP_NAMESPACE="aisix"
export CP_RELEASE="aisix-cp"
export GATEWAY_NAMESPACE="aisix-dp"
export GATEWAY_RELEASE="aisix-dp"
export TARGET_VERSION="<target-version>"
export CP_UPGRADE_TIMEOUT="35m"
export GATEWAY_UPGRADE_TIMEOUT="60m"

35 分钟的控制面超时超过默认启动探针预算。60 分钟的网关超时,是为默认两个副本、每个 Pod 最长 1,230 秒的终止时间和五分钟启动探针预算预留的保守起始值。修改副本数、更新策略、终止宽限期、探针或预计镜像拉取与调度时间时,请重新计算。确认集群能够调度滚动更新所增加的 Pod;延长超时无法解决配额或容量拒绝。

信任 Route 证书​

默认应用域名通常使用由集群内部入口 CA 签发的通配符证书。如果工作站尚未信任此 CA,请导出它,供控制面和网关的 curl 检查使用:

oc get configmap default-ingress-cert -n openshift-config-managed \
-o jsonpath='{.data.ca-bundle\.crt}' > ingress-ca.crt
export CURL_CA_BUNDLE="$PWD/ingress-ca.crt"

如果 CA 文件由管理员提供,请将其保存为 ingress-ca.crt,并只运行 CURL_CA_BUNDLE 导出命令。如果 Route 或默认 Ingress Controller 使用工作站已信任的证书,则跳过此导出步骤。

记录当前部署​

更改前,记录发布、Pod 和 Route:

helm list -n "$CP_NAMESPACE"
helm list -n "$GATEWAY_NAMESPACE"
oc get pods,routes -n "$CP_NAMESPACE"
oc get pods,routes -n "$GATEWAY_NAMESPACE"

仅保存用户提供的 Helm values。文件可能包含凭据,因此应使用严格权限创建:

umask 077
touch cp-values.yaml gateway-values.yaml
chmod 600 cp-values.yaml gateway-values.yaml

helm get values "$CP_RELEASE" -n "$CP_NAMESPACE" -o yaml > cp-values.yaml
helm get values "$GATEWAY_RELEASE" -n "$GATEWAY_NAMESPACE" -o yaml > gateway-values.yaml

不要使用 helm get values --all 或 --reuse-values。沿用源 Chart 计算出的默认值可能使新的默认值无法生效。

如果控制面使用随附的 PostgreSQL,请确认 cp-values.yaml 保留以下两项 SCC 覆盖配置:

cp-values.yaml
postgresql:
primary:
podSecurityContext:
enabled: false
containerSecurityContext:
enabled: false

同时保留 api.publicBaseURL 和 api.dpmgrBaseURL,使公开链接、Route 和数据面管理器证书继续使用现有主机名。移除未由项目分配的固定 runAsUser、runAsGroup 或 fsGroup 值。

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

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

升级控制面​

确定控制面 API Deployment 名称:

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

如果值为空,请勿继续。修改发布前,先针对运行中的集群渲染升级:

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

服务端试运行会检查渲染、集群查询和 OpenAPI 验证,但不会将对象提交给 SCC、配额或其他准入检查。

继续之前,检查目标镜像:

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

控制面 API 和数据面管理器镜像应使用目标版本,或有意设置的、与目标版本兼容的自定义标签。PostgreSQL 独立管理版本;除非已有单独测试的数据库镜像方案,否则请保留目标 Chart 渲染的镜像。

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

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

观察 API 滚动更新,并在重试失败的迁移前记录诊断信息:

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

oc get pods -n "$CP_NAMESPACE"

验证控制面​

确认控制面 Route 仍然指向相同的 API 和数据面管理器 Service:

oc get routes -n "$CP_NAMESPACE"

检查每个控制面 Pod 准入时采用的 SCC 和运行时 UID:

oc get pods -n "$CP_NAMESPACE" \
-o custom-columns='NAME:.metadata.name,SCC:.metadata.annotations.openshift\.io/scc,READY:.status.containerStatuses[*].ready'

for pod in $(oc get pods -n "$CP_NAMESPACE" -o name); do
printf '%s UID=' "$pod"
oc exec -n "$CP_NAMESPACE" "$pod" -- id -u
done

AISIX 和随附 PostgreSQL Pod 应显示 restricted-v2,且容器已就绪。每个运行中的进程都应使用项目范围内的 UID。

将 AISIX_CP 设置为包含 /api 的公开 API 基础 URL,并验证报告的版本:

export AISIX_CP="https://<control-plane-route-host>/api"
curl -fsS "$AISIX_CP/config/public" | jq '{cp_version, cp_commit}'

如果源部署有多个组织,请先登录并完成将多个组织合并为一个,再正常使用控制台。此操作会永久删除未保留的组织,因此提交前请确认选中的组织和恢复集。

确认保留的组织、环境、模型、模型服务提供方密钥和调用方 API Key 仍然存在。现有网关仍运行旧版本时应保持健康。

在控制面通过这些检查之前,不要开始网关滚动更新。

升级网关集群​

确定网关 Deployment 名称:

export GATEWAY_DEPLOYMENT="$(oc get deployment -n "$GATEWAY_NAMESPACE" \
-l "app.kubernetes.io/instance=$GATEWAY_RELEASE,app.kubernetes.io/component=gateway" \
-o jsonpath='{.items[0].metadata.name}')"

如果 Deployment 名称为空,请勿继续。检查 gateway-values.yaml 是否固定到旧镜像标签,并在渲染目标前移除或更新该固定值。保留有意设置的自定义镜像仓库,并使用与目标版本兼容的标签。

渲染目标 Deployment,并获取 Helm 将应用的准确网关镜像:

export TARGET_GATEWAY_IMAGE="$(
helm template "$GATEWAY_RELEASE" api7/aisix \
--namespace "$GATEWAY_NAMESPACE" \
--version "$TARGET_VERSION" \
--values gateway-values.yaml \
--show-only templates/deployment.yaml \
| awk '
$1 == "-" && $2 == "name:" && $3 == "aisix" { in_gateway = 1; next }
in_gateway && $1 == "image:" { gsub(/"/, "", $2); print $2; exit }
'
)"

printf 'Target gateway image: %s\n' "$TARGET_GATEWAY_IMAGE"

如果目标镜像为空,或无法标识预期版本或与目标兼容的自定义构建,请停止。

执行服务端试运行:

helm upgrade "$GATEWAY_RELEASE" api7/aisix \
--namespace "$GATEWAY_NAMESPACE" \
--version "$TARGET_VERSION" \
--values gateway-values.yaml \
--dry-run=server \
--hide-secret

运行 Helm 前,打开第二个终端。选择相同的集群上下文,并使用原终端中的值导出 GATEWAY_NAMESPACE 和 GATEWAY_RELEASE;终端之间不共享 Shell 变量。其他诊断终端也需要重复此设置。在 Helm 仍在等待时,观察网关 Pod,并记录失败目标 Pod 的描述和日志;原子回滚可能在命令返回前移除该 Pod:

export GATEWAY_NAMESPACE="aisix-dp"
export GATEWAY_RELEASE="aisix-dp"

oc get pods -n "$GATEWAY_NAMESPACE" \
-l "app.kubernetes.io/instance=$GATEWAY_RELEASE,app.kubernetes.io/component=gateway" \
--watch

在原终端中运行升级:

helm upgrade "$GATEWAY_RELEASE" api7/aisix \
--namespace "$GATEWAY_NAMESPACE" \
--version "$TARGET_VERSION" \
--values gateway-values.yaml \
--atomic \
--timeout "$GATEWAY_UPGRADE_TIMEOUT"

如果 Helm 成功,请确认目标滚动更新已完成:

oc rollout status -n "$GATEWAY_NAMESPACE" \
"deployment/$GATEWAY_DEPLOYMENT" \
--timeout="$GATEWAY_UPGRADE_TIMEOUT"

--atomic 会阻塞,直到目标发布就绪或 Helm 完成回滚。如果返回非零状态,之后成功的滚动更新状态可能描述的是已恢复的修订。请使用 helm history "$GATEWAY_RELEASE" -n "$GATEWAY_NAMESPACE" 和 Helm 等待期间收集的诊断信息。

请保持 readinessProbe.enabled 为 true;如果滚动更新必须避免流量中断,不要使用 Recreate 策略。单副本部署在唯一 Pod 被替换期间仍可能中断。

对连接到 AISIX Enterprise 控制面的每个网关发布和集群重复此流程。

验证完整产品升级​

对每个网关,确认其 Route 仍指向相同 Service,且 Pod 保留预期 SCC 和项目分配的 UID:

oc get routes -n "$GATEWAY_NAMESPACE"

export GATEWAY_POD="$(oc get pod -n "$GATEWAY_NAMESPACE" \
-l "app.kubernetes.io/instance=$GATEWAY_RELEASE,app.kubernetes.io/component=gateway" \
-o json | jq -er --arg image "$TARGET_GATEWAY_IMAGE" '
[.items[]
| select(.metadata.deletionTimestamp == null)
| select(any(.status.conditions[]?; .type == "Ready" and .status == "True"))
| select(any(.spec.containers[]; .name == "aisix" and .image == $image))
][0].metadata.name // empty
')"

此查询选择运行渲染所得目标镜像的 Ready Pod,并排除仍在排空流量的旧 Pod。如果没有返回 Pod,请停止,然后检查目标 Pod 的 SCC 和运行时 UID:

oc get pod -n "$GATEWAY_NAMESPACE" "$GATEWAY_POD" \
-o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'
oc exec -n "$GATEWAY_NAMESPACE" "$GATEWAY_POD" -- id -u

第一行应显示 restricted-v2,第二行应显示运行中进程使用的 UID。请确认该 UID 位于网关项目分配的范围内。

在控制台中确认每个网关都报告目标版本、健康状态和最新心跳。通过每个网关组发送有代表性的、经过身份验证的推理流量,并检查访问日志、指标、上游行为和部署所需的配置功能。

确认每个网关的控制面地址仍与数据面管理器证书主机名匹配。如果此端点使用 passthrough Route,请保留其现有主机名和目标 Service。即使端点仍可访问,主机名不匹配也会破坏双向 TLS 连接。

在控制面和每个网关按变更策略规定的观察期正常运行之前,保留恢复集和导出的 values。

升级使用安装包部署的控制面​

使用安装包部署的控制面可以管理 OpenShift 或 OKD 上的网关。请按以下顺序操作,而不是执行上方控制面 Helm 命令:

  1. 完成前提条件和特定版本准备,包括恢复集与受支持升级路径检查。
  2. 升级安装包部署,然后验证控制面。
  3. 如果网关 Route 证书尚未受信任,请先信任该证书。
  4. 对每个通过 Helm 管理的网关,使用 oc 按照在 Kubernetes 上升级网关操作。对于此拓扑,该流程会在滚动更新前设置网关变量、渲染目标镜像并保存 values。
  5. 返回验证完整产品升级,完成 Route、SCC、运行时 UID、控制台和流量检查。

回滚​

按与升级相反的顺序回滚:先网关,再控制面。

对于网关,请确定之前的 Helm 修订并恢复:

helm history "$GATEWAY_RELEASE" -n "$GATEWAY_NAMESPACE"

helm rollback "$GATEWAY_RELEASE" <previous-revision> \
--namespace "$GATEWAY_NAMESPACE" \
--wait \
--timeout "$GATEWAY_UPGRADE_TIMEOUT"

控制面回滚必须恢复完整的升级前恢复集,而不只是恢复之前的 Kubernetes 对象。必须一起恢复数据库、匹配的密钥与主密钥、部署配置和旧软件版本。完整恢复要求见回滚。

OKD Web 控制台升级错误​

此问题仅在 OKD Web 控制台中验证过。最初通过 Helm CLI 安装的控制面发布,在其中升级时可能出现以下错误:

found in Chart.yaml, but missing in charts/ directory: postgresql

请继续使用本页中的 Helm CLI 流程。发布的 Chart 已包含 PostgreSQL 依赖,无需单独下载依赖或重新构建 Chart。

排查 SCC 准入问题​

找到 FailedCreate 事件,然后描述事件所指的 ReplicaSet 或 StatefulSet:

export FAILED_NAMESPACE="<project-containing-rejected-workload>"

oc get events -n "$FAILED_NAMESPACE" --sort-by=.lastTimestamp
oc describe -n "$FAILED_NAMESPACE" <controller-kind>/<controller-name>

对于 AISIX 应用 Pod,请移除未由项目分配的固定 runAsUser、runAsGroup 和 fsGroup 值。对于随附 PostgreSQL,请保留安装时对依赖 Chart 安全上下文的禁用配置。不要通过授予 anyuid 来绕过问题。

排查容器启动失败​

描述失败的 Pod;如果容器已启动,请读取其当前日志:

oc describe pod -n <namespace> <pod>
oc logs -n <namespace> <pod> --all-containers --tail=300

如果容器发生重启,请在 Pod 描述中确定其名称,再读取其前一次日志:

oc logs -n <namespace> <pod> -c <restarted-container> --previous --tail=300

如果 CRI-O 对自定义网关镜像报告 exec: Operation not permitted,请确认网关容器保留了 NET_BIND_SERVICE。其他能力应继续全部丢弃。