The in-cluster Gluetun-pod gateway (ADR-0013) cannot be steered: a pod's tun0 is invisible to the node datapath, and hostNetwork Gluetun hijacks the node's own default route (breaks k3s/etcd). The tunnel itself works (PIA egress validated), but not the steering. New decision (ADR-0015): move the tunnel to a HOST OpenVPN systemd service on egress-gateway node(s) (Ansible-managed, split-tunnel so it doesn't touch the node default route), steer egress-class=vpn pods with a CiliumEgressGatewayPolicy (native eBPF, no client-pod changes), and enforce the kill-switch with a host nftables rule (fail-closed independent of Cilium). PIA/OpenVPN-UDP provider decision (ADR-0013) stands; the .ovpn transfers over; PF re-solved host-side (Phase 6). Amended for consistency: ADR-0013 (client+steering superseded), decisions/README, docs/00, docs/01, docs/03, docs/07, agents/task-board. Co-Authored-By: Claude Opus 4.8 <[email protected]>
60 lines
3.4 KiB
Markdown
60 lines
3.4 KiB
Markdown
# Architecture Decision Records (ADRs)
|
|
|
|
ADRs are an **append-only ledger** of the significant technology and pattern choices for this
|
|
platform. Each records the context, the decision, the rejected alternatives, and the requirements it
|
|
serves. **Do not edit an accepted decision in place** — supersede it with a new ADR.
|
|
|
|
> **ADRs are specifications and are immutable to AI agents** (R-TEST-06). Agents may *draft* a
|
|
> proposed ADR and escalate it, but only the **human operator/architect** approves/accepts or edits
|
|
> ADRs. See [`../AGENTS.md` §3 and §11](../AGENTS.md).
|
|
|
|
## Process (read before proposing a change)
|
|
|
|
1. To change a decision, create a **new** ADR with the next number and set `Status: Proposed`,
|
|
`Supersedes: ADR-XXXX`. (Agents draft + escalate; the human approves.)
|
|
2. State what new information invalidates the old decision.
|
|
3. On approval, set the new ADR `Accepted` and the old one `Superseded by: ADR-YYYY`.
|
|
4. Never silently re-interpret an accepted ADR (see [`../AGENTS.md` §3](../AGENTS.md)).
|
|
|
|
## Template
|
|
|
|
```markdown
|
|
# ADR-XXXX — <title>
|
|
- Status: Proposed | Accepted | Superseded by ADR-YYYY
|
|
- Date: <YYYY-MM-DD>
|
|
- Serves: <requirement IDs, e.g. R-NET-01, R-NET-06>
|
|
- Supersedes: <ADR-ZZZZ or —>
|
|
|
|
## Context
|
|
<forces, constraints, why a decision is needed>
|
|
|
|
## Decision
|
|
<what we chose, stated decisively>
|
|
|
|
## Alternatives considered
|
|
<options and why rejected>
|
|
|
|
## Consequences
|
|
<positive, negative, follow-ups, risks>
|
|
```
|
|
|
|
## Index
|
|
|
|
| ADR | Title | Status | Serves |
|
|
|---|---|---|---|
|
|
| [0001](adr-0001-kubernetes-distribution-k3s.md) | Kubernetes distribution: k3s | Accepted | R-PLAT-01 |
|
|
| [0002](adr-0002-cni-cilium.md) | CNI & network policy & ingress: Cilium + Gateway API | Accepted | R-NET-01..07, R-DNS-01 |
|
|
| [0003](adr-0003-storage-longhorn.md) | Distributed storage: Longhorn (+ bulk tier, Velero) | Accepted | R-STATE-01..04 |
|
|
| [0004](adr-0004-gitops-flux.md) | GitOps engine: Flux CD | Accepted | R-GITOPS-01..03 |
|
|
| [0005](adr-0005-vm-workloads-kubevirt.md) | VM workloads: KubeVirt + CDI | Accepted | R-PLAT-03 |
|
|
| [0006](adr-0006-tls-cert-manager-letsencrypt.md) | TLS: cert-manager + Let's Encrypt (DNS-01) | Accepted | R-TLS-01..03 |
|
|
| [0007](adr-0007-secrets-sops-age.md) | Secrets: SOPS + age | Accepted | R-SEC-01 |
|
|
| [0008](adr-0008-vpn-egress-model.md) | VPN egress model: Gluetun sidecar + Cilium Egress Gateway | ~~Superseded by 0012~~ | R-NET-05/06 |
|
|
| [0009](adr-0009-automated-image-updates.md) | Automated updates: Flux image automation + Renovate | Accepted | R-UPD-01..03 |
|
|
| [0010](adr-0010-conformance-testing.md) | Conformance testing: automated, reproducible, behavior-based | Accepted | R-TEST-01..06 |
|
|
| [0011](adr-0011-test-tooling-kyverno-chainsaw.md) | Conformance test tooling: Kyverno + Chainsaw | Accepted | R-TEST-01..05 |
|
|
| [0012](adr-0012-vpn-egress-single-expressvpn-gateway.md) | VPN egress: single shared in-cluster ExpressVPN gateway | ~~Superseded by 0013~~ | R-NET-05/06/07 |
|
|
| [0013](adr-0013-vpn-provider-pia-gluetun-wireguard.md) | VPN provider: PIA over OpenVPN-UDP + port forwarding | Accepted — provider/protocol only (client+steering superseded by 0015) | R-NET-05/06/07 |
|
|
| [0014](adr-0014-idp-keycloak.md) | Identity Provider: Keycloak (SSO via OIDC + forward-auth) | Accepted | R-IDP-01..06 |
|
|
| [0015](adr-0015-vpn-egress-steering-node-tunnel-cilium.md) | VPN egress steering: node-level tunnel + Cilium Egress Gateway (host kill-switch) | Accepted | R-NET-05/06/07 |
|