Kubernetes Deployment Strategies for Claude Code

Table of Contents

  1. Overview
  2. Deployment Strategies
  3. Kubernetes Manifests and Helm Charts
  4. Scaling Considerations
  5. Service Mesh Integration
  6. ConfigMaps and Secrets Management
  7. 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: 1

2. 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-sa

Helm 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

  1. Security: Never store secrets in charts, use Kubernetes Secrets
  2. Environment Separation: Use separate values files per environment
  3. Version Control: Follow semantic versioning for charts
  4. Testing: Use helm lint and test deployments
  5. Documentation: Maintain comprehensive README files
  6. Dependency Management: Use helm dependency for subcharts
  7. 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: 60

Vertical 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: 128Mi

Cluster 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-cluster

Scaling Best Practices

  1. Define resource requests and limits for all containers
  2. Use HPA for stateless workloads
  3. Use VPA for stateful workloads (not with HPA on same metrics)
  4. Configure appropriate stabilization windows
  5. Monitor scaling events and adjust thresholds
  6. Consider KEDA for event-driven scaling

Service Mesh Integration

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: canary

Service 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 files

Secret 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: anthropic

Sealed 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: Opaque

Best Practices

  1. Never store secrets in ConfigMaps
  2. Use external secret management systems
  3. Enable encryption at rest for etcd
  4. Implement RBAC for secret access
  5. Rotate secrets regularly
  6. Audit secret access
  7. 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: 3m

Multi-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: true

Production 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-system

Cost 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: 30

Summary

This comprehensive guide provides production-ready patterns for deploying Claude Code on Kubernetes. Key takeaways:

  1. Start Simple: Use rolling updates and basic manifests before advancing to complex patterns
  2. Security First: Implement proper secret management, RBAC, and network policies
  3. Automate Everything: Leverage GitOps for consistent, auditable deployments
  4. Monitor Proactively: Set up comprehensive monitoring before issues arise
  5. Scale Intelligently: Use appropriate autoscaling mechanisms for your workload
  6. 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.