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.
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 chartsParameter 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‑directoriesStep 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.txtEdit 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: 5Key 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.yamlStep 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
EOFCreate 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: 5Create Service baseline :
# base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: app
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: myappBaseline Validation :
kubectl kustomize . | grep -E "kind:|name:|replicas:"
# Output should include Deployment (replicas:1), Service, ConfigMapStep 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
EOFProd 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
EOFRender 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 definitionStep 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
EOFParameter 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 ServiceStep 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 fieldsResource 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: 200Production 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=myappStep 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: 3mManual 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: /metricsCore 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_unavailableLinux 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 minutesOptimization 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-priorityNode‑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: prodSensitive 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.yamlAudit & 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 URLCommon 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:
- originAnnotationsAnsible 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_modeTesting Environment
Tested on: 2025‑10, Kubernetes 1.30, Helm 3.14, Kustomize 5.3
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
