# ADR 0002: Kubernetes Deployment Strategy for kagent Integration **Status:** Accepted **Date:** 2026-02-07 **Authors:** VAPORA Team ## Context kagent integration required a Kubernetes-native deployment strategy that: - Supports development and production environments - Maintains A2A protocol connectivity with VAPORA - Enables horizontal scaling - Ensures high availability in production - Minimizes operational complexity - Facilitates updates and configuration changes ## Decision We adopted a **Kustomize-based deployment strategy** with environment-specific overlays: ``` kubernetes/kagent/ ├── base/ # Environment-agnostic base │ ├── namespace.yaml │ ├── rbac.yaml │ ├── configmap.yaml │ ├── statefulset.yaml │ └── service.yaml ├── overlays/ │ ├── dev/ # Development: 1 replica, debug logging │ └── prod/ # Production: 5 replicas, HA ``` ### Key Design Decisions 1. **StatefulSet over Deployment** - Provides stable pod identities - Supports ordered startup/shutdown - Compatible with persistent volumes 2. **Kustomize over Helm** - Native Kubernetes tooling (kubectl) - YAML-based, no templating language - Easier code review of actual manifests - Lower complexity for our use case 3. **Separate dev/prod Overlays** - Code reuse via base inheritance - Clear environment differentiation - Easy to add staging, testing, etc. - Single source of truth for base configuration 4. **ConfigMap-based A2A Integration** - Runtime configuration without rebuilding images - Environment-specific values (discovery interval, etc.) - Easy rollback via kubectl rollout 5. **Pod Anti-Affinity** - Development: Preferred (best-effort distribution) - Production: Required (strict node separation) - Prevents single-node failure modes ## Rationale **Why Kustomize?** - No external dependencies or DSLs to learn - kubectl integration (no new tools for operators) - Transparent YAML (easier auditing) - Suitable for our scale (not complex microservices) **Why StatefulSet?** - Pod names are predictable (kagent-0, kagent-1, etc.) - Simplifies debugging and troubleshooting - Compatible with persistent volumes for future phase - A2A clients can reference stable endpoints **Why ConfigMap for A2A settings?** - No image rebuild required for config changes - Easy to adjust discovery intervals per environment - Transparent configuration in Git - Can be patched/updated at runtime **Why separate dev/prod?** - Resource requirements differ dramatically - Logging levels should differ - Scaling policies differ - Both treated equally in code review ## Consequences **Positive:** - Identical code paths in dev and prod (just different replicas/resources) - Easy to add more environments (staging, testing, etc.) - Standard kubectl workflows - Clear separation of concerns - Configuration in version control - No external tools beyond kubectl **Negative:** - Manual pod management (no autoscaling annotations initially) - Kustomize has limitations for complex overlays - No templating language flexibility - Requires understanding of Kubernetes primitives ## Alternatives Considered 1. **Helm Charts** - Rejected: Go templates more complex than needed - Revisit if complexity demands it 2. **Deployment + Horizontal Pod Autoscaler** - Rejected: StatefulSet provides stability needed for debugging - Can layer HPA over StatefulSet if needed 3. **All-in-one manifest** - Rejected: Code duplication between dev/prod - No clear environment separation ## Migration Path 1. **Current:** Kustomize with manual scaling 2. **Phase 2:** Add HorizontalPodAutoscaler overlay 3. **Phase 3:** Add Prometheus/Grafana monitoring 4. **Phase 4:** Integrate with Istio service mesh ## File Structure Rationale ``` base/ # Applied to all environments ├── namespace.yaml # Single kagent namespace ├── rbac.yaml # Shared RBAC policies ├── configmap.yaml # Base A2A configuration ├── statefulset.yaml # Base deployment template └── service.yaml # Shared services overlays/dev/ # Development-specific ├── kustomization.yaml # Patch application order └── statefulset-patch.yaml # 1 replica, lower resources overlays/prod/ # Production-specific ├── kustomization.yaml # Patch application order └── statefulset-patch.yaml # 5 replicas, higher resources ``` ## Related Decisions - ADR-0001: A2A Protocol Implementation - ADR-0003: Error Handling and Protocol Compliance ## References - Kustomize Documentation: https://kustomize.io/ - Kubernetes StatefulSets: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ - kubectl: https://kubernetes.io/docs/reference/kubectl/