Deploy on OpenShift
API7 Gateway uses the same Helm charts on Red Hat OpenShift as on a standard Kubernetes deployment, with additional Security Context Constraint (SCC) and service-account configuration. The values on this page match the released charts, but this procedure has not been validated as an end-to-end installation on every supported OpenShift configuration. Test it in a non-production project and review the rendered manifests against your cluster's SCC and storage policies before rollout.
Architecture Overview
API7 Gateway uses the same two-component architecture on OpenShift as on any Kubernetes cluster:
- Control Plane (CP): Dashboard, DP Manager, and PostgreSQL database
- Data Plane (DP): API7 Gateway instances that handle API traffic
The key difference on OpenShift is that pods must comply with Security Context Constraints (SCCs), which restrict the actions a pod can perform.
Prerequisites
Before you begin, ensure you have:
- A supported OpenShift 4 cluster and permission to grant an SCC to a service account.
- An
ocCLI version compatible with the cluster. See Install the OpenShift CLI. - Helm 3. See Install Helm.
- An API7 Enterprise license. See Get a trial license.
Log in to the OpenShift Cluster
Log in using the oc CLI. You can find the login command from the OpenShift web console under your user menu:
oc login \
--token=sha256~YOUR_TOKEN \
--server=https://api.YOUR_CLUSTER.openshiftapps.com:6443
Verify that the current identity can use the nonroot-v2 SCC referenced later in this guide:
oc auth can-i use scc/nonroot-v2
This command checks the current identity only. Delegating SCC use to the gateway service account also requires permission to create the Role and RoleBinding in the target project. Ask a cluster administrator to perform those steps if your identity cannot create or bind them.
Step 1: Create a Project
Create a dedicated OpenShift project (namespace) for API7:
oc new-project api7
Alternatively, create the project from the OpenShift web console.
Step 2: Install the Control Plane
Add the API7 Helm Repository
helm repo add api7 https://charts.api7.ai
helm repo update
Configure Security Context for Built-in Components
The built-in PostgreSQL, Prometheus, and Jaeger pods ship with explicit securityContext settings that conflict with OpenShift's SCC system. PostgreSQL and Prometheus require a writable filesystem, and Jaeger runs with a fixed UID. On OpenShift, clear these settings so the SCC system can assign a UID from the project's allowed range:
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
Jaeger became a built-in control plane component in API7 Gateway 3.9.5 to back the distributed tracing feature. Unlike PostgreSQL and Prometheus, the bundled Jaeger chart has no enabled toggle for its security context and sets runAsUser, runAsGroup, and fsGroup to 10001, which OpenShift's SCC rejects. Because Helm merges values, podSecurityContext: {} does not clear these keys — you must set each to null. Jaeger uses in-memory storage, so it needs no fixed fsGroup.
For production deployments, use an external PostgreSQL database (e.g., Amazon RDS, Azure Database for PostgreSQL, or a dedicated PostgreSQL instance) instead of the built-in one. See the Kubernetes deployment guide for external database configuration.
Install the Control Plane Helm Chart
helm install api7ee3 api7/api7ee3 \
--version 3.10.10 \
-f cp-values.yaml \
-n api7
Verify Control Plane Services
oc get svc -n api7 -l app.kubernetes.io/name=api7ee3 -o wide
Expected output:
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
Step 3: Activate the License
Port-forward the Dashboard service:
oc port-forward svc/api7ee3-dashboard -n api7 7443:7443
Open https://localhost:7443 in your browser. Log in with the default credentials (admin / admin), then upload your license.
Step 4: Configure the Control Plane Address
In the API7 Dashboard, navigate to Gateway Settings and set the Control Plane Address to:
https://api7ee3-dp-manager.api7.svc.cluster.local:7943
This is the address data plane instances will use to connect to the control plane via mTLS.
Step 5: Install the Data Plane
Configure SCC for API7 Gateway
API7 Gateway needs to write local files at runtime (e.g., nginx.conf, logs, cache files). The nonroot-v2 SCC provides the required permissions.
Create a service account for the gateway:
oc create serviceaccount api7-gateway -n api7
Create a role that grants access to the nonroot-v2 SCC:
oc create role api7-gateway-scc \
--verb=use \
--resource=scc \
--resource-name=nonroot-v2 \
-n api7
Bind the role to the service account:
oc create rolebinding api7-gateway-scc \
--role=api7-gateway-scc \
--serviceaccount=api7:api7-gateway \
-n api7
Generate the Deployment Script
In the API7 Dashboard, select a gateway group (e.g., default), navigate to Gateway Instances, and click Add Gateway Instance. Switch to the Kubernetes tab and click Generate to produce the deployment script with mTLS certificates.
The generated script includes:
- TLS certificates for CP-DP mutual authentication
- A Helm install command with all necessary parameters
Add OpenShift-Specific Helm Values
Insert the following flags before the final image settings in the generated Helm command. Keep the certificate-secret creation and all control-plane connection values from the generated script unchanged:
--set "serviceAccount.name=api7-gateway" \
--set "apisix.securityContext.runAsNonRoot=true" \
--set "apisix.securityContext.runAsUser=636" \
--version 3.10.15 \
The service-account value selects the account granted the nonroot-v2 SCC. The security-context values keep the container non-root and use UID 636, which is the apisix user built into the released gateway image. The chart version shown here is the released gateway chart whose application version is 3.10.7; the generated command should also select the 3.10.7 gateway image from the gateway-group configuration.
Step 6: Verify the Installation
Check Gateway Pods
oc get pods -n api7 -l app.kubernetes.io/name=gateway
Expected output:
NAME READY STATUS RESTARTS AGE
api7-ee-3-gateway-xxxxx-yyyyy 1/1 Running 0 1m
Check Gateway Instances in the Dashboard
Navigate to the gateway group in the API7 Dashboard. The gateway instances should appear as Healthy.
Send a Test Request
Port-forward the gateway service and send a test request:
oc port-forward svc/api7-ee-3-gateway-gateway -n api7 9080:80
curl -i "http://127.0.0.1:9080/"
If no routes are configured, you should receive a 404 response from API7 Gateway, confirming it is running and accepting traffic.
Expose the Gateway
Using OpenShift Routes
Create an OpenShift Route to expose the gateway externally:
oc expose svc/api7-ee-3-gateway-gateway -n api7 --port=80
For HTTPS with edge termination:
oc create route edge api7-gateway \
--service=api7-ee-3-gateway-gateway \
--port=80 \
-n api7
Get the route URL:
oc get route api7-gateway -n api7 -o jsonpath='{.spec.host}'
Using a LoadBalancer Service
If your OpenShift cluster supports cloud load balancers:
oc patch svc api7-ee-3-gateway-gateway -n api7 \
-p '{"spec": {"type": "LoadBalancer"}}'
Troubleshooting
Pod Fails with SCC Violation
Symptom: Pod fails to start with an error referencing SecurityContextConstraint or forbidden.
Resolution: Verify the service account has the correct SCC binding:
oc get rolebinding api7-gateway-scc -n api7 -o yaml
Verify the SCC is applied to the pod:
oc describe pod <gateway-pod-name> -n api7 | grep -i scc
PostgreSQL, Prometheus, or Jaeger Pods Fail to Start
Symptom: A built-in PostgreSQL, Prometheus, or Jaeger pod fails to start, either with a filesystem permission error or an SCC error rejecting a fixed UID (for Jaeger, runAsUser: 10001).
Resolution: Ensure the securityContext overrides for all three components are applied in the Helm values as shown in Step 2. For Jaeger, confirm the runAsUser, runAsGroup, and fsGroup keys are set to null (an empty {} does not clear them).
Data Plane Cannot Connect to Control Plane
See the Kubernetes deployment troubleshooting guide for mTLS connectivity issues.
FAQ
Which SCC Should I Use?
The released gateway image runs as the non-root apisix user with UID and GID 636, and its writable runtime directories are owned by that user. Start with nonroot-v2 and the values in this guide. If your cluster applies additional policies, inspect the admission error and rendered pod security context before granting a broader SCC. Do not grant privileged or anyuid only to bypass an unexplained deployment failure.
Can I Deploy the Control Plane and Data Plane in Different Projects?
Yes. The CP-DP communication uses Kubernetes service DNS (https://{service-name}.{namespace}.svc.cluster.local:7943), which works across namespaces. Ensure the network policies in your OpenShift cluster allow traffic between the projects.
How Do I Connect to an External PostgreSQL?
Configure the database DSN in the Helm values file:
postgresql:
builtin: false
dashboard_configuration:
database:
dsn: "postgres://api7ee:YOUR_DB_PASSWORD@YOUR_PG_HOST:5432/api7ee"
dp_manager_configuration:
database:
dsn: "postgres://api7ee:YOUR_DB_PASSWORD@YOUR_PG_HOST:5432/api7ee"
developer_portal_configuration:
database:
dsn: "postgres://api7ee:YOUR_DB_PASSWORD@YOUR_PG_HOST:5432/api7ee"
Store the production database password in a secret-management workflow appropriate for your cluster instead of committing it to a values file.
Next Steps
- Deploy for High Availability: Configure multi-replica deployments.
- Configure the Control Plane: Fine-tune control plane settings.
- Scale the Data Plane: Add more gateway instances.