kubectl set env: Usage, Options & Common CI Errors
Add, change, or strip environment variables without editing YAML.
kubectl set env edits the environment variables of a Deployment's containers. It can set literals, source whole ConfigMaps or Secrets, or remove a variable - each change triggers a rolling update.
What it does
kubectl set env deploy/NAME KEY=VALUE sets a literal; KEY- removes it; --from=configmap/NAME or --from=secret/NAME imports every key as env vars. -c selects a container in a multi-container pod, and --list prints current env without changing anything.
Common usage
kubectl set env deploy/web LOG_LEVEL=debug
kubectl set env deploy/web LOG_LEVEL- # remove the var
kubectl set env deploy/web --from=configmap/app-cfg
kubectl set env deploy/web --from=secret/db-creds --prefix=DB_
kubectl set env deploy/web --list # show, do not changeCommon errors in CI
Each set env change rolls the Deployment, so scripting several separate calls causes several rollouts - batch them in one invocation (or wrap with rollout pause/resume) to ship one rollout. Setting a var to the value it already has is a no-op with no rollout, so a "config change" that did not actually differ never reaches pods. Importing --from=secret base64-decodes for you at runtime, so do not pre-decode. And removing a var the container relies on can crash-loop the new pods - gate on kubectl rollout status so the pipeline catches it.
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