9 decisions (D-255..D-263) resolved: podman container model, --network host, mounted step-ca CA, dynamic config volume mount, floating-IP LXC registered as linux node, IngressMode on model.Node, MAC generation rules, native-mode DNAT target = LXC IP, LXC nesting. ---ci--- project: orca phase: 0 milestone: v0.14 status: clarify ---/ci---
5.8 KiB
CLARIFY v0.14: Ingress Bootstrap Completeness
Autonomy: full (config autonomy.level = "full")
Budget: 10 questions (used: 5 interactive, 5 auto-resolved)
Result: all ambiguities resolved; 9 decisions (D-255..D-263) recorded in PROJECT.md
Interactive Questions (resolved with operator)
Q1: iptables vs nft emitter
Ambiguity: Codebase is nft-only (D-218). Operator said "iptables used for SNAT/DNAT".
Resolution: D-255 (partial) — Extend the existing nft emitter (internal/emitter/nft.go) with SNAT/MASQUERADE postrouting rules. "iptables" in the operator's description is read as "kernel NAT" — nft is the modern backend. No literal iptables emitter.
Confidence: 0.95
Q2: ingress LXC lifecycle
Ambiguity: Should the floating-IP LXC be registered as an orca-managed node or left as a one-shot external proxy?
Resolution: D-259 — Register as a managed linux node (name=ingress, addr=<floating-ip>:8443). orca job run pushes traefik dynamic config to it like any linux node. This makes routing-to-other-hosts work.
Confidence: 0.92
Q3: Floating-IP network topology
Ambiguity: Where does SNAT run and how does the LXC get the public IP?
Resolution: LXC owns floating IP on eth0 (net0 bridge=vmbr0,hwaddr=<mac>,ip=<floating-ip>/<prefix>,gw=<gateway>). nft runs inside the LXC. Matches Hetzner/OVH floating-IP-with-MAC model.
Confidence: 0.90
Q4: TLS cert resolver in the image
Ambiguity: The emitted static config references certResolver: orca but never declares the certificatesResolvers.orca block. v0.11 claimed P10 would wire step-ca but it was never implemented.
Resolution: D-257 — Bake a certificatesResolvers.orca.tls: { } block pointing at a mounted /etc/orca/step-ca-root.crt CA file. No ACME (offline-first, R-001). If the file is absent at start, traefik logs a warning and serves plain HTTP (graceful degradation). The orca bootstrap pushes the cluster root CA into the container volume.
Confidence: 0.90
Q5: Container networking
Ambiguity: nft DNAT targets 127.0.0.1:8080/8443 on the host. How does the podman container receive that traffic?
Resolution: D-256 — --network host so traefik binds 127.0.0.1:8080/8443 directly on the host (or LXC) loopback. No container port publishing. Simplest, matches the hybrid R-017 model.
Confidence: 0.92
Q6: Dynamic config volume strategy
Ambiguity: How does the podman traefik container consume dynamic config? Today orca job run writes /etc/traefik/dynamic/orca-<svc>.yaml on the host.
Resolution: D-258 — Mount /etc/traefik/dynamic from host (-v /etc/traefik/dynamic:/etc/traefik/dynamic:Z). Zero changes to the existing deployRemote WriteFile path. The image's file provider watches /etc/traefik/dynamic as today.
Confidence: 0.95
Auto-resolved questions (full autonomy, no operator interaction)
Q7: Floating-IP mode — does the PVE host also register as a node?
Ambiguity: In floating-IP mode, only the ingress LXC handles traffic. Does the PVE host also get registered?
Resolution: D-259 — Yes. The PVE host registers as a proxmox node (for pct/qm workload dispatch). The ingress LXC registers as a linux node (for traefik dynamic config pushes). Both are in the registry.
Confidence: 0.92
Q8: --ingress-mode persistence
Ambiguity: Should --ingress-mode be stored on the node record so doctor ingress knows which check path to run?
Resolution: D-260 — Yes. Add IngressMode field to model.Node + a schema migration (0007). Values: "" (legacy/default for linux/localhost), "native", "floating-ip".
Confidence: 0.90
Q9: MAC generation when --mac omitted
Ambiguity: In floating-IP mode, if --mac is not provided, should orca generate one or require it?
Resolution: D-261 — Interactive mode: generate a random locally-administered MAC (02:XX:XX:XX:XX:XX) and print it for operator confirmation. --json mode: require --mac explicitly (no silent generation — non-interactive means explicit inputs).
Confidence: 0.88
Q10: Proxmox native nft DNAT target
Ambiguity: In native mode, traefik runs inside an LXC. LXC has its own network namespace. nft DNAT to 127.0.0.1:8443 on the PVE host would NOT reach a container inside an LXC (different loopback). What's the DNAT target?
Resolution: D-262 — The nft DNAT target is parameterized via NftClusterConfig.DNATTarget (default 127.0.0.1:8443). For proxmox native mode, the DNAT target is the LXC's bridge IP (<lxc-ip>:8443). The LXC gets a DHCP/static bridge IP; orca discovers it after pct start via pct list or pct inspect.
Confidence: 0.90
Additional decisions (derived from constraints, no ambiguity)
D-263: LXC podman requirements
Ubuntu 24.04 LXC template does not have podman preinstalled. Bootstrap must:
pct createwith--features nesting=1,keyctl=1(required for podman in unprivileged LXC)- After LXC start:
apt-get update && apt-get install -y podman nftablesinside the LXC - Then
podman pull orca-traefik:<tag>+podman run ...
This adds ~30-60s to the join time. Documented in docs/uat.md.
Image tag strategy
The orca-traefik image uses the same version tag as the orca release (v0.13.x line). The podman reconciler resolves the tag from internal/cli.version. In dev builds (version="dev"), it falls back to latest.
Registry auth
The orca-traefik image is in the same registry/org as orca (git.cloudinit.dev/coreci/). Pulls are anonymous (REQ-045, repo is public). No podman login needed on workers.
Requirements impact
No new requirements beyond REQ-171..REQ-179 (already in REQUIREMENTS.md). The clarify stage confirmed scope and resolved all implementation ambiguities. The 9 decisions (D-255..D-263) are recorded in PROJECT.md.