Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create production-ready Kubernetes manifests for Deployments, Services, ConfigMaps, and Secrets following best practices and security standards. Use when generating Kubernetes YAML manifests, creating K8s resources, or implementing production-grade Kubernetes configurations.
.claude/skills/dicklesworthstone-k8s-manifest-generator/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 269% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 189% | 0% |
| case-07 | ✓→✗ | ▼ Worse | 426% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 122% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 268% | 0% |
Step-by-step guidance for creating production-ready Kubernetes manifests including Deployments, Services, ConfigMaps, Secrets, and PersistentVolumeClaims.
This skill provides comprehensive guidance for generating well-structured, secure, and production-ready Kubernetes manifests following cloud-native best practices and Kubernetes conventions.
Use this skill when you need to:
Understand the workload:
Questions to ask:
Follow this structure:
yamlapiVersion: apps/v1 kind: Deployment metadata: name: <app-name> namespace: <namespace> labels: app: <app-name> version: <version> spec: replicas: 3 selector: matchLabels: app: <app-name> template: metadata: labels: app: <app-name> version: <version> spec: containers: - name: <container-name> image: <image>:<tag> ports: - containerPort: <port> name: http resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: http initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: http initialDelaySeconds: 5 periodSeconds: 5 env: - name: ENV_VAR value: "value" envFrom: - configMapRef: name: <app-name>-config - secretRef: name: <app-name>-secret
Best practices to apply:
:latest)Reference: See references/deployment-spec.md for detailed deployment options
Choose the appropriate Service type:
ClusterIP (internal only):
yamlapiVersion: v1 kind: Service metadata: name: <app-name> namespace: <namespace> labels: app: <app-name> spec: type: ClusterIP selector: app: <app-name> ports: - name: http port: 80 targetPort: 8080 protocol: TCP
LoadBalancer (external access):
yamlapiVersion: v1 kind: Service metadata: name: <app-name> namespace: <namespace> labels: app: <app-name> annotations: service.beta.kubernetes.io/aws-load-balancer-type: nlb spec: type: LoadBalancer selector: app: <app-name> ports: - name: http port: 80 targetPort: 8080 protocol: TCP
Reference: See references/service-spec.md for service types and networking
For application configuration:
yamlapiVersion: v1 kind: ConfigMap metadata: name: <app-name>-config namespace: <namespace> data: APP_MODE: production LOG_LEVEL: info DATABASE_HOST: db.example.com # For config files app.properties: | server.port=8080 server.host=0.0.0.0 logging.level=INFO
Best practices:
Reference: See assets/configmap-template.yaml for examples
For sensitive data:
yamlapiVersion: v1 kind: Secret metadata: name: <app-name>-secret namespace: <namespace> type: Opaque stringData: DATABASE_PASSWORD: "changeme" API_KEY: "secret-api-key" # For certificate files tls.crt: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- tls.key: | -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----
Security considerations:
kubernetes.io/tls for TLS secretsFor stateful applications:
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: <app-name>-data namespace: <namespace> spec: accessModes: - ReadWriteOnce storageClassName: gp3 resources: requests: storage: 10Gi
Mount in Deployment:
yamlspec: template: spec: containers: - name: app volumeMounts: - name: data mountPath: /var/lib/app volumes: - name: data persistentVolumeClaim: claimName: <app-name>-data
Storage considerations:
Add security context to Deployment:
yamlspec: template: spec: securityContext: runAsNonRoot: true runAsUser: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: app securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL
Security checklist:
Standard labels (recommended):
yamlmetadata: labels: app.kubernetes.io/name: <app-name> app.kubernetes.io/instance: <instance-name> app.kubernetes.io/version: "1.0.0" app.kubernetes.io/component: backend app.kubernetes.io/part-of: <system-name> app.kubernetes.io/managed-by: kubectl
Useful annotations:
yamlmetadata: annotations: description: "Application description" contact: "team@example.com" prometheus.io/scrape: "true" prometheus.io/port: "9090" prometheus.io/path: "/metrics"
File organization options:
Option 1: Single file with --- separator
yaml# app-name.yaml --- apiVersion: v1 kind: ConfigMap ... --- apiVersion: v1 kind: Secret ... --- apiVersion: apps/v1 kind: Deployment ... --- apiVersion: v1 kind: Service ...
Option 2: Separate files
manifests/
├── configmap.yaml
├── secret.yaml
├── deployment.yaml
├── service.yaml
└── pvc.yamlOption 3: Kustomize structure
base/
├── kustomization.yaml
├── deployment.yaml
├── service.yaml
└── configmap.yaml
overlays/
├── dev/
│ └── kustomization.yaml
└── prod/
└── kustomization.yamlValidation steps:
bash# Dry-run validation kubectl apply -f manifest.yaml --dry-run=client # Server-side validation kubectl apply -f manifest.yaml --dry-run=server # Validate with kubeval kubeval manifest.yaml # Validate with kube-score kube-score score manifest.yaml # Check with kube-linter kube-linter lint manifest.yaml
Testing checklist:
Use case: Standard web API or microservice
Components needed:
Reference: See assets/deployment-template.yaml
Use case: Database or persistent storage application
Components needed:
Use case: Scheduled tasks or batch processing
Components needed:
Use case: Application with sidecar containers
Components needed:
The following templates are available in the assets/ directory:
deployment-template.yaml - Standard deployment with best practicesservice-template.yaml - Service configurations (ClusterIP, LoadBalancer, NodePort)configmap-template.yaml - ConfigMap examples with different data typessecret-template.yaml - Secret examples (to be generated, not committed)pvc-template.yaml - PersistentVolumeClaim templatesreferences/deployment-spec.md - Detailed Deployment specificationreferences/service-spec.md - Service types and networking detailsPods not starting:
kubectl describe pod <pod-name>kubectl get nodeskubectl get events --sort-by='.lastTimestamp'Service not accessible:
kubectl get endpoints <service-name>kubectl run debug --rm -it --image=busybox -- shConfigMap/Secret not loading:
kubectl get configmap,secretAfter creating manifests:
helm-chart-scaffolding - For templating and packaginggitops-workflow - For automated deploymentsk8s-security-policies - For advanced security configurations| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 11,460 | 17,847 | +56% | 1 | 1 | 0% | 2,292 | 5,095 | +122% | 0 | 0 | — |
case-02 | pass→pass | 6,719 | 7,287 | +8% | 1 | 1 | 0% | 1,216 | 4,473 | +268% | 0 | 0 | — |
case-03 | pass→pass | 12,689 | 10,205 | -20% | 1 | 1 | 0% | 2,284 | 4,977 | +118% | 0 | 0 | — |
case-04 | fail→fail | 5,908 | 13,603 | +130% | 1 | 1 | 0% | 1,132 | 5,729 | +406% | 0 | 0 | — |
case-05 | fail→fail | 4,581 | 5,674 | +24% | 1 | 1 | 0% | 822 | 4,183 | +409% | 0 | 0 | — |
case-06 | fail→pass | 9,415 | 15,175 | +61% | 1 | 1 | 0% | 1,651 | 6,093 | +269% | 0 | 0 | — |
case-07 | pass→fail | 6,063 | 10,294 | +70% | 1 | 1 | 0% | 977 | 5,138 | +426% | 0 | 0 | — |
case-08 | pass→pass | 14,622 | 13,372 | -9% | 1 | 1 | 0% | 3,026 | 5,963 | +97% | 0 | 0 | — |
case-09 | pass→pass | 13,327 | 11,577 | -13% | 1 | 1 | 0% | 2,614 | 5,366 | +105% | 0 | 0 | — |
case-10 | fail→pass | 8,524 | 8,323 | -2% | 1 | 1 | 0% | 1,644 | 4,744 | +189% | 0 | 0 | — |
case-11 | pass→pass | 3,160 | 4,548 | +44% | 1 | 1 | 0% | 588 | 3,986 | +578% | 0 | 0 | — |
case-12 | pass→pass | 6,826 | 9,652 | +41% | 1 | 1 | 0% | 1,353 | 4,949 | +266% | 0 | 0 | — |
case-13 | pass→pass | 3,455 | 9,302 | +169% | 1 | 1 | 0% | 594 | 4,491 | +656% | 0 | 0 | — |
case-14 | pass→pass | 3,338 | 5,655 | +69% | 1 | 1 | 0% | 533 | 4,179 | +684% | 0 | 0 | — |
case-15 | pass→pass | 12,941 | 6,505 | -50% | 1 | 1 | 0% | 1,862 | 4,297 | +131% | 0 | 0 | — |
case-16 | pass→pass | 8,544 | 8,007 | -6% | 1 | 1 | 0% | 1,515 | 4,345 | +187% | 0 | 0 | — |
case-17 | pass→pass | 10,325 | 7,777 | -25% | 1 | 1 | 0% | 1,935 | 4,330 | +124% | 0 | 0 | — |
case-18 | pass→pass | 6,186 | 3,267 | -47% | 1 | 1 | 0% | 1,053 | 3,615 | +243% | 0 | 0 | — |
case-19 | pass→pass | 7,097 | 9,348 | +32% | 1 | 1 | 0% | 913 | 5,058 | +454% | 0 | 0 | — |
case-20 | pass→pass | 6,553 | 5,513 | -16% | 1 | 1 | 0% | 1,115 | 4,065 | +265% | 0 | 0 | — |
case-21 | pass→pass | 6,432 | 6,756 | +5% | 1 | 1 | 0% | 1,162 | 4,184 | +260% | 0 | 0 | — |
case-22 | pass→pass | 4,098 | 6,348 | +55% | 1 | 1 | 0% | 807 | 4,435 | +450% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.