Kustomize’s HPA patch is the secret weapon for tailoring autoscaling behavior across your different deployment environments.
Let’s watch Kustomize in action. Imagine you have a base Kubernetes HorizontalPodAutoscaler (HPA) definition that looks like this:
# base/hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app-deployment
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 50
This is your sensible default. Now, you want to deploy this application to a staging environment where you’re more aggressive with scaling because you have fewer users and want to ensure responsiveness. You also have a production environment where you want to be more conservative to manage costs.
Here’s how you’d use Kustomize patches to achieve this:
First, your kustomization.yaml for staging:
# overlays/staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesStrategicMerge:
- hpa-patch-staging.yaml
And the patch file overlays/staging/hpa-patch-staging.yaml:
# overlays/staging/hpa-patch-staging.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa # Must match the name in the base
spec:
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
Now, for production, you want to be more cautious:
# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesStrategicMerge:
- hpa-patch-production.yaml
And the production patch file overlays/production/hpa-patch-production.yaml:
# overlays/production/hpa-patch-production.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa # Must match the name in the base
spec:
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 40
When you run kustomize build overlays/staging, Kustomize takes the base/hpa.yaml and applies the hpa-patch-staging.yaml to it. The metadata.name in the patch must match the name of the resource you’re patching in the base. Kustomize’s strategic merge patch intelligently combines the two, overwriting or adding fields as specified. The result for staging would be an HPA with minReplicas: 2, maxReplicas: 10, and targetCPUUtilizationPercentage: 70.
Running kustomize build overlays/production would yield an HPA with minReplicas: 1, maxReplicas: 5, and targetCPUUtilizationPercentage: 40. This gives you fine-grained control over autoscaling parameters without duplicating your entire HPA definition for each environment.
The core problem this solves is avoiding configuration duplication. Without Kustomize patches, you’d likely have separate HPA files for staging and production, each with its own minReplicas, maxReplicas, and targetCPUUtilizationPercentage. This leads to maintenance headaches: if you need to change the scaleTargetRef or add a new autoscaling metric, you’d have to remember to update it in multiple files. Kustomize’s patching mechanism allows you to define a common base and then apply environment-specific overrides, dramatically simplifying your manifest management.
Internally, Kustomize uses strategic merge patch (or json merge patch depending on configuration and resource type) when using patchesStrategicMerge. For HPAs, it’s typically strategic merge. This means Kubernetes’ patcher understands the structure of the HPA resource and can intelligently merge fields. For example, if you only wanted to change maxReplicas in staging, you’d only include maxReplicas in your patch, and Kustomize would merge it with the base HPA, leaving minReplicas and targetCPUUtilizationPercentage as they were in the base.
The exact levers you control are the fields within the spec of the HorizontalPodAutoscaler resource. This includes minReplicas, maxReplicas, and targetCPUUtilizationPercentage for autoscaling/v1 HPAs. For autoscaling/v2beta2 or autoscaling/v2 HPAs, you can also patch behavior settings, which allows for much more nuanced control over scaling cooldowns and stabilization windows. You can also patch custom metrics or external metrics targets.
A common point of confusion is when using patchesJson6902. This type of patch uses JSON Pointers to specify exactly which parts of the YAML to add, remove, or replace. It’s more granular than strategic merge but can be more brittle if the underlying structure changes. For simple overrides of HPA spec fields, patchesStrategicMerge is generally preferred for its readability and robustness.
The next concept you’ll likely encounter is managing multiple patches for a single resource, or using Kustomize to conditionally apply patches based on environment variables.