Claude Code for Kubernetes — kubectl, Helm & Manifest Workflows
Claude Code accelerates Kubernetes work when given the right context about your cluster topology, naming conventions, and manifest style. This guide covers the CLAUDE.md template for k8s repos, Helm chart authoring, debugging runbooks, RBAC generation, and Kustomize overlay patterns.
Kubernetes CLAUDE.md Template
# Project: [Your Platform Name]
## Cluster topology
- Environments: dev (kind), staging (EKS us-east-1), prod (EKS eu-west-1)
- Namespaces: app-dev, app-staging, app-prod, monitoring, ingress-nginx
- Image registry: 123456789.dkr.ecr.us-east-1.amazonaws.com/[service]
- Ingress: nginx ingress controller (ingress class: nginx)
- TLS: cert-manager with letsencrypt-prod ClusterIssuer
## Naming conventions
- Deployments: [service]-[env] (e.g. api-prod)
- Labels: app.kubernetes.io/name, app.kubernetes.io/version, app.kubernetes.io/component
- ConfigMaps: [service]-config-[env]
- Secrets: managed by External Secrets Operator — never hardcode values
## Key commands
```bash
kubectl apply -f k8s/ # apply all manifests
kubectl rollout status deployment/api-prod -n app-prod
kubectl logs -f deployment/api-prod -n app-prod --tail=100
kubectl exec -it deploy/api-prod -n app-prod -- /bin/sh
helm lint charts/[name] # lint a chart
helm template charts/[name] --values values-staging.yaml | kubectl apply --dry-run=client -f -
```
## Manifest style
- Always set resource requests AND limits
- Use RollingUpdate strategy with maxSurge: 1, maxUnavailable: 0 for zero-downtime
- readinessProbe required on every Deployment; livenessProbe optional
- Never use latest tag — always pin to a specific digest or semver tag
- Secrets from External Secrets Operator (ExternalSecret CRD), not literal Secret objects
Manifest Generation Workflows
New Deployment from scratch
claude "create a Kubernetes Deployment for the 'payments' service.
Image: 123456789.dkr.ecr.us-east-1.amazonaws.com/payments:v1.2.0
Namespace: app-prod. Port 8080. Replicas: 3.
Env vars from ConfigMap payments-config-prod.
CPU request: 100m limit: 500m. Memory request: 128Mi limit: 512Mi.
readinessProbe on /health, initialDelaySeconds: 5.
RollingUpdate strategy per our CLAUDE.md conventions."
Add a HorizontalPodAutoscaler
claude "add an HPA for deployment/payments-prod in app-prod namespace.
Min replicas: 2, max: 10.
Scale on CPU 70% and memory 80%.
Use autoscaling/v2 API."
ConfigMap + ExternalSecret pair
claude "create a ConfigMap for non-sensitive payments config (API_BASE_URL,
LOG_LEVEL, TIMEOUT_MS) and an ExternalSecret for DATABASE_URL and
STRIPE_API_KEY. ExternalSecret should pull from AWS Secrets Manager
path /payments/prod/. Use our ESO ClusterSecretStore named 'aws-secretsmanager'."
Debugging Runbook — Common k8s Failures
| Symptom | Claude Code prompt | Root cause check |
|---|---|---|
| CrashLoopBackOff | "diagnose: [paste kubectl describe pod output + kubectl logs --previous]" | Missing env var, OOMKilled, failed readiness probe, entrypoint error |
| Pending pod | "pod is Pending, no node assigned: [paste kubectl describe pod output]" | Insufficient resources, unschedulable taint, missing PVC |
| ImagePullBackOff | "ImagePullBackOff on [image tag]: [paste describe output]" | Wrong registry URL, missing imagePullSecret, tag doesn't exist |
| Service not routing | "Service 'payments-svc' not reaching pods, curl returns connection refused" | Label selector mismatch, wrong targetPort, NetworkPolicy blocking |
| OOMKilled | "pod OOMKilled repeatedly, current memory limit: 256Mi, typical usage: 280Mi" | Memory limit too low; Claude calculates new limit + recommends VPA |
Helm Chart Authoring
Generate a new chart
claude "create a Helm chart named 'payments' for a stateless HTTP service.
Values to template: replicaCount, image.repository/tag/pullPolicy,
service.type/port, ingress.enabled/host/tlsSecret,
resources.requests/limits, env (list of name/value or secretRef pairs).
Include NOTES.txt with post-install instructions.
Match the structure of our existing charts/ directory."
Add a conditional sidecar
claude "add an optional Datadog APM sidecar to the chart.
Enabled via values.datadogSidecar.enabled (default false).
Sidecar image: gcr.io/datadoghq/agent:7, port 8126.
Inject DD_SERVICE, DD_ENV, DD_VERSION from chart metadata.
Only render the sidecar container when the value is true."
RBAC Generation
| Use case | Claude Code prompt |
|---|---|
| CI pipeline (read-only) | "create RBAC for a CI service account that can read pods, deployments, and replicasets in the app-staging namespace. No write access." |
| Deployment automation | "RBAC for a deploy bot: get/list/watch/update deployments and statefulsets in app-prod. No delete." |
| Metrics scraper | "ClusterRole for Prometheus to list and get pods, endpoints, services, and nodes cluster-wide. Bind to namespace monitoring." |
| Developer read access | "RoleBinding giving group 'developers' view ClusterRole in app-staging and app-dev namespaces." |
Kustomize Overlay Patterns
claude "convert our flat k8s/api/ directory into a Kustomize structure.
Base should contain the core Deployment, Service, and ConfigMap.
Create overlays/staging with: replica count 1, image tag :staging-latest,
resource limits halved. Create overlays/prod with: replica count 3,
image tag :prod-v${VERSION}, full resource limits, HPA enabled."
Tell Claude "never modify files in base/ directly — all environment differences go in overlays/". Claude will use JSON6902 or strategic-merge patches instead of duplicating manifests.
GitOps Integration (ArgoCD / Flux)
ArgoCD Application manifest
claude "create an ArgoCD Application for the payments service.
Source: this repo, path k8s/payments/overlays/prod, targetRevision HEAD.
Destination: cluster https://prod-cluster-api, namespace app-prod.
Sync policy: automated with selfHeal: true and prune: true.
Project: platform."
Flux HelmRelease
claude "create a Flux HelmRelease for the payments chart.
Chart source: HelmRepository 'internal' at charts.internal.company.com.
Chart version: '>=1.2.0 <2.0.0'. Target namespace: app-prod.
Values: replicaCount 3, image.tag from an ImagePolicy 'payments-prod'.
Interval: 10m."
5 Tips for Kubernetes + Claude Code
- Paste
kubectl explain deployment.specoutput into your session when asking Claude to write advanced manifest fields — it eliminates hallucinated field names. - Tell Claude your Kubernetes version (e.g. "cluster is 1.29"). API deprecations (networking.k8s.io/v1 vs extensions/v1beta1) matter and Claude will use the right API group.
- For multi-cluster repos, put a CLAUDE.md in each cluster directory (clusters/prod/, clusters/staging/) describing that cluster's specifics. Claude merges hierarchically.
- When generating NetworkPolicy, always tell Claude "default-deny posture — only allow listed traffic". Claude defaults to permissive if not specified.
- Use
helm template ... | kubectl apply --dry-run=client -f -as a PostToolUse hook to catch manifest errors before deploy. Claude sees the dry-run output and self-corrects.