127 lines
4.6 KiB
Markdown
127 lines
4.6 KiB
Markdown
|
|
# 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)
|