Kubernetes Manifest Generator
Production-ready Kubernetes manifest templates for Deployments, Services, ConfigMaps, and Ingress. Copy and customize for your applications.
Description
A collection of production-ready Kubernetes manifest templates. These include security best practices, resource limits, health checks, and proper labeling conventions.
Complete Application Stack
Namespace
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: myapp
labels:
app.kubernetes.io/name: myapp
app.kubernetes.io/part-of: myapp-stack
ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: myapp
labels:
app.kubernetes.io/name: myapp
data:
# Application configuration
APP_ENV: "production"
LOG_LEVEL: "info"
LOG_FORMAT: "json"
# Feature flags
ENABLE_METRICS: "true"
ENABLE_DEBUG: "false"
# File-based config
config.yaml: |
server:
port: 8080
workers: 4
cache:
ttl: 3600
features:
new_feature: true
Secret (External Secrets recommended)
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
namespace: myapp
labels:
app.kubernetes.io/name: myapp
type: Opaque
stringData:
DATABASE_URL: "postgresql://user:pass@db:5432/myapp"
API_KEY: "your-api-key"
JWT_SECRET: "your-jwt-secret"
Deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: myapp
labels:
app.kubernetes.io/name: myapp
app.kubernetes.io/version: "1.0.0"
app.kubernetes.io/component: backend
spec:
replicas: 3
revisionHistoryLimit: 5
selector:
matchLabels:
app.kubernetes.io/name: myapp
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app.kubernetes.io/name: myapp
app.kubernetes.io/version: "1.0.0"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: myapp
terminationGracePeriodSeconds: 30
# Security context
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
# Spread across nodes
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
containers:
- name: myapp
image: myorg/myapp:1.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
# Environment from ConfigMap
envFrom:
- configMapRef:
name: myapp-config
# Environment from Secret
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: myapp-secrets
key: DATABASE_URL
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
# Resources
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# Probes
startupProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
failureThreshold: 30
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 0
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# Lifecycle hooks
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
# Security
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# Volume mounts
volumeMounts:
- name: config-volume
mountPath: /app/config
readOnly: true
- name: tmp
mountPath: /tmp
volumes:
- name: config-volume
configMap:
name: myapp-config
items:
- key: config.yaml
path: config.yaml
- name: tmp
emptyDir: {}
Service
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: myapp
labels:
app.kubernetes.io/name: myapp
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: myapp
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
namespace: myapp
labels:
app.kubernetes.io/name: myapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
name: http
HorizontalPodAutoscaler
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
namespace: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
PodDisruptionBudget
# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp
namespace: myapp
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: myapp
ServiceAccount
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
namespace: myapp
labels:
app.kubernetes.io/name: myapp
automountServiceAccountToken: false
NetworkPolicy
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: myapp
namespace: myapp
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: myapp
policyTypes:
- Ingress
- Egress
ingress:
# Allow from ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
# Allow from same namespace
- from:
- podSelector: {}
egress:
# Allow DNS
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
# Allow database
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
Kustomization
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: myapp
resources:
- namespace.yaml
- configmap.yaml
- secret.yaml
- serviceaccount.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- hpa.yaml
- pdb.yaml
- networkpolicy.yaml
commonLabels:
app.kubernetes.io/managed-by: kustomize
images:
- name: myorg/myapp
newTag: 1.0.0
Usage
# Apply all manifests
kubectl apply -k .
# Or individually
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# Check status
kubectl get all -n myapp
kubectl describe deployment myapp -n myapp
# View logs
kubectl logs -l app.kubernetes.io/name=myapp -n myapp -f
# Port forward for testing
kubectl port-forward svc/myapp 8080:80 -n myapp