Cloud Native 35 min read

Zero‑Config Drift: Deploy Enterprise Kubernetes with Helm + Kustomize in 10 Minutes

This guide walks you through an enterprise‑grade Kubernetes deployment strategy that combines Helm and Kustomize to achieve zero configuration drift, support three or more environments, enforce standardized policies, and enable multi‑environment releases in under ten minutes.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Zero‑Config Drift: Deploy Enterprise Kubernetes with Helm + Kustomize in 10 Minutes

Enterprise Kubernetes Deployment: Helm + Kustomize Hybrid Strategy for Zero Config Drift and 10‑Minute Multi‑Environment Release

Applicable Scenarios & Prerequisites

Applicable Scenarios :

Need to manage a micro‑service architecture across three or more environments (dev / staging / prod).

Require standardized configuration, controllable differences, and traceable changes.

Team size of 5+ developers who need a unified deployment specification.

Prerequisites :

Kubernetes 1.24+ cluster with multi‑namespace isolation.

Helm 3.10+ and Kustomize 5.0+ (built into kubectl 1.27+).

Git repository with branch strategy and PR approval.

Cluster RBAC enabled with at least namespace-admin permission.

Environment and Version Matrix

Component

Version Requirement

Key Feature Dependencies

Minimum Resource Specs

Kubernetes

1.24~1.30

PodSecurity admission, enhanced field validation

3 nodes (4C8G)

Helm

3.10+

values schema validation, chart dependency lock

-

Kustomize

5.0+

replacements, HelmChartInflationGenerator

-

kubectl

1.27+

built‑in Kustomize 5.x, server‑side apply

-

Git

2.30+

branch protection, CODEOWNERS, signed commits

-

OS

RHEL 8+ / Ubuntu 22.04+

-

-

Quick Checklist

Step 1: Initialize Git repository structure (base/overlays/charts).

Step 2: Create minimal Helm chart set.

Step 3: Configure Kustomize base layer.

Step 4: Create multi‑environment overlays (dev/staging/prod).

Step 5: Integrate Helm + Kustomize (core capability).

Step 6: Dry‑run validation and diff comparison.

Step 7: Canary release and health checks.

Step 8: GitOps sync and automatic rollback.

Implementation Steps

Step 1: Initialize Standardized Repository Structure

Goal : Create a GitOps repository skeleton that follows enterprise standards.

# RHEL/CentOS/Ubuntu common
mkdir -p k8s-manifests/{base,overlays/{dev,staging,prod},charts}
cd k8s-manifests

# Initialize Git and protect main branch
git init
git checkout -b main
cat <<EOF > .gitignore
*.swp
.DS_Store
secrets/
EOF

# Directory layout
tree -L 3
# ├── base/               # Common baseline resources
# ├── overlays/
# │   ├── dev/            # Development environment differences
# │   ├── staging/        # Staging environment differences
# │   └── prod/           # Production environment differences
# └── charts/             # Custom Helm charts

Parameter Explanation : base/: Stores environment‑agnostic resources (Deployment/Service/ConfigMap templates). overlays/: Holds per‑environment overrides (replica count, resource limits, image tags, env vars). charts/: Local cache of custom or third‑party Helm charts for offline deployment and version locking.

Verification :

ls -R | grep -E "base|overlays|charts"
# Output should show three top‑level directories and their sub‑directories

Step 2: Create Minimal Helm Chart Set

Goal : Package generic micro‑service deployment logic with parameterized values.

# In charts/ create a standard chart
cd charts
helm create app-template

# Trim the chart (remove example files, keep core templates)
cd app-template
rm -rf templates/tests templates/NOTES.txt

Edit values.yaml (key parameters) :

# charts/app-template/values.yaml
replicaCount: 1

image:
  repository: nginx
  tag: "1.25.3"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi

livenessProbe:
  httpGet:
    path: /health
    port: 80
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 5

Key Parameters : image.tag: Explicit version to avoid latest drift. resources: Production should set limits ≥ 2× requests. probe.initialDelaySeconds: Adjust according to application start‑up time (e.g., Java ≥ 60 s).

Render Test :

helm template my-app . --values values.yaml > /tmp/rendered.yaml
grep -E "replicas|image:|cpu:|memory:" /tmp/rendered.yaml
# Verify that the output contains the values defined in values.yaml

Step 3: Configure Kustomize Base Layer

Goal : Define environment‑agnostic resource baseline.

cd ../../base
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: default

commonLabels:
  app.kubernetes.io/managed-by: kustomize

resources:
  - deployment.yaml
  - service.yaml

configMapGenerator:
  - name: app-config
    literals:
      - LOG_LEVEL=info
      - TIMEZONE=Asia/Shanghai
EOF

Create Deployment baseline :

# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: app
          image: nginx:1.25.3
          ports:
            - containerPort: 80
          envFrom:
            - configMapRef:
                name: app-config
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 30
          readinessProbe:
            httpGet:
              path: /ready
              port: 80
            initialDelaySeconds: 5

Create Service baseline :

# base/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: myapp

Baseline Validation :

kubectl kustomize . | grep -E "kind:|name:|replicas:"
# Output should include Deployment (replicas:1), Service, ConfigMap

Step 4: Create Multi‑Environment Overlays

Goal : Provide per‑environment customizations (replica count, image tag, resources).

Dev Environment (minimal resources)

cd ../overlays/dev
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: dev

bases:
  - ../../base

patchesStrategicMerge:
  - replica-patch.yaml
  - resource-patch.yaml

images:
  - name: nginx
    newTag: 1.25.3-dev
EOF

cat <<EOF > replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1
EOF

cat <<EOF > resource-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 256Mi
EOF

Prod Environment (high‑availability + HPA)

cd ../prod
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: prod

bases:
  - ../../base

patchesStrategicMerge:
  - replica-patch.yaml

images:
  - name: nginx
    newTag: 1.25.3

resources:
  - hpa.yaml
EOF

cat <<EOF > replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 3
EOF

cat <<EOF > hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
EOF

Render Comparison :

# Dev environment
kubectl kustomize ../dev | grep -A2 "replicas:"
# Expected: replicas: 1, cpu: 50m

# Prod environment
kubectl kustomize . | grep -A2 "replicas:"
# Expected: replicas: 3, cpu: 100m, plus HPA definition

Step 5: Integrate Helm + Kustomize (Core Capability)

Goal : Use Kustomize HelmChart generator to manage third‑party charts.

cd ../staging
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: staging

helmCharts:
  - name: redis
    repo: https://charts.bitnami.com/bitnami
    version: 18.1.0
    releaseName: redis
    namespace: staging
    valuesInline:
      auth:
        enabled: true
        password: "StagingRedisPass123"
      master:
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 200m
            memory: 256Mi
      replica:
        replicaCount: 2

bases:
  - ../../base

patchesStrategicMerge:
  - env-patch.yaml
EOF

cat <<EOF > env-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          env:
            - name: REDIS_HOST
              value: redis-master.staging.svc.cluster.local
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: redis
                  key: redis-password
EOF

Parameter Explanation : helmCharts.repo: Must be an HTTPS URL; supports private repos with authentication. valuesInline: Embeds values directly to avoid separate files. releaseName: Helm release name, used for helm list queries.

Render Helm Chart (requires kubectl 1.27+ or kustomize with helm plugin) :

# Method 1: kubectl built‑in kustomize
kubectl kustomize . --enable-helm > /tmp/staging-with-helm.yaml

# Method 2: kustomize CLI with helm plugin
kustomize build . --enable-helm > /tmp/staging-with-helm.yaml

# Verify Redis resources are generated
grep -E "kind: StatefulSet|name: redis" /tmp/staging-with-helm.yaml
# Should output Redis StatefulSet and Service

Step 6: Dry‑Run Validation & Diff Comparison

Goal : Detect configuration errors and resource conflicts before applying.

# Production dry‑run (server‑side validation)
kubectl apply -k overlays/prod --dry-run=server --validate=true

# Example output
# deployment.apps/app created (dry run)
# service/app unchanged (dry run)
# horizontalpodautoscaler.autoscaling/app-hpa created (dry run)

# Diff against current cluster (requires kubectl‑diff or kubediff)
kubectl diff -k overlays/prod
# Shows git‑like diff of added/removed/changed fields

Resource Quota Check :

# Check namespace ResourceQuota
kubectl get resourcequota -n prod

# Calculate total requests of new configuration
kubectl kustomize overlays/prod | \
  yq eval 'select(.kind == "Deployment") | .spec.template.spec.containers[].resources.requests' - | \
  awk '/cpu:/ {cpu+=$2} /memory:/ {mem+=$2} END {print "Total CPU:", cpu "m", "Memory:", mem "Mi"}'

Step 7: Canary Release & Health Checks

Goal : Gradually replace Pods, ensure new version is stable before full rollout.

# Apply staging (includes Helm chart)
kubectl apply -k overlays/staging --server-side --force-conflicts

# Monitor rollout progress
kubectl rollout status deployment/app -n staging --timeout=5m

# Verify new Pods are ready
kubectl get pods -n staging -l app=myapp -o wide
kubectl logs -n staging -l app=myapp --tail=50 | grep -E "ERROR|WARN"

# Simple health check via curl
POD_IP=$(kubectl get pod -n staging -l app=myapp -o jsonpath='{.items[0].status.podIP}')
kubectl run curl-test --image=curlimages/curl -it --restart=Never -- \
  curl -s http://$POD_IP/health -w "
HTTP_CODE: %{http_code}
"
# Expected output: HTTP_CODE: 200

Production Gradual Rollout (zero‑downtime):

# Add rollout strategy patch
cd overlays/prod
cat <<EOF > rollout-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
EOF

yq eval '.patchesStrategicMerge += ["rollout-patch.yaml"]' -i kustomization.yaml

# Apply to production
kubectl apply -k . --server-side

# Watch pod replacement
watch kubectl get pods -n prod -l app=myapp

Step 8: GitOps Automatic Sync & Rollback

Goal : Integrate ArgoCD for Git‑as‑configuration (example only, not executed).

# argocd-application.yaml (example)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/k8s-manifests.git
    targetRevision: main
    path: overlays/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

Manual Rollback to Previous Version :

# View Deployment revision history
kubectl rollout history deployment/app -n prod

# Example output
# REVISION  CHANGE-CAUSE
# 1         Initial deployment
# 2         Update to v1.25.3
# 3         Scale to 5 replicas

# Roll back to Revision 2
kubectl rollout undo deployment/app -n prod --to-revision=2

# Verify rollback
kubectl rollout status deployment/app -n prod
kubectl describe deployment/app -n prod | grep Image:

Monitoring & Alerting

Prometheus Key Metrics

# ServiceMonitor (requires Prometheus Operator)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: app-metrics
  namespace: prod
spec:
  selector:
    matchLabels:
      app: myapp
  endpoints:
    - port: metrics
      interval: 30s
      path: /metrics

Core PromQL Queries :

# Pod availability (target >99.9%)
sum(kube_deployment_status_replicas_available{deployment="app", namespace="prod"}) /
sum(kube_deployment_spec_replicas{deployment="app", namespace="prod"}) * 100

# Container restarts (alert if >3 in last hour)
rate(kube_pod_container_status_restarts_total{namespace="prod", pod=~"app-.*"}[1h]) > 3

# Rolling update duration (target <5 min)
time() - kube_deployment_status_observed_generation{deployment="app"} *
  on(deployment) group_left kube_deployment_spec_strategy_rollingupdate_max_unavailable

Linux Native Monitoring Commands

# View actual pod resource usage
kubectl top pods -n prod -l app=myapp --containers

# Continuous pod event watch (restart / scheduling failures)
kubectl get events -n prod --field-selector involvedObject.name=app --watch

# Verify service endpoints
kubectl get endpoints -n prod app -o yaml | grep -A5 addresses:

Performance & Capacity

Benchmark Commands

# Use wrk to test application throughput
kubectl run wrk-bench --image=williamyeh/wrk --rm -it --restart=Never \
  -t4 -c100 -d30s --latency http://app.prod.svc.cluster.local/api/test

# Expected output
# Requests/sec:  5000+
# Latency (P99): <50ms

# Measure deployment speed
time kubectl apply -k overlays/prod --server-side
# Goal: complete full update of 100+ Pods within 10 minutes

Optimization Parameters

Kubernetes‑level :

spec:
  progressDeadlineSeconds: 600   # 10‑minute timeout
  revisionHistoryLimit: 5        # Keep 5 revisions
  strategy:
    rollingUpdate:
      maxSurge: 25%              # Production: 1‑2 extra pods
      maxUnavailable: 0         # Zero downtime
  template:
    spec:
      terminationGracePeriodSeconds: 30
      priorityClassName: high-priority

Node‑level (system) :

# Increase file descriptor limits (RHEL/CentOS)
cat <<EOF > /etc/sysctl.d/k8s-perf.conf
fs.file-max = 2097152
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 8192
EOF
sysctl -p /etc/sysctl.d/k8s-perf.conf

# Ubuntu/Debian: same settings in /etc/sysctl.d/

Capacity Planning Formula :

# Node CPU total = (Pod count × requests.cpu) / usable_rate(0.7‑0.8)
# Node memory total = (Pod count × requests.memory) / usable_rate(0.7‑0.8) + system reserve (2‑4 GB)

Security & Compliance

RBAC Minimal Permissions

# ServiceAccount for deployment
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deployer
  namespace: prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-deployer
  namespace: prod
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get","list","patch","update"]
  - apiGroups: [""]
    resources: ["services","configmaps"]
    verbs: ["get","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployer-binding
  namespace: prod
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: app-deployer
subjects:
  - kind: ServiceAccount
    name: deployer
    namespace: prod

Sensitive Information Management

# Use Sealed Secrets to store encrypted secrets in Git
kubectl create secret generic redis-auth \
  --from-literal=password=Prod_Redis_Pass_2024 \
  --dry-run=client -o yaml | \
  kubeseal --controller-namespace=kube-system \
  --controller-name=sealed-secrets --format yaml > overlays/prod/redis-secret-sealed.yaml

# Verify encrypted data is present
grep "encryptedData:" overlays/prod/redis-secret-sealed.yaml

Audit & Traceability

# Enable Kustomize build metadata for origin tracking
cd overlays/prod
kustomize edit add buildmetadata originAnnotations

# Verify generated resources contain Git info
kubectl kustomize . | grep -E "config.kubernetes.io/origin"
# Example output shows path and repo URL

Common Issues & Troubleshooting

Symptom

Diagnostic Command

Possible Root Cause

Quick Fix

Permanent Fix kubectl apply -k fails kubectl kustomize . | kubectl apply --dry-run=server -f - YAML syntax error or resource conflict

Run kubectl kustomize . | yq to inspect format

Integrate yamllint + kubeval in CI pipeline

Helm chart not rendered kubectl kustomize . --enable-helm kubectl version < 1.27 or missing plugin

Upgrade kubectl or install kustomize 5.x with helm plugin

Declare --enable-helm explicitly in kustomization.yaml Image pull failure kubectl describe pod <pod> -n <ns> | grep -A5 Events Tag does not exist or private registry auth failure

Rollback to previous version

Configure ImagePullSecrets and verify image existence

Pod stuck in Pending

kubectl get events --field-selector involvedObject.name=<pod>

Insufficient resources or overly strict node affinity

Scale nodes or lower resource requests

Set ResourceQuota and LimitRange to prevent over‑commit

ConfigMap changes not applied kubectl rollout restart deployment/<name> -n <ns> ConfigMap mounted via subPath does not support hot reload

Manually restart pods

Use envFrom or a reloader sidecar for automatic restarts

Rolling update hangs kubectl rollout status deploy/<name> --timeout=0 Readiness probe failure in new pods

Check endpoint and timeout settings

Adjust probe parameters or fix application start‑up logic

Change & Rollback Playbooks

Production Deployment Script (prod-deploy.sh)

#!/bin/bash
# prod-deploy.sh – Production release playbook
set -euo pipefail

NAMESPACE="prod"
OVERLAY_PATH="overlays/prod"
BACKUP_DIR="backups/$(date +%Y%m%d-%H%M%S)"

echo "==> 1. Backup current configuration"
mkdir -p "$BACKUP_DIR"
kubectl get all,cm,secret -n "$NAMESPACE" -o yaml > "$BACKUP_DIR/pre-deploy-snapshot.yaml"

echo "==> 2. Validate new configuration"
kubectl kustomize "$OVERLAY_PATH" --enable-helm | kubectl apply --dry-run=server -f -

echo "==> 3. Apply changes (canary: maxSurge=1, maxUnavailable=0)"
kubectl patch deployment app -n "$NAMESPACE" -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
kubectl apply -k "$OVERLAY_PATH" --server-side

echo "==> 4. Health check (wait 2 minutes)"
sleep 120
kubectl rollout status deployment/app -n "$NAMESPACE" --timeout=5m

echo "==> 5. Verify new pod logs for errors"
NEW_POD=$(kubectl get pod -n "$NAMESPACE" -l app=myapp --sort-by=.metadata.creationTimestamp | tail -1 | awk '{print $1}')
kubectl logs -n "$NAMESPACE" "$NEW_POD" --tail=100 | grep -i error && {
  echo "Error detected, triggering rollback"
  kubectl rollout undo deployment/app -n "$NAMESPACE"
  exit 1
}

echo "==> 6. Full rollout"
kubectl scale deployment/app -n "$NAMESPACE" --replicas=10

echo "==> Deployment completed, backup stored at $BACKUP_DIR"

Quick Rollback Script (rollback.sh)

#!/bin/bash
# rollback.sh – One‑click rollback to previous stable version
NAMESPACE="${1:-prod}"
DEPLOYMENT="${2:-app}"

echo "==> Rolling back $NAMESPACE/$DEPLOYMENT to previous revision"
kubectl rollout undo deployment/$DEPLOYMENT -n $NAMESPACE

echo "==> Waiting for rollback to finish"
kubectl rollout status deployment/$DEPLOYMENT -n $NAMESPACE --timeout=3m

echo "==> Verifying pod status after rollback"
kubectl get pods -n $NAMESPACE -l app=myapp
kubectl logs -n $NAMESPACE -l app=myapp --tail=50 | grep -i "started successfully"

echo "==> Rollback completed"

Best Practices (10 Decision Points)

Layered Configuration : Keep environment‑agnostic resources in base/; apply all environment‑specific values via overlays/. Never hard‑code env‑specific values in the base.

Image Version Locking : Prohibit latest or floating tags in production; use full SHA256 digest or semantic version (e.g., v1.2.3).

Resource Limits Enforcement : Every Deployment must declare requests and limits; set limits to 1.5‑2× requests.

Rolling Update Parameters : Production should use maxUnavailable=0 and maxSurge=1 (or 25 %); set progressDeadlineSeconds=600 to avoid stuck rollouts.

Health‑Check Tuning : Set readinessProbe.initialDelaySeconds to 1.2× actual start‑up time; keep livenessProbe independent of external services.

Helm Integration via Kustomize : Use helmCharts generator for third‑party components (Redis, MySQL, Kafka) to maintain a single source of truth.

GitOps Atomicity : One Git commit per change; include ticket ID and summary; sign commits to prevent tampering.

Environment Promotion Strategy : Promote code dev → staging → prod via Git branches or tags; require automated smoke & performance tests in staging and two‑person PR approval for production.

Secret Encryption : Store sensitive data with Sealed Secrets, External Secrets Operator, or Vault; never commit plain‑text Secrets.

Rollback Observation Window : After production deployment keep a 30‑minute monitoring window; watch error rate, P99 latency, and restart count; roll back immediately on anomalies.

Appendix: Full Configuration Sample

Production kustomization.yaml (complete example)

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: prod

# Reference baseline
bases:
  - ../../base

# Helm chart integration (Redis cluster)
helmCharts:
  - name: redis
    repo: https://charts.bitnami.com/bitnami
    version: 18.1.0
    releaseName: redis-ha
    namespace: prod
    valuesInline:
      auth:
        enabled: true
        existingSecret: redis-auth-sealed
      master:
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 2000m
            memory: 4Gi
      replica:
        replicaCount: 3
        resources:
          requests:
            cpu: 200m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 2Gi

# Image override (use SHA256 digest)
images:
  - name: nginx
    newName: myregistry.com/myapp
    newTag: sha256:abcd1234...

# Common labels
commonLabels:
  env: production
  team: platform
  cost-center: "12345"

# Common annotations
commonAnnotations:
  deployed-by: argocd
  git-commit: ${GIT_COMMIT}

# ConfigMap generator (additional config)
configMapGenerator:
  - name: app-config
    behavior: merge
    literals:
      - MAX_CONNECTIONS=1000
      - CACHE_TTL=3600

# Secret generator (Sealed Secret example)
secretGenerator:
  - name: app-secrets
    files:
      - secrets/database-creds.txt
      - secrets/api-keys.txt

# Resource patches
patchesStrategicMerge:
  - replica-patch.yaml
  - rollout-strategy-patch.yaml
  - monitoring-patch.yaml

# JSON6902 patch (example field modification)
patchesJson6902:
  - target:
      group: apps
      version: v1
      kind: Deployment
      name: app
    patch: |
      - op: replace
        path: /spec/template/spec/containers/0/resources/requests/cpu
        value: "1000m"

# Transformers (priority setting example)
transformers:
  - priority-transformer.yaml

# Build metadata for traceability
buildMetadata:
  - originAnnotations

Ansible Deployment Task Example

# ansible/deploy-k8s-app.yml
---
- name: Deploy application using Kustomize
  hosts: localhost
  gather_facts: no
  vars:
    overlay: "overlays/{{ env }}"
    namespace: "{{ env }}"
  tasks:
    - name: Validate kustomization
      command: kubectl kustomize {{ overlay }} --enable-helm
      register: kustomize_output
      changed_when: false
      check_mode: no

    - name: Dry‑run apply
      command: kubectl apply -k {{ overlay }} --dry-run=server --validate=true
      register: dryrun_result
      failed_when: "'error' in dryrun_result.stderr"

    - name: Backup current state
      shell: |
        kubectl get all,cm,secret -n {{ namespace }} -o yaml > backups/{{ namespace }}-$(date +%Y%m%d-%H%M%S).yaml
      args:
        creates: backups/{{ namespace }}

    - name: Apply kustomization
      command: kubectl apply -k {{ overlay }} --server-side
      when: not ansible_check_mode

    - name: Wait for rollout
      command: kubectl rollout status deployment/app -n {{ namespace }} --timeout=5m
      when: not ansible_check_mode

    - name: Verify deployment
      command: kubectl get pods -n {{ namespace }} -l app=myapp -o jsonpath='{.items[*].status.phase}'
      register: pod_status
      failed_when: "'Running' not in pod_status.stdout"
      when: not ansible_check_mode

Testing Environment

Tested on: 2025‑10, Kubernetes 1.30, Helm 3.14, Kustomize 5.3

Configuration diagram
Configuration diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ci/cdKubernetesGitOpsKustomizeMulti-EnvironmentZero-Config Drift
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.