cswork / libraryOpen practice workspace

Articles

Kustomize Interview Questions: Overlays, Patch Order, and Generated ConfigMaps

Practice Kustomize interview questions with tested overlays, patch ordering, generated ConfigMap references, replacements, and rendered-output checks.

Kustomize interview questions become easier when you stop guessing from filenames and inspect the rendered resources. A production overlay can build successfully while retaining the wrong replica count. A generated ConfigMap can receive a new name while an unrelated command argument keeps an old Service name.

This guide uses an original inventory-service fixture to trace those differences. Official Kubernetes and Kustomize documentation supports the behavior contracts; the output tables report local rendering with standalone Kustomize v5.7.1 and kubectl v1.34.0, whose embedded Kustomize reports v5.7.1. No cluster was contacted. The prompts are preparation exercises, not reported employer questions. Pair them with Design Safe Configuration and Deployment for Hundreds of Services to practice explaining the deployment implications.

What Does an Overlay Actually Change?

An overlay selects resources and applies its configured transformations. A directory called prod has no special deployment authority. The command must target that directory, and its kustomization must express the desired differences.

Our base contains a Deployment named inventory, a Service with the same name, and an inventory-config generator. The Deployment starts with one replica. Its container references the ConfigMap through envFrom.configMapRef.name and has arguments ['--service', 'inventory'].

The development overlay adds dev- to names. The production overlay adds prod- and applies two patches to replicas. This makes name transformation, patch ordering, and reference handling visible in one small example.

The official Kubernetes guide introduces bases, overlays, generators, and transformations. Our fixture uses those features together; it does not imply that rendering deploys anything or verifies application health.

Set Up the Inventory Fixture

Use this directory structure:

base/
  kustomization.yaml
  deployment.yaml
  service.yaml
overlays/
  dev/kustomization.yaml
  prod/kustomization.yaml

The base kustomization selects two resources and generates one ConfigMap:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: inventory-config
  literals:
  - MODE=standard

The relevant Deployment is deliberately small:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: inventory
spec:
  replicas: 1
  selector:
    matchLabels:
      app: inventory
  template:
    metadata:
      labels:
        app: inventory
    spec:
      containers:
      - name: app
        image: example.invalid/inventory:1.0
        args: ["--service", "inventory"]
        envFrom:
        - configMapRef:
            name: inventory-config

The image is an explicit placeholder for a render-only exercise. It cannot establish that a real workload will start. The Service uses app: inventory as its selector, exposes port 80, and targets port 8080:

apiVersion: v1
kind: Service
metadata:
  name: inventory
spec:
  selector:
    app: inventory
  ports:
  - port: 80
    targetPort: 8080

The development kustomization has the same API version and kind as the base, followed by resources: [../../base] and namePrefix: dev-. Build that exact path and inspect the Deployment name, replica count, Service selector, and ConfigMap reference together.

kustomize version
kubectl version --client -o json
kustomize build overlays/dev > dev.yaml
kustomize build overlays/prod > prod.yaml

Recording both versions matters when switching command entry points. kubectl kustomize uses the implementation bundled into that kubectl release; an independently installed binary may differ. In this experiment they reported the same Kustomize version, and the checked final fields matched.

Which Patch Wins When Both Change Replicas?

Here is the initial production overlay:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: [../../base]
namePrefix: prod-
patches:
- target:
    kind: Deployment
    name: inventory
  patch: |-
    - op: replace
      path: /spec/replicas
      value: 2
- target:
    kind: Deployment
    name: inventory
  patch: |-
    - op: replace
      path: /spec/replicas
      value: 3

The Kustomize patches reference specifies ordered application. Our first render produced three replicas. Reversing these two entries produced two. The relevant order is the list under patches, not alphabetical order of filenames.

That result is easy to explain because both operations replace the same existing scalar. Do not extend “last value wins” into a universal explanation for all patch operations. A removal, a failed path lookup, or a list merge needs different reasoning.

Before rendering, predict the resource selected and the value after each operation. Then compare the final field. If the prediction is wrong, reduce the overlay to the smallest conflicting transformations rather than adding another patch to compensate blindly.

Local renderDeploymentReplicasInterpretation
Developmentdev-inventory1Base count preserved.
Production, patch 2 then 3prod-inventory3Second replacement determines final count.
Production, patch 3 then 2prod-inventory2Reversing order changes the result.
Second target misspelledprod-inventory2Intended second change did not apply.

For an actual repository, simplify contradictory patches when possible. The two competing replacements are intentional teaching material, not a recommendation for production configuration style.

Does a Wrong Patch Target Always Fail?

No. In the fixture, changing only the second target name from inventory to typo still produced a successful render. The first patch applied, leaving two replicas. The missing intended change was visible in output, not in a failing exit code.

This observation concerns an explicit target on a JSON patch in the tested version. Other patch forms and invalid paths can fail differently. Avoid claiming that every unmatched patch is silently ignored, or that every typo must produce an error.

Use a positive assertion: exactly one expected Deployment has three replicas. That is stronger than “the command exited zero.” Also check that no unintended Deployment changed if a target uses a broad selector.

Targets can include resource identity and label or annotation selectors. The reference documents name matching as an anchored regular expression. That is another reason to use deliberate selectors and inspect the match set instead of assuming a name fragment means a literal substring search.

For custom resources, strategic merge behavior depends on available schema information. Do not assume every list merges by an element's name. A JSON patch can express a precise operation, but a numeric list index can become fragile when earlier changes reorder elements. Choose the patch form for the actual structure and verify the resulting object.

Why Did the ConfigMap Name Change?

Now restore the original patch order and change the generator literal from MODE=standard to MODE=fast. The local render changed the generated ConfigMap name and the Deployment's recognized reference together:

Before:
  ConfigMap: prod-inventory-config-hf4k82fgk7
  reference: prod-inventory-config-hf4k82fgk7
  MODE: standard

After:
  ConfigMap: prod-inventory-config-7kcm455446
  reference: prod-inventory-config-7kcm455446
  MODE: fast

These suffixes are observed values from this fixture, not strings to memorize or hard-code. The useful invariant is that the rendered reference equals the generated resource name, and that the changed content is present in the generated data.

The diagram uses simplified names to make the relationship readable. The concrete output above shows the real suffixes. In our fixture, both initial overlays shared the same content suffix even though their prefixes differed.

Disabling the suffix through generator options changes this naming behavior. It does not automatically supply an alternative application reload or rollout mechanism. Ask how consumers observe changed configuration before treating a stable name as a harmless cosmetic preference.

Rendering also does not remove previously deployed ConfigMaps. Retention, pruning, rollout, and rollback depend on the delivery workflow. This exercise stops at the generated desired state, so it cannot establish which old objects remain in a cluster.

Why Does the Service Argument Stay Wrong?

The Service name became prod-inventory, but the container argument remained inventory. Kustomize recognized the ConfigMap reference field; it did not infer that an arbitrary string in args was a Service reference.

This is the difference between structured references and meaningful-looking text. A name prefix is not global string replacement across every scalar. The renderer cannot safely assume that every occurrence of inventory names the same resource.

Add a replacement to the production kustomization to copy the Service's name into the intended argument:

replacements:
- source:
    kind: Service
    name: inventory
    fieldPath: metadata.name
  targets:
  - select:
      kind: Deployment
      name: inventory
    fieldPaths:
    - spec.template.spec.containers.[name=app].args.1

The resulting argument was prod-inventory, matching the Service. The Kustomize implementation makes the source-and-target nature of replacements explicit. The practical contract here is narrower: copy this resource field into this known argument location.

The container selector uses its name, while the argument still uses index 1. If the command-line layout changes, revisit that target. A passing render today does not protect an index from a future insertion at the beginning of the array.

Do not treat replacements as arbitrary shell expansion or assume they rewrite every embedded identifier in a custom document. Identify the exact scalar, define its source, and assert the final equality after all relevant transformations.

What Should You Check in the Rendered Diff?

Start with resource identity: kind, name, and namespace. Then check selectors, references, replicas, image values, and the configuration fields that prompted the change. A diff that changes only formatting can distract from a single wrong reference.

For this fixture, the assertions were concrete: dev has one replica; production has three; reversing patches produces two; the typo variant also produces two; generated name equals reference; changing MODE changes both; replacement makes the argument equal the Service name.

We also rendered the repaired overlay with kubectl kustomize and compared those fields against standalone output. That is evidence for this version pair and fixture, not proof of universal equivalence between all kubectl and Kustomize releases.

A stronger repository check can parse YAML documents and assert selected fields rather than searching raw text. Count matches so that a check cannot accidentally pass by finding the expected value in an unrelated object. Retain the full render for review, even when automated checks summarize only important invariants.

Successful YAML generation remains an earlier gate than API acceptance, admission policy, scheduling, image availability, readiness, or correct business behavior. Our placeholder image makes that boundary unmistakable. A deployment-oriented interview answer should name the next verification step without pretending the render already completed it.

Does secretGenerator Encrypt a Secret?

No. Generating a Kubernetes Secret is not equivalent to encrypting source files or making them safe to commit. The official Secret documentation explains the distinction between encoded data and protection such as encryption at rest and access control.

Use fake values in a practice exercise. In a real workflow, assess source storage, repository access, build logs, rendered artifacts, and cluster permissions separately. This article's ConfigMap example contains only a harmless mode value; it does not demonstrate secure secret delivery.

Practice Explaining the Change

A strong explanation ties each observation to one mechanism: “The later scalar patch set replicas to three. The misspelled target selected nothing in this variant. The generator updated a recognized reference, while the arbitrary argument required an explicit replacement.”

QuestionPractice focus
Design Safe Configuration and Deployment for Hundreds of ServicesSeparate configuration changes from rollout guarantees.
Design first-time Kubernetes deployment in new cloudIdentify checks after rendering.
Explain CI/CD, Kubernetes delivery, and troubleshootingPreserve evidence across delivery stages.
Debug Kubernetes crashes and review Python ingestion scriptDistinguish configuration from runtime failure.
Implement Kubernetes Service Dependency QueriesTrace identities and relationships precisely.

Return to the configuration-and-deployment design exercise and explain which rendered invariants you would require before a change could proceed to deployment verification.

Sources and Further Reading