在 OpenShift 或 OKD 上部署 AISIX Enterprise
AISIX Enterprise 包括客户自行运维的控制面,以及为应用流量提供服务的 AISIX 网关。因此,完整的 OpenShift 或 OKD 部署应先启动控制面,暴露其管理端点和数据面管理器端点,再部署至少一个已连接的网关。
AISIX 应用工作负载在默认的 restricted-v2 安全上下文约束(SCC)下运行。随附的 PostgreSQL 依赖固定了自己的用户和组 ID,因此必须在首次 Helm 安装前禁用它的 Pod 和容器安全上下文。生产环境应使用外部高可用 PostgreSQL 数据库,而不是随附的单实例数据库。
前提条件
- 已有 OpenShift 或 OKD 4.11 或更高版本的集群。
oc会话能够在目标项目中管理工作负载、Service、Secret 和 Route,读取 Pod 日志并运行oc exec。- 已获得应用域名和入口 CA 证书,或拥有读取集群 Ingress 配置和
openshift-config-managed中default-ingress-certConfigMap 的权限。集群管理员也可以直接提供域名和 CA,而无需授予这些权限。 - Helm 3、OpenSSL、cURL 和
jq。 - 部署 AISIX Enterprise 控制面中所述的计算、存储、数据库和网络容量。
本流程使用 aisix 作为控制面项目,使用 aisix-dp 作为网关项目。分离项目可使每个项目拥有独立的 UID 范围和访问策略。如果使用其他名称,请在所有命令中一致替换。
准备项目与 Route 主机名
选择或创建控制面项目和网关项目:
oc get project aisix >/dev/null 2>&1 || oc new-project aisix
oc get project aisix-dp >/dev/null 2>&1 || oc new-project aisix-dp
安装控制面前,先选择供外部客户端访问的主机名。示例使用集群的通配符应用域名。如果该域名由集群管理员提供,请将 ROUTE_DOMAIN 设置为此域名,并省略下方第一条导出命令:
export ROUTE_DOMAIN="$(oc get ingresses.config.openshift.io cluster \
-o jsonpath='{.spec.domain}')"
export CP_ROUTE_HOST="aisix.$ROUTE_DOMAIN"
export DPM_ROUTE_HOST="aisix-dpm.$ROUTE_DOMAIN"
export GATEWAY_ROUTE_HOST="aisix-gateway.$ROUTE_DOMAIN"
如果使用组织管理的 DNS,请将这些变量设为对应主机名,并确保它们解析到路由器。对于边缘 Route,请提供匹配的证书和私钥,或配置 Ingress Controller 的默认证书。数据面管理器 TLS 证书中的主机名由 api.dpmgrBaseURL 初始化。
信任 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 导出命令。登录前,将 ingress-ca.crt 导入浏览器或操作系统信任存储。如果 Route 或默认 Ingress Controller 使用工作站已信任的证书,则跳过这些步骤。
部署控制面
阅读部署 AISIX Enterprise 控制面中的生产要求,但不要执行其中的通用 Kubernetes Helm 命令。将必需的 PostgreSQL SCC 覆盖配置保存为 values.yaml:
postgresql:
primary:
podSecurityContext:
enabled: false
containerSecurityContext:
enabled: false
使用对外可访问的 Route URL 和生成的密钥安装控制面:
helm repo add api7 https://charts.api7.ai
helm repo update
helm install aisix-cp api7/aisix-cp \
--namespace aisix \
--values values.yaml \
--set-string api.publicBaseURL="https://$CP_ROUTE_HOST" \
--set-string api.dpmgrBaseURL="https://$DPM_ROUTE_HOST" \
--set-string secrets.masterKey="$(openssl rand -base64 32)" \
--set-string postgresql.auth.password="$(openssl rand -hex 24)" \
--set-string postgresql.auth.postgresPassword="$(openssl rand -hex 24)"
不要禁用 postgresql.shmVolume。否则,PostgreSQL 会退回使用容器运行时提供的 64 MB /dev/shm,并行查询可能因 could not resize shared memory segment 而失败。
控制面 API 和数据面管理器不固定用户或组 ID,因此 restricted-v2 可以从项目范围内分配 ID。它们的容器使用只读根文件系统、禁用权限提升并丢弃所有能力。网关遵循相同策略,但保留 NET_BIND_SERVICE。应用运行时可写路径使用 emptyDir 卷。
不要向 AISIX ServiceAccount 授予 anyuid SCC。如果集群管理员分配了固定 ID,请在 api.podSecurityContext 和 dpm.podSecurityContext 下都设置 runAsUser、runAsGroup 和 fsGroup。除非镜像使用的 UID 和组 ID 10001、101 属于项目允许的范围,否则不要复用它们。
如果组织策略使用比 restricted-v2 更严格的 SCC,请由集群管理员审查渲染后的清单,并明确分配所需的 ID 或能力。
暴露并验证控制面
通过边缘 Route 暴露控制面 API 和控制台:
oc create route edge aisix-cp \
--service=aisix-cp-api \
--port=http \
--hostname="$CP_ROUTE_HOST" \
--namespace aisix
数据面管理器与已连接网关之间使用双向 TLS。通过 TLS passthrough 暴露它,避免路由器终止连接:
oc create route passthrough aisix-cp-dpm \
--service=aisix-cp-dpm \
--port=tls \
--hostname="$DPM_ROUTE_HOST" \
--namespace aisix
这些命令使用默认的 aisix-cp-api/http 和 aisix-cp-dpm/tls Service 目标。如果发布使用了名称覆盖,请运行 oc get service -n aisix,并替换为实际的 Service 名称和命名端口。
等 待工作负载就绪,并检查其 SCC 和分配的 UID:
oc get pods -n aisix --watch
# 所有 Pod 就绪后停止观察,再检查准入后的安全上下文。
oc get pods -n aisix \
-o custom-columns='NAME:.metadata.name,SCC:.metadata.annotations.openshift\.io/scc,READY:.status.containerStatuses[*].ready'
for pod in $(oc get pods -n aisix -o name); do
printf '%s UID=' "$pod"
oc exec -n aisix "$pod" -- id -u
done
AISIX 和随附 PostgreSQL Pod 应显示 restricted-v2,且容器已就绪。每个运行中的进程都应使用 aisix 项目范围内的 UID。
确认数据面管理器证书包含其 passthrough Route 主机名:
openssl s_client \
-connect "$DPM_ROUTE_HOST:443" \
-servername "$DPM_ROUTE_HOST" \
</dev/null 2>/dev/null |
openssl x509 -noout -ext subjectAltName
登录并配置网关资源
打开 https://$CP_ROUTE_HOST。Helm 安装说明会输出读取引导管理员密码的命令。使用配置的引导邮箱和该密码登录,并按提示替换密码。
在 Admin tokens 中创建具有 write 范围的组织级管理 Token,然后导出控制面 API URL 和 Token:
export AISIX_CP="https://$CP_ROUTE_HOST/api"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
创建环境、OpenAI 模型服务提供方密钥、gpt-4o-mini 模型和调用方 API Key。请保存调用方密钥的明文值,因为它只返回一次:
ENV_RESPONSE=$(curl -fsS -X POST "$AISIX_CP/environments" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"display_name": "prod"}')
export ENV_ID=$(echo "$ENV_RESPONSE" | jq -er '.environment.id')
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
PROVIDER_KEY_RESPONSE=$(curl -fsS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"provider": "openai",
"display_name": "OpenAI",
"api_key": "'"${OPENAI_API_KEY}"'",
"api_base": "https://api.openai.com/v1",
"allowed_environments": ["'"${ENV_ID}"'"]
}')
export PROVIDER_KEY_ID=$(echo "$PROVIDER_KEY_RESPONSE" | jq -er '.provider_key.id')
MODEL_RESPONSE=$(curl -fsS -X POST "$AISIX_CP/environments/$ENV_ID/models" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "gpt-4o-mini",
"model_name": "gpt-4o-mini",
"provider_key_id": "'"${PROVIDER_KEY_ID}"'"
}')
export MODEL_ID=$(echo "$MODEL_RESPONSE" | jq -er '.model.id')
API_KEY_RESPONSE=$(curl -fsS -X POST "$AISIX_CP/environments/$ENV_ID/api_keys" \
-H "Authorization: Bearer ${AISIX_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"display_name": "openshift-caller",
"allowed_models": ["'"${MODEL_ID}"'"]
}')
export AISIX_API_KEY=$(echo "$API_KEY_RESPONSE" | jq -er '.plaintext')
如果有请求失败,请停止并修正后再继续。缺少资源 ID 会导致后续请求失败。
签发网关证书
打开 prod 环境的 Data planes 视图,签发网关证书,并下载 cert.pem、key.pem 和 ca.pem。私钥只显示一次。
部署网关
将证书包存入网关项目:
oc -n aisix-dp create secret generic aisix-gateway-certificate \
--from-file=cert.pem=./cert.pem \
--from-file=key.pem=./key.pem \
--from-file=ca.pem=./ca.pem
连接数据面管理器 Route,安装一个网关副本。在环境的 Kubernetes (Helm) 说明中确认端点,并按需替换:
helm install aisix-dp api7/aisix --namespace aisix-dp \
--set image.repository=ghcr.io/api7/aisix \
--set image.tag=dev \
--set controlPlane.baseURL="https://$DPM_ROUTE_HOST:443" \
--set controlPlane.certificate.existingSecret=aisix-gateway-certificate \
--set replicaCount=1
网关 Chart 无需自定义 SCC 或更改 ServiceAccount 即可支持 restricted-v2。如果网关需要项目分配的固定 ID,请将 podSecurityContext.runAsUser、podSecurityContext.runAsGroup 和 podSecurityContext.fsGroup 设为这些值。
如果限制或缓存条目需要在副本间保持一致,请在增加副本数之前配置共享 Redis。
暴露并验证网关
为 默认的纯 HTTP proxy Service 端口创建边缘 Route:
oc create route edge aisix-dp \
--service=aisix-dp \
--port=proxy \
--hostname="$GATEWAY_ROUTE_HOST" \
--namespace aisix-dp
此命令使用默认的网关发布名称和 proxy Service 端口。如果发布使用了名称覆盖或自定义监听器,请运行 oc get service -n aisix-dp,并替换为实际的 Service 名称和命名端口。
等待网关就绪,然后验证其 SCC 和 UID:
oc rollout status deployment/aisix-dp -n aisix-dp --timeout=5m
export GATEWAY_POD="$(oc get pod -n aisix-dp \
-l 'app.kubernetes.io/instance=aisix-dp,app.kubernetes.io/component=gateway' \
-o jsonpath='{.items[0].metadata.name}')"
oc get pod -n aisix-dp "$GATEWAY_POD" \
-o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'
oc exec -n aisix-dp "$GATEWAY_POD" -- id -u
第一行应显示 restricted-v2,第二行应显示运行中进程使用的 UID。请确认该 UID 位于 aisix-dp 项目范围内,且控制台显示网关健康、心跳为最新状态。
最后,检查 Route,并通过它发送有代表性的、经过身份验证的推理请求:
export AISIX_PROXY="https://$GATEWAY_ROUTE_HOST"
curl -fsS "$AISIX_PROXY/readyz"
curl -fsS "$AISIX_PROXY/v1/models" \
-H "Authorization: Bearer ${AISIX_API_KEY}"
curl -sS -X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Say hello from AISIX Enterprise."}
]
}'
就绪检查请求应返回 ok,模型列表应包含 gpt-4o-mini,推理响应应包含助手消息。将生产流量导向网关前,请在控制台日志和用量视图中验证该请求。