How I Use Kustomize on GKE for app deployments?

How I Use Kustomize on GKE for Real-World Kubernetes Deployments

When I first started running production workloads on GKE, I thought managing Kubernetes manifests would be the easy part. Just write some YAML, deploy it, and move on.

That illusion lasted about two environments.

Very quickly, I found myself dealing with the same application deployed to dev, staging, and prod, each with slightly different settings. Different image tags, different replica counts, different ingress hosts, different resource limits. The core workload was the same, but the configuration kept drifting.

At first, I did what most people do: copy folders and tweak values manually. Then I tried Helm. Then I realized both approaches were solving different problems than the one I actually had.

That’s when I landed on Kustomize as the right level of abstraction for most GKE workloads.

Why Kubernetes config becomes painful on GKE

GKE makes it very easy to spin up clusters, but it doesn’t solve the configuration problem for you.

In real systems, you usually have:

  • Multiple environments (dev, staging, prod)

  • Multiple clusters or projects

  • The same service deployed everywhere

  • Slight but important differences between environments

The problem is not writing YAML. The problem is maintaining consistency over time without duplication.

This is where most teams either:

  • Copy-paste manifests

  • Or introduce complex templating systems too early

Both approaches create long-term operational debt.

What Kustomize actually is (in practical terms)

Kustomize is often described as a “configuration management tool for Kubernetes”, but that’s too vague to be useful.

In simple terms, Kustomize lets you:

  • Define a base configuration that represents the core workload

  • Define overlays that modify only what needs to change per environment

  • Compose everything together without templates or variables

The most important mental shift is this:

Kustomize is about composition, not generation.

It doesn’t generate YAML from logic.
It layers and modifies existing YAML in a predictable way.

This turns out to be exactly what most GKE teams need.

Why Kustomize fits GKE particularly well

GKE environments usually follow a fairly consistent pattern:

  • Same cluster architecture

  • Same namespaces

  • Same service structure

  • Different scale and exposure

What changes is typically:

  • Replica counts

  • Resource limits

  • Ingress settings

  • Image versions

  • Node pool placement

Kustomize works well here because it lets you keep the “what” stable and only adjust the “how much” and “where”.

It also integrates nicely with the GKE ecosystem:

  • Native support in kubectl

  • Works with GitHub Actions, Cloud Build, ArgoCD, Flux

  • No extra runtime or controllers required

It’s just configuration logic, which is a big operational advantage.

The base and overlay model (the core idea)

This is the single most important concept in Kustomize.

The base represents:

  • What the service is

  • What never changes

  • The core deployment, service, config maps

The overlays represent:

  • Where it runs

  • How it behaves in that environment

  • The differences that must exist

In practice, this usually means:

The base contains:

  • Deployment

  • Service

  • Health probes

  • Default resource requests

The overlays contain:

  • Image tags

  • Replicas

  • Ingress hostnames

  • Environment-specific annotations

  • Higher resource limits in prod

This separation forces you to think clearly about what is truly environment-specific and what is not. That alone improves design quality.

How I structure Kustomize repos on GKE

In most cases, I keep Kustomize inside the application repo.

A typical structure looks like:

  • /base

  • /overlays/dev

  • /overlays/staging

  • /overlays/prod

Each overlay has its own kustomization.yaml that references the base and applies patches.

This keeps everything:

  • Versioned with the code

  • Easy to review

  • Easy to promote between environments

For platform teams, this also fits nicely with golden paths and service templates, because the structure is predictable and repeatable.

Kustomize vs Helm (an honest comparison)

This is where many discussions become ideological. I prefer to be pragmatic.

Helm is great when:

  • You need to package complex software

  • You consume third-party charts

  • You need parameterized releases

Kustomize is better when:

  • You control the application

  • You want full transparency

  • You care about diff readability

  • You want minimal abstraction

In most GKE platforms I’ve worked on, the pattern ends up being:

  • Helm for vendor software (Prometheus, Istio, cert-manager)

  • Kustomize for internal services

That combination works very well.

Common Kustomize mistakes I see on GKE

The biggest mistake is overusing overlays.

I’ve seen setups with:

  • 10+ overlays

  • Deeply nested patches

  • No clear base

At that point, you’ve recreated the complexity you were trying to avoid.

Another common mistake is using Kustomize to manage secrets directly. That usually leads to either committing secrets to Git or building fragile workflows. Kustomize should reference secrets, not store them.

Finally, many teams treat Kustomize as a replacement for validation and policy. It’s not. You still need:

  • OPA or admission policies

  • Resource quotas

  • Naming conventions

  • Platform guardrails

Kustomize helps with structure, not governance.

Kustomize in a real GKE CI/CD pipeline

In most real pipelines, Kustomize is just one step.

A typical flow looks like:

  • Build container image

  • Push to Artifact Registry

  • Update image tag in overlay

  • Run kustomize build

  • Apply to cluster

The key advantage is that you always deploy fully resolved manifests. There is no hidden templating logic at runtime. What you see in Git is what goes to the cluster.

This makes:

  • Rollbacks easier

  • Reviews safer

  • Debugging simpler

Kustomize in a platform and IDP model

This is where Kustomize really shines for platform engineering.

Service golden paths often use Kustomize because:

  • The base encodes platform standards

  • The overlays encode team-specific choices

  • Policy engines can validate the final output

  • Platform teams can enforce structure without blocking autonomy

It fits perfectly with an IDP model where:

  • The platform defines the paved road

  • Teams stay within guardrails

  • Everything remains Git-native

When Kustomize is not enough

There is a point where Kustomize starts to feel limited.

This usually happens when:

  • You need cross-service orchestration

  • You manage hundreds of environments

  • You need dynamic infrastructure composition

At that point, you start looking at:

  • GitOps controllers

  • Crossplane

  • Terraform + Helm

  • Higher-level abstractions

But that’s a maturity problem. Most teams are not there, and they shouldn’t pretend they are.

Why I still use Kustomize

I still use Kustomize because it keeps Kubernetes boring.

It doesn’t introduce:

  • New runtimes

  • New control planes

  • New mental models

It simply enforces good structure and makes environment differences explicit.

For most GKE teams, that’s exactly what you want:
predictable deployments, transparent configuration, and just enough abstraction to stay sane.

Not magic. Just good engineering.

Buoyant Cloud Inc
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.