How to Install Instant API in Kubernetes
Oz Instant API is a stateless deployment of Oz API: it runs liveness and face matching analyses and returns results immediately, without storing any media or results. This guide covers installing it in Kubernetes via the official Helm chart.
The example below is based on the 1.0.2 chart version. However, this is an illustrative example, and we recommend using the latest chart version.
Prerequisites
Before you start: request these from your Oz representative.
DockerHub credentials – to pull the Instant API image (used in step 2 of Preparation).
License key – required to run Instant API (step 3 of Preparation).
Image tag – the application image version to deploy (used in your
valuesfile).
If you plan to use OzCapsula, you will also need to generate a JWT key pair (step 4 of Preparation).
Kubernetes 1.23+ – the chart uses autoscaling/v2 (HPA with behavior policies, GA in 1.23), networking.k8s.io/v1 (Ingress, GA in 1.19), and policy/v1 (PDB, GA in 1.21). Clusters running 1.21–1.22 are partially supported via automatic fallback to autoscaling/v2beta2 and policy/v1beta1.
Before installing, make sure the following components are running in your cluster:
Ingress controller (one of, when using Ingress API):
F5 NGINX Ingress Controller >= 3.0 (recommended, IngressClass:
f5-nginx).ingress-nginx >= 1.0 (legacy, retiring, IngressClass:
nginx).
Gateway API CRDs >= 1.0 and a compatible controller (e.g. Istio >= 1.20, Envoy Gateway, Cilium) – when using Gateway API instead of Ingress. The chart creates
gateway.networking.k8s.io/v1resources (Gateway, HTTPRoute).cert-manager >= 1.0 with a configured
ClusterIssuer(for TLS certificates). For Gateway API TLS, cert-manager >= 1.5 is required with--feature-gates=ExperimentalGatewayAPISupport=true.metrics-server >= 0.5 (required for HPA autoscaling).
cluster-autoscaler (optional, for automatic node scaling).
KEDA >= 2.0 (optional, alternative to vanilla HPA; the chart uses
keda.sh/v1alpha1ScaledObject API).Prometheus Operator (kube-prometheus-stack) >= 0.44 (optional, for
monitoring.coreos.com/v1ServiceMonitor support).
Preparation
1. Create a namespace
kubectl create namespace api-instant
2. Create image pull secret
Alternatively, if you already have a pre-encoded .dockerconfigjson base64 string (e.g., provided by Oz Support), use one of the options:
Then:
The value under .dockerconfigjson is a base64-encoded JSON string in the format {"auths":{"<https://index.docker.io/v1/>":{"username":"...","password":"...","auth":"..."}}}. Contact Oz Support to get the credentials. The secret name must match imagePull.secret in your values (default: oz-dockerhub-creds).
3. Get a license key
Contact Oz Support to get your license key.
4. Create JWT secret (optional)
Instant API in case of using OzCapsula requires a JWT key pair for session tokens. Generate the keys and create the secret:
The secret name must match api.jwt.secretName in your values (default: "").
Installation
1. Add Helm repository
2. Apply basic configuration
Create a my-values.yaml file:
Install the chart:
3. Verify the installation
To check that the API is up and responding, call GET {{host}}/api/healthcheck.
To confirm it processes verification requests, run an analysis against the deployed Instant API.
Upgrade
Key Configuration
Only the parameters marked Mandatory must be set (they appear in the Basic configuration above). All other parameters are optional – you only need to be aware that they exist and can override them if needed.
imagePull.secret
Image pull secret name
oz-dockerhub-creds
imagePull.policy
Image pull policy
IfNotPresent
affinity
Global pod affinity rules (nodeAffinity, podAffinity, podAntiAffinity)
{}
nodeSelector
Global node selector constraints
{}
tolerations
Global tolerations
[]
api.hostname
Mandatory. Public hostname for the Instant API
somehost.example.local
api.additionalHostnames
Additional hostnames (e.g. CDN aliases); added to Ingress rules and Gateway listeners
[]
api.licenseKey
Mandatory. License key for Instant API (from Oz Support)
""
api.extraEnvs
Additional environment variables (key-value pairs). Stored in a ConfigMap – do not put secrets here.
{NUM_WORKERS: "16", ...}
api.extraEnvVarsSecret
Name of an existing Secret whose keys are injected as env vars (via envFrom.secretRef). Use for sensitive values such as S3 credentials.
""
api.image.tag
Mandatory. Application image tag (contact Oz Support)
""
api.resources
CPU and memory requests/limits
requests/limits: 15 CPU, 28Gi RAM
api.autoscaling.hpa.enabled
Enable HPA
true
api.autoscaling.keda.enabled
Enable Keda ScaledObject
false
api.ingress.enabled
Create Ingress resource
true
api.ingress.className
Ingress class
nginx
api.ingress.annotations
Ingress annotations (proxy, CORS, etc.)
{}
api.ingress.tls.enabled
Enable TLS
true
api.ingress.tls.clusterIssuer
cert-manager ClusterIssuer
letsencrypt-production
api.gateway.enabled
Create Gateway API resources (mutually exclusive with api.ingress)
false
api.gateway.className
Gateway class name
istio
api.gateway.annotations
Gateway annotations
{}
api.gateway.tls.enabled
Enable TLS on Gateway
true
api.gateway.tls.clusterIssuer
cert-manager ClusterIssuer for Gateway
letsencrypt-production-dns
api.proxy.enabled
Enable HTTP proxy
false
api.proxy.url
Proxy URL
<http://proxy.local:3128>
api.proxy.auth.existingSecret
Name of existing Secret with all_proxy key containing the full proxy URL. If set, login/password are ignored.
""
api.proxy.auth.login
Proxy username (used when existingSecret is not set)
""
api.proxy.auth.password
Proxy password – special characters are percent-encoded automatically (used when existingSecret is not set)
""
api.serviceMonitor.enabled
Create Prometheus ServiceMonitor
true
For the full list of parameters, see values.yaml.
Traffic management
This chart supports two ways to route external traffic to Instant API: K8s Ingress API and K8s Gateway API. They are mutually exclusive – enable only one at a time.
Important: Any traffic management configuration (load balancing, retries, connection pooling, CORS, etc.) should be validated with load testing that reflects the chosen setup and the client's actual traffic profile.
You can use any controller that implements the chosen K8s API. The examples below show the most common options.
Option 1: K8s Ingress API (default)
Set api.ingress.enabled: true (default) and api.gateway.enabled: false.
The chart creates an Ingress resource. You need an Ingress controller installed in your cluster. Set api.ingress.className to match your controller's IngressClass.
api.ingress.annotations is empty by default. Add annotations that your controller needs.
Ingress-NGINX controller – example configuration
Note: The Ingress-NGINX project is retiring. Consider migrating to the F5 NGINX Ingress Controller.
F5 NGINX Ingress Controller – example configuration
F5 NGINX Ingress Controller does not have dedicated CORS annotations. Use nginx.org/location-snippets with add_header directives instead.
See the F5 NGINX IC annotations docs and the migration guide from ingress-nginx.
Other Ingress controllers
Any controller that implements the Kubernetes Ingress API will work. Set api.ingress.className to your controller's IngressClass and provide the appropriate annotations.
Option 2: Gateway API
Set api.ingress.enabled: false and api.gateway.enabled: true.
The chart creates a Gateway and HTTPRoute resource. You need a controller that implements the Kubernetes Gateway API (e.g., Istio, Envoy Gateway, Cilium). Set api.gateway.className to match your GatewayClass.
Istio – example configuration
Prerequisites:
Istio >= 1.20 with Gateway API CRDs installed
cert-manager >= 1.5 with
--feature-gates=ExperimentalGatewayAPISupport=true
The chart creates Gateway and HTTPRoute resources. Traffic policies such as load balancing, retries, and CORS are not managed by this chart when using Gateway API. Configure them with Istio CRDs applied alongside the Helm release.
Load balancing
DestinationRule
loadBalancer.simple: LEAST_REQUEST
Connection pooling
DestinationRule
connectionPool.http.maxRequestsPerConnection
Outlier detection
DestinationRule
outlierDetection (eject unhealthy endpoints on 5xx)
Retries
EnvoyFilter
Route-level retryPolicy
CORS
EnvoyFilter
Envoy CORS filter (typedPerFilterConfig)
Istio – load balancing, connection pooling, and outlier detection
Create a DestinationRule targeting the Instant API service (replace <release-name> with your Helm release name, e.g. oz-api-instant):
By default, LEAST_REQUEST picks the least-loaded endpoint out of 2 random candidates. For more even distribution across pods (especially useful with heavy liveness verification workloads), create an EnvoyFilter to increase the candidate pool size:
Higher choice_count values improve load distribution but add a small overhead per request. A value of 5 is a good starting point for clusters with 5+ pods.
Alternatively, in Istio >= 1.22 (Envoy >= 1.30) you can use the FULL_SCAN selection method, which scans all endpoints and picks the one with the fewest active requests (ties are broken via reservoir sampling). This guarantees the optimal choice but costs O(n) per request, so it is best suited for deployments with a small number of pods or low RPS:
When load_balancing_policy is set it takes precedence over the legacy lb_policy / least_request_lb_config fields. Use one approach or the other, not both.
Istio – retries
Create an EnvoyFilter to add a route-level retry policy:
Istio – CORS
Create an EnvoyFilter to configure CORS headers:
Replace <release-name> with your Helm release name (e.g. oz-api-instant). The DestinationRule and EnvoyFilter resources above are not part of this chart – apply them with kubectl apply after installing the Helm release.
The exact EnvoyFilter configuration may vary depending on your Istio version. Test with istioctl proxy-config routes and istioctl proxy-config listeners to verify the filters are applied correctly.
Other Gateway API controllers
Any controller that implements the Kubernetes Gateway API will work. Set api.gateway.className to your GatewayClass and add controller-specific settings via api.gateway.annotations.
OpenShift Route
This chart does not create OpenShift Route resources. If you need to use Routes, set api.ingress.enabled: false and api.gateway.enabled: false, then create a Route manually for the http-api port of the service (<release-name>-api).
TLS certificates
Both Ingress and Gateway options support automatic TLS certificate provisioning via cert-manager. Set clusterIssuer or issuer under api.ingress.tls or api.gateway.tls to reference your cert-manager issuer.
Proxy configuration
If the Instant API pod requires internet access through an HTTP proxy, set api.proxy.enabled: true.
Both options below are equally secure – choose whichever fits your setup.
Option 1: inline credentials
Special characters in the password are percent-encoded automatically by the chart.
Option 2: existing Secret
Use this when credentials contain characters that are hard to escape in YAML, or when you want to keep credentials out of values files entirely. Create a Secret with the full proxy URL pre-encoded:
Then, reference it in values:
When auth.existingSecret is set, auth.login and auth.password are ignored. The Secret must contain a key named all_proxy with the complete proxy URL including credentials.
S3 storage
Instant API can store liveness verification data in an S3 or S3-compatible bucket instead of local storage. Two env vars are always required to enable S3:
OZ_INSTANT_SAVING_ARTIFACTS_ENABLED: "true"(for API versions below 6.5:OZ_INSTANT_SAVING_ARTIFACTS_IN_S3_ENABLED)OZ_FILE_STORAGE_TYPE: "S3".
Non-sensitive S3 parameters go in api.extraEnvs; credentials must be placed in a pre-created Secret referenced by api.extraEnvVarsSecret – its keys are injected as env vars alongside the ConfigMap.
Option 1: AWS S3 with access keys
Create a Secret with the credentials:
Reference it in values alongside the non-sensitive S3 params:
Option 2: AWS S3 with IAM role (EKS IRSA)
Use this when running on EKS with IAM Roles for Service Accounts. No access keys are needed – the pod assumes an IAM role via the service account.
1. Create the S3 bucket.
2. Create an OIDC Identity Provider in IAM:
Type: OpenID Connect
Audience:
sts.amazonaws.com
3. Create an IAM policy:
4. Create an IAM role with the following trust policy, then attach the policy from step 3:
Example:
5. Annotate the chart's service account with the role ARN:
6. Set S3 env vars (no access keys needed):
Option 3: S3-compatible storage (MinIO, NetApp StorageGRID, etc.)
Tested compatible: MinIO 5.4.0, NetApp StorageGRID 11.8.
Uninstall
This does not delete the JWT and image pull secrets. Remove them manually if needed.
Last updated
Was this helpful?
