Air-Gapped Installation
This guide explains how to install Kedify in air-gapped or network-restricted Kubernetes clusters.
In this setup, cluster nodes cannot pull images directly from public registries such as ghcr.io or quay.io.
You must first mirror all required images into your private registry and then configure Kedify Helm values to use the mirrored locations.
For the standard online installation, refer to Dashboard Installation.
Prerequisites
- A running Kubernetes cluster (for example EKS, GKE, AKS, OpenShift, or on-prem Kubernetes)
- Access to a private container registry reachable from your cluster nodes
kubectlconfigured for your clusterhelminstalleddocker(withbuildx) or another OCI-compatible image tool- A Kedify account with Organization ID and API key
Required Images
Mirror every Kedify and dependency image to your private registry. Pin the mirrored copies by digest for deterministic deployments.
Current source version: v0.6.8 (updated 2026-07-31)
docker.io/bats/bats:v1.4.1@sha256:d1049593eee83c2c8f420cdc94e4a540532cb09d681cc6bb098cbc5c4e739affdocker.io/grafana/grafana:12.3.1@sha256:7c064e627d9cb50c3485c9ded5ca0222de89a08e41403322a0c3ca6f1777a8d1docker.io/grafana/loki-canary:3.7.3@sha256:85ba0ef50525b17bed881bfe2dbac81c4aa25e3a33f1537c0e8296d877a4f495docker.io/grafana/loki:3.7.3@sha256:d14b3a2c419b72fe27cd094c017863bd37a5ea9ac7d72f35bcd25f5bd081dc47docker.io/kiwigrid/k8s-sidecar:2.8.0@sha256:a81226f4f135a391636776e3364e70c318621086e8b8cc1ae63c7b3654b847fbdocker.io/nginxinc/nginx-unprivileged:1.31-alpine@sha256:e1e5ceb69d135a725ea762637f730bd3e0721f11a957de34bade41db9a29bd60envoyproxy/envoy:v1.39.0@sha256:f6e2f57b1bef8235083a2553b523508cf97d8991c893fd2aae3a94a6b21096a2ghcr.io/jkroepke/access-log-exporter:0.4.4@sha256:ccec179021f0a1538d6f760a261a7138839a66314d4852396b6317697bb62b0aghcr.io/kedify/agent:v0.6.8@sha256:0750a03c7cfe45127f91f1e2d44c50ddd5c73f7fdafeedfa28ac543c37e147f5ghcr.io/kedify/autoscaling-checks:v0.0.2@sha256:f59e123907cf39c58f336656c5433601c3580e5cd5fb9cdd7b899a4730accb3bghcr.io/kedify/http-add-on-interceptor:v0.11.1-6@sha256:855fc4c0bcffbde0b472613e6d0731ca477383284b1a5556e7ab4d44e64a65e0ghcr.io/kedify/http-add-on-scaler:v0.11.1-6@sha256:9a556e9badf6bff4054292121d2e774ef17b1cf727c511b2efd570f08aee925dghcr.io/kedify/keda-admission-webhooks:v2.20.2-0@sha256:13cd5c292d12b9bf68d7ba36e75a184bdc52010d9b90cc1c98c8b3c782afc137ghcr.io/kedify/keda-metrics-apiserver:v2.20.2-0@sha256:1d9471db4a12f638e995403f10a680594adfee9b44a82c14752809f13e0595c0ghcr.io/kedify/keda-operator:v2.20.2-0@sha256:23e2f4e310a9ea2874d08f286939e22d46f6f4e8b4aa63b98417c35d43c18658ghcr.io/kedify/keda-prediction-controller:v0.1.5@sha256:edb5353e0b471ec6c41bd436711fe2710f881fcffa8856ce7f26f9c9304a8cd1ghcr.io/kedify/keda-prophet:v0.1.5@sha256:414f1183c0adad8fb7facd8f3233e3616369943cac6609ce00e7cc02d572d4b3ghcr.io/kedify/kubectl:v1.33.1@sha256:2ea25099363a3f16a491fc2c5a30fff304a8bbd939c782f0f80b399e821084c3ghcr.io/kedify/otel-add-on:v0.1.4@sha256:9fa29faf5ffabe7bd039c9e7e0eb8d642b3110a6bed80ad01540858daba0df14ghcr.io/kedify/sample-http-server:latest@sha256:325c0389411f881510e9c785cdbd069725b409f0cfc30f017703932cdc957a50ghcr.io/kedify/sample-load-generator:latest@sha256:5488057bfa8b5c45dcf15bbf6fbede527f6442a940a48a19e5203c9d1e2537edghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.131.0@sha256:004e38c269fa37816e247d6b9196e339f7c65c5b6950309cd7b2d7d08c9cbdacotel/opentelemetry-collector-k8s:0.154.0@sha256:9be3317fb7244cc1e8af2c00edefeb5a40d5f5a47698bede4e3480aa5d263a2cquay.io/brancz/kube-rbac-proxy:v0.19.1@sha256:ea7bdc09a4929c8cad2b84b06ea4455721e75d4b86aa3dddf41f29b4817db358quay.io/kiwigrid/k8s-sidecar:2.5.0@sha256:4f8f7ff326827489dc3742e17cd0e04e2f89deb49f67021d2a5418d8b78e7ddcquay.io/minio/mc:RELEASE.2024-11-21T17-21-54Z@sha256:771f5ad7925a6b5e069786d8e847a292de320f1e3e3203647e29f47ec9b3d93bquay.io/minio/minio:RELEASE.2024-12-18T13-15-44Z@sha256:34c8e2f52a5984492555427fee07254c80036bdb7079bb91679232abd7a4fa20quay.io/prometheus-operator/prometheus-config-reloader:v0.92.1@sha256:bf6f3527663207af1d936e4f3f27c7a4aab703c0de2a82844f95c14af35dfe19quay.io/prometheus/prometheus:v3.12.0@sha256:dd4bced05dfaddf23a7ec50f87334993a4149f7fcfbf58456d1c8bafce91cd13registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.1@sha256:7661da8c99b733d43117e4cba12bd9865d335e5777191d0af3d789807aded9f4Mirror Images to Your Private Registry
The example below mirrors images to registry.internal.example.com. Adjust the registry host and target paths to match your environment.
REGISTRY="registry.internal.example.com"
while read -r IMAGE; do [ -z "$IMAGE" ] && continue
TARGET="$REGISTRY/${IMAGE#*/}"
docker pull "$IMAGE" docker tag "$IMAGE" "$TARGET" docker push "$TARGET"done <<'IMAGES'docker.io/bats/bats:v1.4.1@sha256:d1049593eee83c2c8f420cdc94e4a540532cb09d681cc6bb098cbc5c4e739affdocker.io/grafana/grafana:12.3.1@sha256:7c064e627d9cb50c3485c9ded5ca0222de89a08e41403322a0c3ca6f1777a8d1docker.io/grafana/loki-canary:3.7.3@sha256:85ba0ef50525b17bed881bfe2dbac81c4aa25e3a33f1537c0e8296d877a4f495docker.io/grafana/loki:3.7.3@sha256:d14b3a2c419b72fe27cd094c017863bd37a5ea9ac7d72f35bcd25f5bd081dc47docker.io/kiwigrid/k8s-sidecar:2.8.0@sha256:a81226f4f135a391636776e3364e70c318621086e8b8cc1ae63c7b3654b847fbdocker.io/nginxinc/nginx-unprivileged:1.31-alpine@sha256:e1e5ceb69d135a725ea762637f730bd3e0721f11a957de34bade41db9a29bd60envoyproxy/envoy:v1.39.0@sha256:f6e2f57b1bef8235083a2553b523508cf97d8991c893fd2aae3a94a6b21096a2ghcr.io/jkroepke/access-log-exporter:0.4.4@sha256:ccec179021f0a1538d6f760a261a7138839a66314d4852396b6317697bb62b0aghcr.io/kedify/agent:v0.6.8@sha256:0750a03c7cfe45127f91f1e2d44c50ddd5c73f7fdafeedfa28ac543c37e147f5ghcr.io/kedify/autoscaling-checks:v0.0.2@sha256:f59e123907cf39c58f336656c5433601c3580e5cd5fb9cdd7b899a4730accb3bghcr.io/kedify/http-add-on-interceptor:v0.11.1-6@sha256:855fc4c0bcffbde0b472613e6d0731ca477383284b1a5556e7ab4d44e64a65e0ghcr.io/kedify/http-add-on-scaler:v0.11.1-6@sha256:9a556e9badf6bff4054292121d2e774ef17b1cf727c511b2efd570f08aee925dghcr.io/kedify/keda-admission-webhooks:v2.20.2-0@sha256:13cd5c292d12b9bf68d7ba36e75a184bdc52010d9b90cc1c98c8b3c782afc137ghcr.io/kedify/keda-metrics-apiserver:v2.20.2-0@sha256:1d9471db4a12f638e995403f10a680594adfee9b44a82c14752809f13e0595c0ghcr.io/kedify/keda-operator:v2.20.2-0@sha256:23e2f4e310a9ea2874d08f286939e22d46f6f4e8b4aa63b98417c35d43c18658ghcr.io/kedify/keda-prediction-controller:v0.1.5@sha256:edb5353e0b471ec6c41bd436711fe2710f881fcffa8856ce7f26f9c9304a8cd1ghcr.io/kedify/keda-prophet:v0.1.5@sha256:414f1183c0adad8fb7facd8f3233e3616369943cac6609ce00e7cc02d572d4b3ghcr.io/kedify/kubectl:v1.33.1@sha256:2ea25099363a3f16a491fc2c5a30fff304a8bbd939c782f0f80b399e821084c3ghcr.io/kedify/otel-add-on:v0.1.4@sha256:9fa29faf5ffabe7bd039c9e7e0eb8d642b3110a6bed80ad01540858daba0df14ghcr.io/kedify/sample-http-server:latest@sha256:325c0389411f881510e9c785cdbd069725b409f0cfc30f017703932cdc957a50ghcr.io/kedify/sample-load-generator:latest@sha256:5488057bfa8b5c45dcf15bbf6fbede527f6442a940a48a19e5203c9d1e2537edghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.131.0@sha256:004e38c269fa37816e247d6b9196e339f7c65c5b6950309cd7b2d7d08c9cbdacotel/opentelemetry-collector-k8s:0.154.0@sha256:9be3317fb7244cc1e8af2c00edefeb5a40d5f5a47698bede4e3480aa5d263a2cquay.io/brancz/kube-rbac-proxy:v0.19.1@sha256:ea7bdc09a4929c8cad2b84b06ea4455721e75d4b86aa3dddf41f29b4817db358quay.io/kiwigrid/k8s-sidecar:2.5.0@sha256:4f8f7ff326827489dc3742e17cd0e04e2f89deb49f67021d2a5418d8b78e7ddcquay.io/minio/mc:RELEASE.2024-11-21T17-21-54Z@sha256:771f5ad7925a6b5e069786d8e847a292de320f1e3e3203647e29f47ec9b3d93bquay.io/minio/minio:RELEASE.2024-12-18T13-15-44Z@sha256:34c8e2f52a5984492555427fee07254c80036bdb7079bb91679232abd7a4fa20quay.io/prometheus-operator/prometheus-config-reloader:v0.92.1@sha256:bf6f3527663207af1d936e4f3f27c7a4aab703c0de2a82844f95c14af35dfe19quay.io/prometheus/prometheus:v3.12.0@sha256:dd4bced05dfaddf23a7ec50f87334993a4149f7fcfbf58456d1c8bafce91cd13registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.1@sha256:7661da8c99b733d43117e4cba12bd9865d335e5777191d0af3d789807aded9f4IMAGESConfigure Helm Values for Air-Gapped Registry
Create air-gapped-values.yaml and override image repositories to point to your mirrored registry.
agent: image: repository: registry.internal.example.com/kedify/agent tag: <agent-tag> kubectlImage: repository: registry.internal.example.com/kedify/kubectl tag: <kubectl-tag>
keda: image: keda: repository: registry.internal.example.com/kedify/keda-operator tag: <keda-operator-tag> metricsApiServer: repository: registry.internal.example.com/kedify/keda-metrics-apiserver tag: <keda-metrics-apiserver-tag> webhooks: repository: registry.internal.example.com/kedify/keda-admission-webhooks tag: <keda-webhooks-tag>
keda-add-ons-http: images: interceptor: registry.internal.example.com/kedify/http-add-on-interceptor:<http-interceptor-tag> scaler: registry.internal.example.com/kedify/http-add-on-scaler:<http-scaler-tag> kubectlImage: repository: registry.internal.example.com/kedify/kubectl tag: <kubectl-tag>
otel-add-on: image: repository: registry.internal.example.com/kedify/otel-add-on tag: <otel-add-on-tag> kubectlImage: repository: registry.internal.example.com/kedify/kubectl tag: <kubectl-tag> otelOperator: manager: image: repository: registry.internal.example.com/open-telemetry/opentelemetry-operator/opentelemetry-operator tag: <otel-operator-tag> kubeRBACProxy: image: repository: registry.internal.example.com/brancz/kube-rbac-proxy tag: <kube-rbac-proxy-tag>
kedify-predictor: image: repository: registry.internal.example.com/kedify/keda-prophet tag: <keda-prophet-tag> kedaPredictionController: image: repository: registry.internal.example.com/kedify/keda-prediction-controller tag: <keda-prediction-controller-tag> kubectlImage: repository: registry.internal.example.com/kedify/kubectl tag: <kubectl-tag>If your registry requires authentication, configure imagePullSecrets for the relevant components and service accounts.
Install Kedify with Air-Gapped Values
Use the Kedify installation method you normally use (Dashboard, Fleet, or Helm), and provide the image override values.
helm upgrade --install kedify-agent kedifykeda/kedify-agent \ --namespace keda \ --create-namespace \ -f air-gapped-values.yamlValidate the Installation
1. Check all pods are running:
kubectl get pods -n keda2. Confirm images are pulled from your internal registry:
kubectl get pods -n keda -o jsonpath='{..image}' | tr ' ' '\n' | sort -u3. Ensure there are no ImagePullBackOff or ErrImagePull states:
kubectl get pods -n kedakubectl describe pod <pod-name> -n kedaTroubleshooting
ImagePullBackOfffrom public registry: one or more image repositories were not overridden in Helm values.- Pull authentication errors: verify registry credentials and
imagePullSecretsconfiguration. - TLS trust errors against internal registry: ensure cluster nodes trust the private registry CA certificate.
- Missing image in internal registry: confirm the exact digest-pinned image exists in the mirrored target repository.