Kubernetes Manifest Generator
Generate production-ready Kubernetes YAML manifests following best practices.
When to Use
- •Creating new Kubernetes resources (Deployment, Service, ConfigMap, etc.)
- •Converting application requirements to K8s manifests
- •Generating CRD instances (Karpenter NodePool, Kyverno Policy, etc.)
Core Rules
1. Pin Image Version
Never use latest tag. Always pin specific version (e.g., nginx:1.25.3).
2. Set Resource Requests and Limits
Every container must have resource requests. Set memory limits but avoid CPU limits (causes throttling).
Bad Case - With CPU Limit
spec:
containers:
- name: app
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "100m" # CPU limit set - causes throttling
memory: "128Mi"
- •CPU limit causes CFS throttling during burst traffic
- •Results in latency spikes and response delays
Good Case - Without CPU Limit
spec:
containers:
- name: app
resources:
requests:
cpu: "100m" # Request only for scheduling guarantee
memory: "128Mi"
limits:
memory: "128Mi" # Memory limit retained (OOM protection)
# CPU limit intentionally omitted
- •CPU request guarantees minimum resources
- •Can utilize idle CPU during burst
- •Stable latency without throttling
3. Run as Non-Root
Set securityContext.runAsNonRoot: true and allowPrivilegeEscalation: false.
4. Define Probes
Add liveness and readiness probes for all Deployments.
5. Use Standard Labels
Include app.kubernetes.io/* labels for all resources.
Generation Guidelines
Required Fields
Always include these fields for production readiness:
metadata:
name: <resource-name>
namespace: <namespace>
labels:
app.kubernetes.io/name: <app-name>
app.kubernetes.io/instance: <instance>
app.kubernetes.io/version: <version>
app.kubernetes.io/component: <component>
app.kubernetes.io/managed-by: <tool>
Deployment Best Practices
spec:
replicas: 2 # Minimum for HA
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
spec:
containers:
- name: <container-name>
image: <image>:<tag> # Always use specific tag, never 'latest'
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
memory: "512Mi" # No CPU limit to avoid throttling
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
Security Requirements
- •Always set
securityContextat pod and container level - •Use
readOnlyRootFilesystem: truewhen possible - •Set
runAsNonRoot: trueunless absolutely necessary - •Never use
privileged: truewithout justification - •Always specify resource requests and memory limits (avoid CPU limits)
Pod Disruption Budget
For production workloads, always create PDB:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: <app>-pdb
spec:
minAvailable: 1 # or maxUnavailable: 1
selector:
matchLabels:
app: <app>
EKS Best Practices
DNS Optimization (ndots)
Default ndots (5) causes unnecessary CoreDNS queries for external domains. Set ndots: 2 to reduce DNS lookup latency for external services (S3, RDS, etc.).
spec:
dnsConfig:
options:
- name: ndots
value: "2"
- name: edns0
Warning: Test thoroughly. Setting ndots too low may cause DNS lookup failures. Alternative: use trailing dot for external domains (e.g., api.example.com.).
Topology Spread Constraints
Spread pods across AZs and nodes for high availability:
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: <app-name>
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: <app-name>
Use DoNotSchedule only if it's preferable for pods to not run instead of violating the constraint.
Pod Anti-Affinity
Alternative to topology spread for distributing replicas:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- <app-name>
topologyKey: topology.kubernetes.io/zone
Graceful Shutdown
Default grace period is 30 seconds. Increase for long-running requests and add preStop hook for connection draining:
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"]
Startup Probe
For slow-starting applications (e.g., Java apps hydrating caches):
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 2
Node Selection for Karpenter
Use nodeSelector or affinity for Karpenter NodePools:
spec:
nodeSelector:
karpenter.sh/nodepool: default
Service Account
Create dedicated ServiceAccount for each application:
apiVersion: v1 kind: ServiceAccount metadata: name: <app>-sa automountServiceAccountToken: false # Set true only if needed
Leaving Room for Imperativeness
When using GitOps (e.g., ArgoCD), not every field should be tracked in Git. If a controller (HPA, VPA, KEDA) manages a field, omit it from the manifest to avoid conflicts.
Replicas Managed by HPA
If replicas is defined in both the manifest and an HPA, ArgoCD and HPA will fight over the value. Omit replicas from the Deployment when HPA controls scaling.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
# Do not include replicas if controlled by HPA
# replicas: 2
template:
spec:
containers:
- name: nginx
image: nginx:1.25.3
ports:
- containerPort: 80
Common Fields to Omit
| Field | Omit When Managed By |
|---|---|
spec.replicas | HPA, KEDA, Rollout controller |
resources.requests/limits | VPA |
metadata.annotations | External controllers (e.g., cert-manager) |
ArgoCD ignoreDifferences
If a field must exist in the manifest but is also managed externally, configure ArgoCD to ignore diffs:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
Output Format
- •Use
---to separate multiple resources - •Order: Namespace > ServiceAccount > ConfigMap/Secret > Deployment/StatefulSet > Service > Ingress
- •Add comments for non-obvious configurations
Validation Checklist
After generation, verify:
- • All required labels present
- • Resource requests/limits defined
- • Probes configured
- • Security context set
- • No hardcoded secrets (use Secret or external-secrets)