| name | kubernetes-manifest-generator |
| description | Generates Kubernetes manifests (Deployments, Services, Ingress, ConfigMaps, Secrets) with best practices for production workloads. Use when user asks to "create k8s manifest", "generate Kubernetes deployment", "setup k8s service", or "create Kubernetes resources". |
| allowed-tools | Write, Read, Bash |
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