Kubernetes Manifest Generator
Generates production-ready Kubernetes manifests with best practices for security, resource management, and high availability.
When to Use
- "Create Kubernetes deployment"
- "Generate k8s manifests"
- "Setup Kubernetes service"
- "Create Ingress configuration"
- "Generate ConfigMap and Secrets"
Instructions
1. Gather Requirements
Ask for:
- Application name
- Container image and tag
- Number of replicas
- Resource requirements (CPU, memory)
- Environment variables
- Ports exposed
- Ingress/Service type needed
- Storage requirements
2. Generate Deployment
Basic Deployment:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
labels:
app: myapp
version: v1.0.0
environment: production
spec:
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: myapp
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: myapp
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: myapp
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: myapp
image: myapp:v1.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "8080"
envFrom:
- configMapRef:
name: myapp-config
- secretRef:
name: myapp-secrets
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
3. Generate Service
ClusterIP Service:
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: production
labels:
app: myapp
spec:
type: ClusterIP
selector:
app: myapp
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
sessionAffinity: None
LoadBalancer Service:
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
namespace: production
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8080
Headless Service (for StatefulSets):
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: production
spec:
clusterIP: None
selector:
app: myapp
ports:
- name: http
port: 8080
4. Generate Ingress
NGINX Ingress:
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
namespace: production
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
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
Traefik Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
namespace: production
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
5. Generate ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: production
data:
# Simple values
LOG_LEVEL: "info"
FEATURE_FLAGS: "feature1,feature2"
# File content
app.conf: |
server {
listen 8080;
location / {
root /app;
}
}
config.json: |
{
"database": {
"pool": {
"min": 2,
"max": 10
}
},
"cache": {
"ttl": 3600
}
}
6. Generate Secrets
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
namespace: production
type: Opaque
stringData:
DATABASE_URL: "postgresql://user:password@postgres:5432/myapp"
API_KEY: "your-api-key-here"
JWT_SECRET: "your-jwt-secret"
---
# TLS Secret (for custom certificates)
apiVersion: v1
kind: Secret
metadata:
name: myapp-tls
namespace: production
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTi... # base64 encoded
tls.key: LS0tLS1CRUdJTi... # base64 encoded
Create secret from file:
kubectl create secret generic myapp-secrets \
--from-file=.env \
--namespace=production \
--dry-run=client -o yaml > secret.yaml
7. Generate StatefulSet
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: production
spec:
serviceName: mongodb-headless
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:6.0
ports:
- containerPort: 27017
name: mongodb
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secrets
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secrets
key: password
volumeMounts:
- name: data
mountPath: /data/db
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi
8. Generate PersistentVolumeClaim
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myapp-data
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 10Gi
9. Generate HorizontalPodAutoscaler
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 3
maxReplicas: 20
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: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
10. Generate NetworkPolicy
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: myapp
namespace: production
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
11. Generate ServiceAccount & RBAC
# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myapp
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp
namespace: production
subjects:
- kind: ServiceAccount
name: myapp
namespace: production
roleRef:
kind: Role
name: myapp
apiGroup: rbac.authorization.k8s.io
12. Generate Kustomization
kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- configmap.yaml
- secret.yaml
- hpa.yaml
- networkpolicy.yaml
- rbac.yaml
commonLabels:
app: myapp
managed-by: kustomize
images:
- name: myapp
newName: registry.example.com/myapp
newTag: v1.2.3
configMapGenerator:
- name: myapp-env
literals:
- NODE_ENV=production
- LOG_LEVEL=info
secretGenerator:
- name: myapp-api
literals:
- API_KEY=secret-value
13. Generate All Resources Script
#!/bin/bash
# generate-k8s-manifests.sh
APP_NAME=${1:-myapp}
NAMESPACE=${2:-production}
IMAGE=${3:-$APP_NAME:latest}
mkdir -p k8s
cat > k8s/namespace.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: $NAMESPACE
EOF
cat > k8s/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: $APP_NAME
namespace: $NAMESPACE
spec:
replicas: 3
selector:
matchLabels:
app: $APP_NAME
template:
metadata:
labels:
app: $APP_NAME
spec:
containers:
- name: $APP_NAME
image: $IMAGE
ports:
- containerPort: 8080
EOF
echo "Kubernetes manifests generated in k8s/"
Best Practices
DO:
- Use resource requests and limits
- Implement health checks
- Use non-root users
- Enable pod security contexts
- Use secrets for sensitive data
- Implement network policies
- Use HPA for autoscaling
- Add pod anti-affinity
- Use readOnly root filesystem
DON'T:
- Run as root
- Hardcode secrets
- Skip resource limits
- Use :latest tag
- Ignore security contexts
- Allow privilege escalation
- Skip health checks
- Use default service account
Checklist
- [ ] Deployment configured
- [ ] Service created
- [ ] Ingress setup (if needed)
- [ ] ConfigMap and Secrets created
- [ ] Resource limits set
- [ ] Health checks configured
- [ ] Security contexts applied
- [ ] RBAC configured
- [ ] HPA setup (if needed)
- [ ] Network policies defined