跳到主要内容
版本:3.10.x

在 OpenShift 上部署

本指南介绍如何在 Red Hat OpenShift 集群上部署 API7 网关。部署采用与标准 Kubernetes 部署相同的 Helm 模型,同时说明安全上下文约束(SCC)和服务账号配置等 OpenShift 特有事项。

架构概览

API7 网关在 OpenShift 上使用与其他 Kubernetes 集群相同的双组件架构:

  • 控制面(CP):Dashboard、DP Manager 和 PostgreSQL 数据库。
  • 数据面(DP):处理 API 流量的 API7 网关实例。

OpenShift 的主要区别是 Pod 必须符合安全上下文约束(SCC),它限制 Pod 可以执行的操作。

前提条件

开始前,请确保具备:

  • 运行 4.12 或更高版本且拥有 cluster-admin 权限的 OpenShift 集群。
  • OpenShift CLI(oc4.12 或更高版本。请参阅安装 oc
  • Helm 3.10 或更高版本。请参阅安装 Helm
  • API7 网关许可证。请参阅获取试用许可证

登录 OpenShift 集群

使用 oc CLI 登录。可以在 OpenShift Web 控制台的用户菜单中找到登录命令:

oc login \
--token=sha256~YOUR_TOKEN \
--server=https://api.YOUR_CLUSTER.openshiftapps.com:6443

验证是否拥有 cluster-admin 权限:

oc auth can-i create scc --all-namespaces

第 1 步:创建项目

为 API7 创建专用 OpenShift 项目(命名空间):

oc new-project api7

也可以通过 OpenShift Web 控制台创建项目。

第 2 步:安装控制面

添加 API7 Helm 仓库

helm repo add api7 https://charts.api7.ai
helm repo update

配置内置组件的安全上下文

内置 PostgreSQL、Prometheus 和 Jaeger Pod 带有明确的 securityContext 设置,与 OpenShift SCC 系统冲突。PostgreSQL 和 Prometheus 需要可写文件系统,Jaeger 则使用固定 UID。在 OpenShift 上应清除这些设置,使 SCC 系统可以从项目允许的范围中分配 UID:

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

prometheus:
server:
podSecurityContext:
enabled: false
containerSecurityContext:
enabled: false

jaeger:
jaeger:
podSecurityContext:
runAsUser: null
runAsGroup: null
fsGroup: null
备注

从 API7 网关 3.9.5 开始,Jaeger 成为支持分布式追踪的内置控制面组件。与 PostgreSQL 和 Prometheus 不同,内置 Jaeger Chart 的安全上下文没有 enabled 开关,并将 runAsUserrunAsGroupfsGroup 设置为 10001,会被 OpenShift SCC 拒绝。由于 Helm 会合并配置值,podSecurityContext: {} 无法清除这些键,必须逐一设置为 null。Jaeger 使用内存存储,因此不需要固定 fsGroup

生产环境建议

生产部署应使用外部 PostgreSQL 数据库(例如 Amazon RDS、Azure Database for PostgreSQL 或专用 PostgreSQL 实例),而不是内置数据库。外部数据库配置请参阅 Kubernetes 部署指南

安装控制面Helm Chart

helm install api7ee3 api7/api7ee3 \
-f cp-values.yaml \
-n api7

验证控制面Service

oc get svc -n api7 -l app.kubernetes.io/name=api7ee3 -o wide

预期输出:

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
api7ee3-dashboard ClusterIP 172.30.39.137 <none> 7080/TCP,7443/TCP 2m
api7ee3-developer-portal ClusterIP 172.30.114.132 <none> 4321/TCP 2m
api7ee3-dp-manager ClusterIP 172.30.232.75 <none> 7900/TCP,7943/TCP 2m

第 3 步:激活许可证

对 Dashboard Service 执行端口转发:

oc port-forward svc/api7ee3-dashboard -n api7 7443:7443

在浏览器中打开 https://localhost:7443,使用默认凭证(admin / admin)登录,然后上传许可证。

第 4 步:配置控制面地址

在 API7 Dashboard 中进入 Gateway Settings,将 Control Plane Address 设置为:

https://api7ee3-dp-manager.api7.svc.cluster.local:7943

数据面实例将使用此地址通过 mTLS 连接控制面。

第 5 步:安装数据面

为 API7 网关配置 SCC

API7 网关运行时需要写入本地文件,例如 nginx.conf、日志和缓存文件。nonroot-v2 SCC 提供所需权限。

为网关创建服务账号:

oc create serviceaccount api7-gateway -n api7

创建授予 nonroot-v2 SCC 使用权限的角色:

oc create role api7-gateway-scc \
--verb=use \
--resource=scc \
--resource-name=nonroot-v2 \
-n api7

将角色绑定到服务账号:

oc create rolebinding api7-gateway-scc \
--role=api7-gateway-scc \
--serviceaccount=api7:api7-gateway \
-n api7

生成部署脚本

在 API7 Dashboard 中选择网关组(例如 default),进入 Gateway Instances 并点击 Add Gateway Instance。切换到 Kubernetes 标签页并点击 Generate,生成包含 mTLS 证书的部署脚本。

生成的脚本包括:

  1. 用于控制面与数据面双向认证的 TLS 证书。
  2. 包含所有必需参数的 Helm 安装命令。

添加 OpenShift 专用 Helm 配置

在生成的 Helm 命令后追加以下参数,以确保兼容 OpenShift:

--set "serviceAccount.name=api7-gateway" \
--set "apisix.securityContext.runAsNonRoot=true" \
--set "apisix.securityContext.runAsUser=636"

完整 Helm 命令应类似如下:

helm upgrade --install api7-ee-3-gateway api7/gateway \
--set "etcd.auth.tls.enabled=true" \
--set "etcd.auth.tls.existingSecret=api7-ee-3-gateway-tls" \
--set "etcd.auth.tls.certFilename=tls.crt" \
--set "etcd.auth.tls.certKeyFilename=tls.key" \
--set "etcd.auth.tls.verify=true" \
--set "gateway.tls.existingCASecret=api7-ee-3-gateway-tls" \
--set "gateway.tls.certCAFilename=ca.crt" \
--set "apisix.extraEnvVars[0].name=API7_GATEWAY_GROUP_SHORT_ID" \
--set "apisix.extraEnvVars[0].value=default" \
--set "etcd.host[0]=https://api7ee3-dp-manager.api7.svc.cluster.local:7943" \
--set "apisix.replicaCount=1" \
--set "apisix.image.repository=api7/api7-ee-3-gateway" \
--set "apisix.image.tag=3.9.10" \
// Annotate 1
--set "serviceAccount.name=api7-gateway" \
// Annotate 2
--set "apisix.securityContext.runAsNonRoot=true" \
// Annotate 3
--set "apisix.securityContext.runAsUser=636" \
-n api7

❶ 使用拥有 nonroot-v2 SCC 访问权限的服务账号。

❷ 确保 Pod 以非 root 用户运行。

❸ 将网关进程 UID 设置为 636,以符合 SCC 要求。

第 6 步:验证安装

检查网关 Pod

oc get pods -n api7 -l app.kubernetes.io/name=gateway

预期输出:

NAME                                       READY   STATUS    RESTARTS   AGE
api7-ee-3-gateway-xxxxx-yyyyy 1/1 Running 0 1m

在 Dashboard 中检查网关实例

在 API7 Dashboard 中进入网关组,网关实例应显示为 Healthy

发送测试请求

对网关 Service 执行端口转发并发送测试请求:

oc port-forward svc/api7-ee-3-gateway-gateway -n api7 9080:80
curl -i "http://127.0.0.1:9080/"

如果尚未配置路由,应收到 API7 网关返回的 404 响应,表明网关正在运行并接收流量。

暴露网关

使用 OpenShift Route

创建 OpenShift Route,将网关暴露到集群外:

oc expose svc/api7-ee-3-gateway-gateway -n api7 --port=80

要使用边缘终止 HTTPS:

oc create route edge api7-gateway \
--service=api7-ee-3-gateway-gateway \
--port=80 \
-n api7

获取 Route URL:

oc get route api7-gateway -n api7 -o jsonpath='{.spec.host}'

使用 LoadBalancer Service

如果 OpenShift 集群支持云负载均衡器:

oc patch svc api7-ee-3-gateway-gateway -n api7 \
-p '{"spec": {"type": "LoadBalancer"}}'

故障排查

Pod 因违反 SCC 而启动失败

现象:Pod 启动失败,错误中出现 SecurityContextConstraintforbidden

解决方法:验证服务账号是否拥有正确的 SCC 绑定:

oc get rolebinding api7-gateway-scc -n api7 -o yaml

验证 SCC 是否已应用到 Pod:

oc describe pod <gateway-pod-name> -n api7 | grep -i scc

PostgreSQL、Prometheus 或 Jaeger Pod 启动失败

现象:内置 PostgreSQL、Prometheus 或 Jaeger Pod 因文件系统权限错误,或 SCC 拒绝固定 UID(Jaeger 为 runAsUser: 10001)而启动失败。

解决方法:确保按第 2 步所示,在 Helm 配置中覆盖三个组件的 securityContext。对于 Jaeger,请确认 runAsUserrunAsGroupfsGroup 均设为 null,空 {} 无法清除这些值。

数据面无法连接控制面

有关 mTLS 连接问题,请参阅 Kubernetes 部署故障排查指南

常见问题

应使用哪个 SCC?

API7 网关使用 nonroot-v2 SCC 即可。它允许 Pod 以非 root 用户(UID 636)运行,同时允许写入 NGINX 配置和日志所需的文件系统。无需使用 privilegedanyuid SCC。

能否将控制面和数据面部署到不同项目?

可以。控制面与数据面通信使用 Kubernetes Service DNS(https://{service-name}.{namespace}.svc.cluster.local:7943),支持跨命名空间。请确保 OpenShift 集群网络策略允许项目之间的流量。

如何连接外部 PostgreSQL?

在 Helm 配置文件中配置数据库 DSN:

postgresql:
enabled: false

externalPostgresql:
host: "YOUR_PG_HOST"
port: 5432
user: "api7"
password: "YOUR_DB_PASSWORD"
database: "api7ee"

后续步骤