Skip to content
LatchkeyLatchkey home

kubectl apply -k: Apply a Kustomization

kubectl apply -k <dir> renders the kustomization in that directory and applies the result to the cluster.

apply -k is the one-step deploy: kubectl has Kustomize built in, so you skip the separate build. Mind that the embedded version may differ from a standalone kustomize.

What it does

kubectl apply -k <dir> invokes kubectl built-in Kustomize to build the directory, then applies the resulting manifests just like apply -f. kubectl diff -k previews the change without applying. The -k flag also works with delete and other verbs that accept it.

Common usage

Terminal
kubectl apply -k overlays/prod
kubectl diff -k overlays/prod        # preview
kubectl delete -k overlays/prod      # tear down

Flags

FlagWhat it does
-k, --kustomize <dir>Build and apply the kustomization in dir
--dry-run=client|serverValidate without persisting
--server-sideUse server-side apply
--pruneDelete resources no longer in the build (use with care)
-n, --namespaceOverride the namespace at apply time

In CI

kubectl embeds its own Kustomize, which often trails the standalone release and may lack newer fields or the --enable-helm support. For helmCharts or the latest fields, render with a pinned standalone kustomize build and pipe to kubectl apply -f - instead of relying on apply -k. Pin the kubectl version on the runner.

Common errors in CI

"error: unknown field" or "json: unknown field" from apply -k usually means the embedded Kustomize is older than the kustomization expects; render with a newer standalone kustomize. "must specify --enable-helm" cannot be passed through apply -k in older kubectl, so render separately. "namespaces ... not found" means the target namespace is not created by the build.

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.

Terminal
# 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

Frequently asked questions

kubectl apply -k: Apply a Kustomization?
apply -k is the one-step deploy: kubectl has Kustomize built in, so you skip the separate build. Mind that the embedded version may differ from a standalone kustomize.
What it does?
kubectl apply -k <dir> invokes kubectl built-in Kustomize to build the directory, then applies the resulting manifests just like apply -f. kubectl diff -k previews the change without applying. The -k flag also works with delete and other verbs that accept it.
In CI?
kubectl embeds its own Kustomize, which often trails the standalone release and may lack newer fields or the --enable-helm support. For helmCharts or the latest fields, render with a pinned standalone kustomize build and pipe to kubectl apply -f - instead of relying on apply -k. Pin the kubectl version on the runner.
Common errors in CI?
"error: unknown field" or "json: unknown field" from apply -k usually means the embedded Kustomize is older than the kustomization expects; render with a newer standalone kustomize. "must specify --enable-helm" cannot be passed through apply -k in older kubectl, so render separately. "namespaces ...

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card