Right, so you’ve got your kustomization.yaml file looking sharp, and you’re ready to deploy. You could run kustomize build ./your-dir/ | kubectl apply -f -, piping the rendered YAML to kubectl. It works, but it feels a bit like using a Rube Goldberg machine to butter your toast. There’s a better way, and it’s built right into kubectl itself: kubectl apply -k.

This flag is kubectl’s native hook into Kustomize. When you run apply -k, kubectl calls the Kustomize library internally to build the configuration from the specified directory and then immediately applies it. It’s a single, clean, atomic command for your deployment workflow. The -k flag is your signal that you’re not just applying a file, you’re applying a customization.

The Basic Command Structure

The syntax is brutally simple. You point -k at the directory containing your kustomization.yaml file.

kubectl apply -k ./my-overlay/

That’s it. Kubectl will build the overlay, send the resulting YAML to the API server, and create or patch all the resources it just built. You’ll see output listing each resource that was configured, just like a standard apply.

service/my-app configured
deployment.apps/my-app created
configmap/my-app-config-8gb58ghf59 created

Notice that last one? The configMap got a hash suffix appended. This is Kustomize working its magic under the hood, ensuring that a change to your configMap automatically triggers a rolling update of any Deployments that reference it, because the Pod template’s reference to the configMap name also changed. You get this immutable-infrastructure goodness for free, without ever writing a template.

Why -k is More Than Just a Shortcut

You might think, “Big deal, it saves me a pipe character.” But the integration goes deeper. The -k flag works across all relevant kubectl commands, creating a consistent experience.

Need to see what would happen without actually changing a thing? Dry-run is your best friend.

kubectl apply -k ./my-overlay/ --dry-run=client

This builds the configuration and shows you the final YAML that would be sent to the server. It’s an invaluable sanity check, especially when you’re knee-deep in complex, multi-layer overlays. Use it religiously.

Want to clean up everything defined in your kustomization?

kubectl delete -k ./my-overlay/

This is spectacularly useful. It tells kubectl to build the configuration just like apply does, but then it uses the generated list of resources to delete them. This ensures you tear down exactly what you built, nothing more and nothing less. It’s a perfect bookend for your environment.

The Gotchas: Where This Thing Will Bite You

Now, let’s get direct about the rough edges. This isn’t all rainbows and unicorns.

First, the -k flag has the same logic as apply regarding the --server-side flag. If you need server-side apply for managing certain fields, you must use the pipe method. You cannot do kubectl apply -k ./dir --server-side. It just doesn’t work. The designers made a questionable choice here, and we’re all stuck with it for now. So for SSA, you’re back to:

kustomize build ./my-overlay/ | kubectl apply --server-side -f -

Second, and this is a big one, error reporting. When you run apply -k, kubectl builds the entire kustomization and then applies it. If there’s a error in the build phase—say, a missing generator—the error message can be spectacularly unhelpful. It might just barf with a generic “error: unable to find one of…” message. When this happens, abandon -k immediately and go back to the pipe method to isolate the problem.

# If 'apply -k' fails, do this to see the real build error:
kustomize build ./my-overlay/

The pipe method gives you a clearer, more specific error from the kustomize CLI itself, which is far better at telling you what’s actually wrong in your kustomization file.

Best Practice: Make It Scriptable

The real power of -k emerges in scripts and CI/CD pipelines. The command is predictable and consistent. You can write a generic deployment script that takes an overlay path as an argument.

#!/bin/bash
OVERLAY_DIR=$1

# Dry-run first to validate
if ! kubectl apply -k "${OVERLAY_DIR}" --dry-run=client; then
    echo "Kustomize build failed. Aborting."
    exit 1
fi

# Actually apply
echo "Applying resources for ${OVERLAY_DIR}..."
kubectl apply -k "${OVERLAY_DIR}"

This script encapsulates the entire workflow: validate, then deploy. It’s robust, simple, and leverages everything we just talked about. So, use -k for your day-to-day commands and automation, but keep kustomize build in your back pocket for debugging. That’s the honest, trench-level workflow.