Kubernetes Deployment Strategies for Claude Code
Table of Contents
- Overview
- Deployment Strategies
- Kubernetes Manifests and Helm Charts
- Scaling Considerations
- Service Mesh Integration
- ConfigMaps and Secrets Management
- Production Deployment Patterns
Overview
This document provides comprehensive guidance on deploying Claude Code applications in Kubernetes environments, based on 2025 best practices and production patterns.
Deployment Strategies
Core Kubernetes Deployment Strategies
1. Rolling Update (Default Strategy)
- Description: Gradually replaces old instances with new ones
- Benefits: Zero downtime, gradual exposure to new version
- Use Case: Standard application updates
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 12. Blue/Green Deployment
- Description: Runs two identical environments, switches traffic once stable
- Benefits: Instant rollback capability, minimal risk
- Requirements: Service mesh or load balancer for traffic switching
3. Canary Deployment
- Description: Routes small percentage of traffic to new version
- Benefits: Risk mitigation, gradual validation
- Implementation: Requires service mesh (Istio/Linkerd) or ingress controller
4. Recreate Deployment
- Description: All pods terminated before new ones created
- Downtime: Yes
- Use Case: Non-critical applications or when resources are limited
5. Shadow Deployment
- Description: Mirror production traffic to new version without affecting users
- Benefits: Real-world testing without user impact
- Requirements: Service mesh capability
Best Practices
- Use declarative deployments
- Implement comprehensive health checks
- Enable monitoring and rollback capabilities
- Test deployment strategies in staging first
- Keep it simple when possible
Kubernetes Manifests and Helm Charts
Production-Ready Kubernetes Manifest
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: claude-code-app
namespace: production
labels:
app: claude-code
environment: production
version: v1.0.0
spec:
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: claude-code
environment: production
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: claude-code
environment: production
version: v1.0.0
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- claude-code
topologyKey: kubernetes.io/hostname
containers:
- name: claude-code
image: your-registry/claude-code-app:v1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: http
protocol: TCP
env:
- name: ENVIRONMENT
value: "production"
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: claude-code-secrets
key: api-key
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
configMap:
name: claude-code-config
securityContext:
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: claude-code-saHelm Chart Structure
# values.yaml
replicaCount: 3
image:
repository: your-registry/claude-code-app
tag: v1.0.0
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8080
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
secrets:
anthropicApiKey: "" # Override in values-prod.yaml
configMap:
data:
LOG_LEVEL: "info"
ENVIRONMENT: "production"Helm Best Practices
- Security: Never store secrets in charts, use Kubernetes Secrets
- Environment Separation: Use separate values files per environment
- Version Control: Follow semantic versioning for charts
- Testing: Use
helm lintand test deployments - Documentation: Maintain comprehensive README files
- Dependency Management: Use
helm dependencyfor subcharts - CI/CD Integration: Automate deployments with GitOps
Scaling Considerations
Horizontal Pod Autoscaler (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: claude-code-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: claude-code-app
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: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60Vertical Pod Autoscaler (VPA)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: claude-code-vpa
namespace: production
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: claude-code-app
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: claude-code
maxAllowed:
cpu: 2
memory: 2Gi
minAllowed:
cpu: 100m
memory: 128MiCluster Autoscaler Configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
containers:
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.29.0
name: cluster-autoscaler
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/claude-code-clusterScaling Best Practices
- Define resource requests and limits for all containers
- Use HPA for stateless workloads
- Use VPA for stateful workloads (not with HPA on same metrics)
- Configure appropriate stabilization windows
- Monitor scaling events and adjust thresholds
- Consider KEDA for event-driven scaling
Service Mesh Integration
Linkerd Configuration (Recommended for simplicity)
apiVersion: v1
kind: Namespace
metadata:
name: production
annotations:
linkerd.io/inject: enabled
---
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
name: claude-code-authz
namespace: production
spec:
server:
selector:
matchLabels:
app: claude-code
client:
meshTLS:
identities:
- "cluster.local/ns/production/sa/claude-code-client"Istio Configuration (For advanced features)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: claude-code-vs
namespace: production
spec:
hosts:
- claude-code
http:
- match:
- headers:
version:
exact: canary
route:
- destination:
host: claude-code
subset: canary
weight: 10
- destination:
host: claude-code
subset: stable
weight: 90
- route:
- destination:
host: claude-code
subset: stable
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: claude-code-dr
namespace: production
spec:
host: claude-code
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 100
http2MaxRequests: 100
loadBalancer:
simple: ROUND_ROBIN
subsets:
- name: stable
labels:
version: stable
- name: canary
labels:
version: canaryService Mesh Selection Criteria
- Choose Linkerd if: You want simplicity, low overhead, Kubernetes-only deployment
- Choose Istio if: You need advanced traffic management, multi-cloud support, extensive features
ConfigMaps and Secrets Management
ConfigMap Example
apiVersion: v1
kind: ConfigMap
metadata:
name: claude-code-config
namespace: production
data:
app.yaml: |
server:
port: 8080
timeout: 30s
claude:
model: claude-3-opus-20240229
max_tokens: 4096
temperature: 0.7
logging:
level: info
format: json
CLAUDE.md: |
# Claude Code Configuration
- Never assume. Search the web if doubting
- Use deepwiki MCP for framework documentation
- Avoid using dashes in prose
- Check existing patterns before creating new filesSecret Management with External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
namespace: production
spec:
provider:
vault:
server: "https://vault.example.com:8200"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "claude-code"
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: claude-code-secrets
namespace: production
spec:
refreshInterval: 15s
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: claude-code-secrets
creationPolicy: Owner
data:
- secretKey: api-key
remoteRef:
key: claude-code/api-keys
property: anthropicSealed Secrets Alternative
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: claude-code-secrets
namespace: production
spec:
encryptedData:
api-key: AgBe7s1K5p... # Encrypted value
template:
metadata:
name: claude-code-secrets
type: OpaqueBest Practices
- Never store secrets in ConfigMaps
- Use external secret management systems
- Enable encryption at rest for etcd
- Implement RBAC for secret access
- Rotate secrets regularly
- Audit secret access
- Use separate namespaces for isolation
Production Deployment Patterns
GitOps with ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: claude-code-app
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: production
source:
repoURL: https://github.com/yourorg/claude-code-k8s
targetRevision: main
path: deployments/production
helm:
valueFiles:
- values-prod.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3mMulti-Environment Setup
# ApplicationSet for multiple environments
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: claude-code-environments
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: dev
url: https://dev-cluster.example.com
namespace: claude-code-dev
- cluster: staging
url: https://staging-cluster.example.com
namespace: claude-code-staging
- cluster: production
url: https://prod-cluster.example.com
namespace: claude-code-prod
template:
metadata:
name: '{{cluster}}-claude-code'
spec:
project: default
source:
repoURL: https://github.com/yourorg/claude-code-k8s
targetRevision: main
path: deployments/{{cluster}}
destination:
server: '{{url}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: trueProduction Checklist
Pre-Deployment
- Container image security scanning completed
- Resource limits and requests defined
- Health checks implemented
- Secrets encrypted and stored externally
- RBAC policies configured
- Network policies defined
- Pod disruption budgets set
- Backup and disaster recovery tested
Deployment
- GitOps repository updated
- Deployment strategy selected
- Monitoring and alerting configured
- Service mesh policies applied
- Autoscaling configured
- Load testing performed
Post-Deployment
- Application metrics validated
- Error rates monitored
- Performance benchmarks met
- Security scans passed
- Documentation updated
- Runbooks available
Monitoring Stack
apiVersion: v1
kind: ServiceMonitor
metadata:
name: claude-code-metrics
namespace: production
spec:
selector:
matchLabels:
app: claude-code
endpoints:
- port: metrics
interval: 30s
path: /metrics
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: claude-code-alerts
namespace: production
spec:
groups:
- name: claude-code
interval: 30s
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{job="claude-code",status=~"5.."}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate detected"
description: "Error rate is {{ $value }} for {{ $labels.instance }}"Enterprise Integration Patterns
Multi-Cluster Deployment
# Cluster Registry
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: Cluster
metadata:
name: production-us-east
spec:
kubernetesApiEndpoints:
serverEndpoints:
- url: https://k8s-prod-us-east.example.com
authInfo:
controller:
kind: Secret
name: production-us-east-credentials
namespace: fleet-systemCost Optimization
# Spot Instance Configuration
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: claude-code-spot
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
limits:
resources:
cpu: 1000
memory: 1000Gi
provider:
instanceStorePolicy: RAID0
userData: |
#!/bin/bash
/etc/eks/bootstrap.sh claude-code-cluster
ttlSecondsAfterEmpty: 30Summary
This comprehensive guide provides production-ready patterns for deploying Claude Code on Kubernetes. Key takeaways:
- Start Simple: Use rolling updates and basic manifests before advancing to complex patterns
- Security First: Implement proper secret management, RBAC, and network policies
- Automate Everything: Leverage GitOps for consistent, auditable deployments
- Monitor Proactively: Set up comprehensive monitoring before issues arise
- Scale Intelligently: Use appropriate autoscaling mechanisms for your workload
- Choose Tools Wisely: Select service mesh and deployment tools based on actual needs
Remember that the best deployment strategy is one that matches your team’s expertise and application requirements. Start with the basics and incrementally adopt more sophisticated patterns as your needs evolve.