在 OpenShift 上部署
本指南介绍如何在 Red Hat OpenShift 集群上部署 API7 网关。部署采用与标准 在 Kubernetes 上部署相同的 Helm 模型,同时说明安全上下文约束(SCC)和服务账号配置等 OpenShift 特有事项。
架构概览
API7 网关在 OpenShift 上使用与其他 Kubernetes 集群相同的双组件架构:
- 控制面(CP):控制台、DP Manager 和 PostgreSQL 数据库。
- 数据面(DP):处理 API 流量的 API7 网关实例。
OpenShift 的主要区别是 Pod 必须符合安全上下文约束(SCC),它限制 Pod 可以执行的操作。
前置条件
开始前,请确保具备:
- 运行
4.12或更高版本且拥有cluster-admin权限的 OpenShift 集群。 - OpenShift CLI(
oc)4.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:
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 开关,并将 runAsUser、runAsGroup 和 fsGroup 设置为 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 步:激活许可证
对控制台 Service 执行端口转发:
oc port-forward svc/api7ee3-dashboard -n api7 7443:7443
在浏览器中打开 https://localhost:7443,使用默认凭证(admin / admin)登录,然后上传许可证。
第 4 步:配置控制面地址
在 API7 控制台中进入 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 控制台中选择网关组(例如 default),进入 Gateway Instances 并点击 Add Gateway Instance。切换到 Kubernetes 标签页并点击 Generate,生成包含 mTLS 证书的部署脚本。
生成的脚本包括:
- 用于控制面 与数据面双向认证的 TLS 证书。
- 包含所有必需参数的 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
在控制台中检查网关实例
在 API7 控制台中进入网关组,网关实例应显示为 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 启动失败,错误中出现 SecurityContextConstraint 或 forbidden。
解决方法:验证服务账号是否拥有正确的 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,请确认 runAsUser、runAsGroup 和 fsGroup 均设为 null,空 {} 无法清除这些值。
数据面无法连接控制面
有关 mTLS 连接问题,请参阅 在 Kubernetes 上部署。
常见问题
应使用哪个 SCC?
API7 网关使用 nonroot-v2 SCC 即可。它允许 Pod 以非 root 用户(UID 636)运行,同时允许写入 NGINX 配置和日志所需的文件系统。无需使用 privileged 或 anyuid 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"
后续步骤
- 部署高可用环境:配置多副本部署。
- API7 网关控制面配置参考:调整控制面设置。
- 扩缩容数据面:添加更多网关实例。