Proof-of-concept: expose a service directly on the NetBird mesh
The standalone routing-peer approach can't work: Cilium socketLB only translates a pod's own socket connections, not traffic a peer forwards for mesh clients — so forwarded packets to any ClusterIP/LB VIP are blackholed (confirmed via conntrack: the flow stays [UNREPLIED]). A central terminating proxy would work but is extra machinery to maintain.
This PR validates the third option — the pod itself becomes a mesh peer:
A non-privileged netbird sidecar shares the audiobookshelf pod's network namespace and brings up wt0 there. The pod enrolls as audiobookshelf.nb.renner.uno.
Mesh clients connect straight to the pod's mesh IP:80 — traffic is delivered locally inside the netns. No L3 forwarding, socketLB never in the path.
NET_ADMIN/SYS_ADMIN/SYS_RESOURCE only (the WireGuard minimum); not privileged (the operator's default sidecar is privileged — we override that).
Reuses the existing reusable setup key (new sops secret in the audiobookshelf namespace). The existing audiobookshelf CNP already permits the sidecar's egress (world + kube-dns), so no policy change.
Validate (from a mesh peer)
dig audiobookshelf.nb.renner.uno # → the pod's 100.96.x.x mesh IP
curl http://audiobookshelf.nb.renner.uno # → audiobookshelf directly (no Traefik, no VIP)
A NetBird access policy must allow the client's group to reach this peer's group.
Scope / caveats
Names are under *.nb.renner.uno (NetBird's zone), not the canonical audiobooks.renner.uno. Mapping the canonical names is a separate optional CNAME layer.
Direct exposure = HTTP straight to the pod (no Traefik/TLS in front). Fine for the PoC; TLS/ingress semantics are a later decision.
One sidecar per exposed pod. If this holds up, the choice is manual sidecars vs. the NetBird operator for label-driven injection.
If validated, the now-defunct standalone netbird-ingress routing peer should be removed.
🤖 Generated with Claude Code
## Proof-of-concept: expose a service **directly** on the NetBird mesh
The standalone routing-peer approach can't work: Cilium **socketLB only translates a pod's own socket connections**, not traffic a peer *forwards* for mesh clients — so forwarded packets to any ClusterIP/LB VIP are blackholed (confirmed via conntrack: the flow stays `[UNREPLIED]`). A central terminating proxy would work but is extra machinery to maintain.
This PR validates the third option — **the pod itself becomes a mesh peer**:
- A **non-privileged** netbird sidecar shares the audiobookshelf pod's network namespace and brings up `wt0` there. The pod enrolls as `audiobookshelf.nb.renner.uno`.
- Mesh clients connect **straight to the pod's mesh IP:80** — traffic is delivered locally inside the netns. **No L3 forwarding, socketLB never in the path.**
- `NET_ADMIN`/`SYS_ADMIN`/`SYS_RESOURCE` only (the WireGuard minimum); **not** privileged (the operator's default sidecar *is* privileged — we override that).
- Reuses the existing reusable setup key (new sops secret in the `audiobookshelf` namespace). The existing audiobookshelf CNP already permits the sidecar's egress (`world` + kube-dns), so no policy change.
### Validate (from a mesh peer)
```
dig audiobookshelf.nb.renner.uno # → the pod's 100.96.x.x mesh IP
curl http://audiobookshelf.nb.renner.uno # → audiobookshelf directly (no Traefik, no VIP)
```
A NetBird **access policy** must allow the client's group to reach this peer's group.
### Scope / caveats
- Names are under `*.nb.renner.uno` (NetBird's zone), not the canonical `audiobooks.renner.uno`. Mapping the canonical names is a separate optional CNAME layer.
- Direct exposure = HTTP straight to the pod (no Traefik/TLS in front). Fine for the PoC; TLS/ingress semantics are a later decision.
- One sidecar per exposed pod. If this holds up, the choice is manual sidecars vs. the NetBird operator for label-driven injection.
If validated, the now-defunct standalone `netbird-ingress` routing peer should be removed.
🤖 Generated with Claude Code
Proof-of-concept for "direct mesh exposure" — the alternative to the
standalone routing peer, which can't deliver mesh traffic to cluster
LoadBalancer/ClusterIP VIPs (Cilium socket-LB only translates a pod's
OWN socket connections, not traffic a peer forwards on behalf of mesh
clients; confirmed via conntrack on netbird-ingress).
Here a non-privileged netbird sidecar shares the audiobookshelf pod's
network namespace, so the pod becomes its own mesh peer
(audiobookshelf.nb.renner.uno). Mesh clients connect straight to the
pod's mesh IP:80 — traffic is delivered locally inside the netns, so
there is no L3 forwarding and socket-LB is never in the path.
- non-privileged; NET_ADMIN/SYS_ADMIN/SYS_RESOURCE (WireGuard minimum)
- reuses the existing reusable setup key (new sops secret in this ns)
- existing audiobookshelf CNP already permits the sidecar's egress
(world + kube-dns), so no network-policy change needed
Validation: from a mesh peer, `dig audiobookshelf.nb.renner.uno` then
`curl http://audiobookshelf.nb.renner.uno` — expect the app directly,
no Traefik, no VIP. A NetBird access policy must allow the client's
group to reach this peer's group.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Proof-of-concept: expose a service directly on the NetBird mesh
The standalone routing-peer approach can't work: Cilium socketLB only translates a pod's own socket connections, not traffic a peer forwards for mesh clients — so forwarded packets to any ClusterIP/LB VIP are blackholed (confirmed via conntrack: the flow stays
[UNREPLIED]). A central terminating proxy would work but is extra machinery to maintain.This PR validates the third option — the pod itself becomes a mesh peer:
wt0there. The pod enrolls asaudiobookshelf.nb.renner.uno.NET_ADMIN/SYS_ADMIN/SYS_RESOURCEonly (the WireGuard minimum); not privileged (the operator's default sidecar is privileged — we override that).audiobookshelfnamespace). The existing audiobookshelf CNP already permits the sidecar's egress (world+ kube-dns), so no policy change.Validate (from a mesh peer)
A NetBird access policy must allow the client's group to reach this peer's group.
Scope / caveats
*.nb.renner.uno(NetBird's zone), not the canonicalaudiobooks.renner.uno. Mapping the canonical names is a separate optional CNAME layer.If validated, the now-defunct standalone
netbird-ingressrouting peer should be removed.🤖 Generated with Claude Code