Use kcli to mirror connector images
kcli is designed for environments requiring image mirroring before deployment, including air-gapped clusters and GitOps-driven installations. The tool integrates into the Cortex Cloud portal's Kubernetes Connect wizard, slotting between the configuration download step and the final installation step.
Functional responsibilities
The image mirroring workflow distributes tasks across two roles:
Platform Engineer (Infrastructure): Installs kcli, mirrors images to the private registry, and commits the rewritten values file to version control.
Cluster Administrator (Deployment): Executes the portal's installation commands against the rewritten values file to deploy the konnector to the cluster.
Prerequisites
Verify the following tools are installed on the workstation where you will run kcli:
bash
4.0+
Script runtime
docker
20.10+ with buildx
Pull and push multi-architecture images
yq
v4 (mikefarah/yq)
YAML processing
jq
1.6+
JSON processing
curl
Any recent version
Chart download and version check
helm
3.8+
Pull chart from source OCI registry
tar, base64
POSIX standard
Bundled with all supported operating systems
Install the image mirroring CLI
kcli is a single self-contained bash script. Pin to a specific version tag for reproducible installations.
Alternatively, clone the repository and create a symlink to the kcli script in your PATH:
Mirror images to your private registry
Step 1: Download configuration files from the portal
From Cortex, navigate to Settings → Data Sources & Integrations.
Select Kubernetes, and then right-click and select Edit.
Click Edit Profile and configure the following:
Set Profile Name to
Standalone-Installer.Disable Auto Upgrade.
Click Apply.
Click Generate.
From the Kubernetes Connect screen, download both
values.yamlandauth.jsonto your computer.Do not continue with the steps in the wizard. This should be done later when deploying the konnector.
Step 2: Create a pull secret for your private registry
If you are using --docker-pull-secret-file, create a kubelet-compatible pull secret with inline credentials. kubelet cannot use Docker credential helpers (credsStore, credHelpers, osxkeychain, acr, gcloud, ecr-login).
Build the pull secret:
Credential recipes by registry:
Azure Container Registry (ACR): Use an ACR token with pull rights: :
Google Artifact Registry (GAR) / Google Container Registry (GCR): Use a service account with
roles/artifactregistry.reader: _json_key:$(cat key.json)Amazon Elastic Container Registry (ECR): Prefer IRSA or EKS Pod Identity with
--no-pull-secret(ECR tokens expire after 12 hours).Harbor, Quay, Artifactory: Use a robot account:
username:passwordDocker Hub: Use a Personal Access Token:
<username>:<PAT>
Step 3: Mirror images and rewrite values.yaml
Sign in to your private registry: docker login myregistry.azurecr.io
Run kcli mirror to pull images from the Cortex source registry and push them to your private registry: kcli mirror \ --chart-version 2.0.0 \ --values ./values.yaml \ --private-registry myregistry.azurecr.io/cortex \ --docker-pull-secret-file ./pull-secret.dockerconfigjson ### Note If you have already downloaded the Helm chart archive (for example, on an air-gapped relay host), pass the local chart file instead: kcli mirror \ --chart ./konnector-2.0.0.tgz \ --values ./values.yaml \ --private-registry myregistry.azurecr.io/cortex \ --docker-pull-secret-file ./pull-secret.dockerconfigjsonWhat kcli modifies: kcli writes a timestamped backup to
<values>.bak.YYYYMMDDTHHMMSSZand updates three fields inyour values file: global: imageRegistry: myregistry.azurecr.io/cortex dockerPullSecret: bundle: : image: repository:Delete the temporary pull secret file: rm pull-secret.dockerconfigjson The credentials are now embedded in the rewritten values file under
global.dockerPullSecret.Commit the rewritten values file to version control if you are using GitOps (Argo CD, Flux): git add values.yaml git commit -m "Mirror konnector images to private registry" git push
Step 4: Deploy the Konnector
From the Kubernetes Connect screen, continue at step 2 where you run deployment script and install the Helm chart. This block contains two commands:
helm registry login: Authenticates to the Cortex source OCI registry using the
auth. jsoncredentials.helm upgrade --install: Deploys the konnector using the rewritten values file, so Pods pull images from your private registry.
Run both commands together as shown on the screen:
cat K8s-security-profile-panw-31-May-26-5PM.auth.json | helm registry login us-central1-docker.pkg.dev --username _json_key --password-stdin helm upgrade --install konnector oci://us-central1-docker.pkg.dev/qa2-test- 99924894351125/agent-docker/helm/konnector-launcher \ --wait-for-jobs \ --create-namespace \ --namespace panw \ --values K8s-security-profile-panw-31-May-26-5PM.values.yaml \ --set-file konnector-upgrader.rawValuesContent=K8s-security-profile-panw- 31-May-26-5PM.values.yaml
kcli command reference
kcli mirror
Mirror images and rewrite the Helm values file.
kcli mirror (--chart <chart.tgz> | --chart-version ) \ --values \ --private-registry \ (--docker-pull-secret | --docker-pull-secret-file | --no-pull-secret) \ [--dry-run]
--chart<chart.tgz>
One of these
Local konnector Helm chart archive (bundle v2+).
--chart-version<version>
One of these
Pull the chart from oci://<global.imageRegistry>/helm/konnector-bundle:<version> (for example, 2.0.0). The <global.imageRegistry> value is read from the values file. Requires helm.
--values<file>
Yes
Tenant values YAML file. Rewritten in place with a .bak backup.
--private-registry<url>
Yes
Target registry URL (for example, myregistry.azurecr.io/proj/repo).
--docker-pull-secret<b64>
One of these
Base64-encoded dockerconfigjson.
--docker-pull-secret-file <file>
One of these
Path to dockerconfigjson file (automatically base64-encoded).
--no-pull-secret
One of these
Strip global.dockerPullSecret from values. Use for managed identities (IRSA, AKS, GKE) or out-of-band imagePullSecret resources.
--dry-run
No
Preview changes without pulling, pushing, or rewriting files.
-h, --help
No
Display command help.
Other commands
kcli version(also--version,-v): Display the installed kcli version.kcli help(also--help,-h): Display general help.kcli mirror --help: Display help for the mirror command.
Environment variables
NO_COLOR: Set to any value to disable ANSI color output.DOCKER_CONFIG: Docker configuration directory (default:~/.docker).TMPDIR: Temporary directory for chart extraction and logs (default:/tmp).KCLI_SKIP_VERSION_CHECK: Set to1to skip the upstream version check (air-gapped environments).
Exit codes
0- Success1- Runtime failure64- Usage error65- Stale version (kcli is outdated)130- Interupted by user
Update kcli
Every kcli run (except version and help) compares your local version to the canonical script on the main branch. If your version is older, kcli fails with exit code 65 and an actionable message.
The version check is best-effort and is skipped (with a warning) if curl is unavailable, the fetch times out (5 seconds), or KCLI_SKIP_VERSION_CHECK=1 is set.
To update
Installed via curl: Re-run the install command and update the
KCLI_VERSIONvariable.Installed via git clone: Run
git pullin the cloned repository.
Troubleshooting image mirroring
"Unsupported bundle version"
kcli requires bundle v2 or higher. Verify with tar -xzOf <chart.tgz> konnector-bundle/Chart.yaml | yq '.version'. Download a v2+ chart from the Cortex Cloud portal.
"Could not extract global.imageRegistry/global.dockerPullSecret"
Your values file is missing required fields. The portal-issued file includes both. Verify you are not using a hand-crafted values file.
Docker login failures
Source registry credentials come from global.dockerPullSecret (must be valid base64). For the target registry, run docker login <your-registry> first. In CI/CD, use non-interactive login.
ImagePullBackOff after installation
Most common causes: (1) You used --docker-pull-secret-file with ~/.docker/config.json that delegates to a credential helper. Build a proper inline secret per the pull secret section. (2) You used --no-pull-secret but did not create the imagePullSecret resource, or your managed-identity binding is incorrect.
Multi-architecture push failures
kcli uses docker buildx imagetools create and falls back to single-architecture docker tag and docker push. Ensure docker buildx is installed and a builder exists: docker buildx create --use.
"Wrong yq" error
Run yq --version. Must show mikefarah/yq v4. Install with brew install yq (macOS) or follow the mikefarah/yq installation guide.
"A newer kcli version is available" (exit 65)
Update kcli per the Update kcli section, or set KCLI_SKIP_VERSION_CHECK=1 in air-gapped environments.
Debugging
Each run writes a log to $TMPDIR/kcli-log-XXXXXX.log (preserved on success and failure). Attach this log to support tickets. For deep debugging, run bash -x /usr/local/bin/kcli mirror ...
Last updated
Was this helpful?
