istioctl install: Deploy Istio From CI
istioctl install applies an Istio installation to the cluster in your current kube context, from a named profile or an IstioOperator file.
In a pipeline you usually install a fixed profile with pinned overrides so environments stay reproducible. Add --dry-run first to render without touching the cluster.
What it does
istioctl install reconciles the Istio control plane (istiod, gateways) into the cluster your kube context points at. It takes a built-in profile (default, demo, minimal, ambient) plus overrides via --set or a full IstioOperator manifest with -f.
Common usage
istioctl install --set profile=minimal -y
# render without applying (PR gate)
istioctl install -f istio-operator.yaml --dry-run
# pin the tag and skip the prompt
istioctl install --set profile=default --set tag=1.22.0 -yOptions
| Flag | What it does |
|---|---|
| --set <path=value> | Override a single IstioOperator field (repeatable) |
| -f <file> | Apply a full IstioOperator YAML manifest |
| --dry-run | Render the manifests without applying them |
| -y, --skip-confirmation | Do not prompt for confirmation (required in CI) |
| --revision <name> | Install a named revision for canary control-plane upgrades |
| --verify | Verify the install after applying |
In CI
Always pass -y (or --skip-confirmation); without it istioctl install prompts "This will install the Istio ... Proceed? (y/N)" and hangs the job waiting on stdin. Pin the version with --set tag=... so a floating latest does not silently change the control plane.
Common errors in CI
"Error: no active context found" or "context ... does not exist" means KUBECONFIG is unset or points at the wrong file; export KUBECONFIG or pass --kubeconfig. "failed to wait for resource: resources not ready after ... deployment/istiod" means istiod did not come up in the timeout window, usually image pull or resource pressure. "creating default tag would conflict" appears when a revision install collides with an existing default.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes