Kustomize uses a mechanism to automatically update Kubernetes Deployments, StatefulSets, and DaemonSets whenever a Secret or ConfigMap referenced by those workloads changes. This is achieved by injecting a hash of the Secret/ConfigMap’s data into an environment variable within the Pod spec. When the Secret/ConfigMap is updated, its hash changes, which in turn changes the Pod spec, triggering a rolling update of the Deployment.
Here’s how to set it up and understand it:
The Core Idea: A Phantom Environment Variable
Kustomize can be instructed to add a specific environment variable to your Pods. The value of this environment variable isn’t static; it’s dynamically generated as a hash of the contents of a specified Secret or ConfigMap.
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- my-secret.yaml # The secret we want to track
patchesStrategicMerge:
- patch-deployment.yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
ports:
- containerPort: 80
# my-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-app-secret
type: Opaque
data:
# Base64 encoded data
API_KEY: c29tZS1zZWNyZXQtdmFsdWUgMQ==
Now, the crucial part is the patch that tells Kustomize to add the hashed environment variable.
# patch-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
env:
- name: SECRET_HASH
valueFrom:
configMapKeyRef:
name: my-app-secret # This is the name of your Secret
key: __data # This is a special key Kustomize uses for the hash
What __data Means
The __data key in configMapKeyRef (or secretKeyRef if you were referencing a Secret directly, though configMapKeyRef is more common for this pattern) is a Kustomize convention. When Kustomize sees this, it doesn’t look for a literal key named __data in your Secret. Instead, it takes all the data within the specified Secret (in this case, my-app-secret), calculates a SHA256 hash of that combined data, and injects that hash as the SECRET_HASH environment variable’s value.
How it Works in Practice
-
Initial Deployment: When you first apply
kustomize build . | kubectl apply -f -, Kustomize processesmy-secret.yamlanddeployment.yamlalong with the patch. It calculates the hash ofmy-app-secret’s data ({"API_KEY": "c29tZS1zZWNyZXQtdmFsdWUgMQ=="}). Let’s say this hash isa1b2c3d4e5f6.... Themy-appDeployment is created with a Pod template that includesenv: [{name: SECRET_HASH, value: "a1b2c3d4e5f6..."}]. -
Secret Update: You modify
my-app-secret. For example, you updateAPI_KEYtoc29tZS1zZWNyZXQtdmFsdWUgMg==. -
Re-application: You run
kustomize build . | kubectl apply -f -again. Kustomize re-readsmy-secret.yaml, calculates the new hash of the updated secret data. This new hash will be different, e.g.,f6e5d4c3b2a1.... -
Pod Spec Change: Kustomize applies the patch to the Deployment’s Pod template. The
SECRET_HASHenvironment variable’s value is updated to the new hash. Because the Pod template has changed (even if only an environment variable’s value changed), Kubernetes sees this as a change to the Deployment’sspec.template. -
Rolling Update: Kubernetes initiates a rolling update for the
my-appDeployment. New Pods are created with the updatedSECRET_HASHenvironment variable, and old Pods are terminated. The application inside the Pods can then read thisSECRET_HASHvariable to determine if it needs to re-fetch configuration or secrets from the API server.
Important Considerations:
-
Secret vs. ConfigMap: While the example uses a Secret, this pattern works identically for ConfigMaps. The
valueFrom.configMapKeyRefpoints to the ConfigMap whose data will be hashed. -
Single Hash: Kustomize generates one hash for all data within the specified Secret or ConfigMap. If you have multiple keys in a Secret and only want to trigger an update based on one, this direct approach won’t work. You’d need a more complex patching strategy or a dedicated tool.
-
"Phantom" Key: The
__datakey is purely a Kustomize construct for this hashing mechanism. It does not exist as a literal key in your Secret or ConfigMap. -
Application Logic: Your application must be designed to use this
SECRET_HASHenvironment variable. The typical pattern is for the application to periodically check the value ofSECRET_HASH. If it’s different from the last known value, the application re-reads the actual Secret/ConfigMap from the Kubernetes API. -
Alternative (
configMapRef/secretRefinenv): You can directly reference a Secret or ConfigMap key into an environment variable like this:# Alternative, but doesn't provide a hash for updates env: - name: MY_API_KEY valueFrom: secretKeyRef: name: my-app-secret key: API_KEYThis injects the value directly. If the secret changes, the value in the Pod will not update automatically. This is why the hashing method is crucial for forcing restarts.
This Kustomize feature is a powerful, declarative way to manage the lifecycle of secrets and configuration that your applications depend on, ensuring they always run with the latest available data without manual intervention.