# ADR-0031: Kubernetes Deployment Strategy for kagent Integration

**Status**: Accepted
**Date**: 2026-02-07
**Deciders**: VAPORA Team
**Technical Story**: Kubernetes-native deployment of kagent that supports dev/prod environments and A2A protocol connectivity with VAPORA

---

## Decision

**Kustomize-based deployment** with a shared base and environment-specific overlays:

```text
kubernetes/kagent/
├── base/
│   ├── namespace.yaml
│   ├── rbac.yaml
│   ├── configmap.yaml
│   ├── statefulset.yaml
│   └── service.yaml
└── overlays/
    ├── dev/     # 1 replica, debug logging, relaxed resources
    └── prod/    # 5 replicas, required pod anti-affinity, HPA-ready
```

**StatefulSet** (not Deployment) with pod anti-affinity configured per environment.

---

## Rationale

**Why Kustomize over Helm?** No external dependencies or Go templating. Standard `kubectl apply -k` workflow. Produced YAML is auditable and transparent. Complexity does not justify a templating layer at current scale.

**Why StatefulSet?** Stable pod identities (`kagent-0`, `kagent-1`) simplify debugging. A2A clients can reference predictable endpoint names. Compatible with persistent volumes if needed. Ordered startup/shutdown matches A2A readiness requirements.

**Why ConfigMap for A2A settings?** Configuration changes (discovery intervals, VAPORA URL) don't require image rebuilds. Changes are tracked in Git. `kubectl rollout restart` applies new config atomically.

**Why separate dev/prod overlays?** Resource requirements, replica counts, and anti-affinity policies differ between environments. Base inheritance prevents duplication. Additional environments (staging, canary) can be added as overlays without touching base.

---

## Alternatives Considered

**Helm Charts** — rejected: Go template complexity exceeds current requirements. Revisit if the manifest set grows substantially.

**Deployment + HPA** — rejected: StatefulSet provides the stable identities needed for A2A client configuration and ordered rollout. HPA can be layered over StatefulSet when scaling requirements emerge.

**Single all-in-one manifest** — rejected: Duplicates resource specs between environments, no clear mechanism for environment differentiation.

---

## Trade-offs

**Pros:**

- Identical code path in dev and prod (overlays change parameters, not structure)
- Configuration in version control — full audit trail
- No tooling beyond `kubectl` required
- Pod anti-affinity prevents correlated failures in production

**Cons:**

- Manual scaling (no HPA initially — requires operator action for load spikes)
- Kustomize has limited expressiveness for complex conditional logic
- StatefulSet rolling updates are slower than Deployment rolling updates

---

## Implementation

**Apply commands:**

```bash
# Development
kubectl apply -k kubernetes/kagent/overlays/dev

# Production
kubectl apply -k kubernetes/kagent/overlays/prod

# Verify rollout
kubectl rollout status statefulset/kagent -n kagent
```

**Key manifest locations:**

- `kubernetes/kagent/base/statefulset.yaml` — StatefulSet template
- `kubernetes/kagent/base/configmap.yaml` — A2A discovery config (VAPORA URL, interval)
- `kubernetes/kagent/overlays/prod/statefulset-patch.yaml` — 5 replicas + required anti-affinity
- `kubernetes/kagent/overlays/dev/statefulset-patch.yaml` — 1 replica + preferred anti-affinity

---

## Verification

```bash
# Validate manifests without applying
kubectl kustomize kubernetes/kagent/overlays/dev | kubectl apply --dry-run=client -f -
kubectl kustomize kubernetes/kagent/overlays/prod | kubectl apply --dry-run=client -f -

# Verify running pods
kubectl get pods -n kagent -l app=kagent
kubectl get statefulset kagent -n kagent
```

---

## Consequences

- Adding a new environment requires only a new overlay directory — base is never modified
- Scaling kagent horizontally in production requires a manual `kubectl scale` or an HPA manifest in the prod overlay
- A2A endpoint (`POST /`) must be exposed via a Kubernetes Service (ClusterIP or LoadBalancer) for VAPORA backend to reach it

---

## References

- `kubernetes/kagent/` — Manifests
- [Kustomize Documentation](https://kustomize.io/)
- [Kubernetes StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)

**Related ADRs:**

- [ADR-0030](./0030-a2a-protocol-implementation.md) — A2A protocol server that kagent communicates with
- [ADR-0032](./0032-a2a-error-handling-json-rpc.md) — Error handling in A2A communication
- [ADR-0009](./0009-istio-service-mesh.md) — Istio service mesh (mTLS for kagent ↔ VAPORA traffic)
