- 31 new managed skills (anubis/arr/authentik/hermes/freetoken/podman/llm-swap runbooks etc.) now tracked. - Removed superseded skills: omp_harness_config, peon_ping_integration (replaced by user-authored peon-ping-* managed skills), rocmfp4-strix-benchmark-orchestration. - New memory-root skills: niri_compositor_ops, omp_git_workflow, omp_model_config, quadlet-media-migration, homelab-service-triage, hermes-dankclaw-ops, frank-default-large-ops, caddy-auth-dns-playbook.
2.8 KiB
2.8 KiB
name, description
| name | description |
|---|---|
| podman-netns-addressability-probe | Runbook to answer "can container X actually reach service Y" on a rootless-podman/netavark host, instead of assuming localhost works everywhere; includes the probe commands and the false-positive traps. |
Podman netns addressability probe
Answer "can this container actually dial that service?" per network namespace,
not per host. On rootless podman + netavark, a bridge-net container cannot reach
host-netns loopback listeners at all, so localhost:PORT reasoning is wrong for it.
Decision rule
NetworkMode=host→ the container is the host netns: dials everything on127.0.0.1, binds any free port.- bridge/named network → own netns. Only published ports are reachable, via the
network's gateway IP. Unpublished host listeners are refused instantly (RST),
not routed — even when the listener is bound
0.0.0.0.
Probe sequence (all read-only, run on the host)
- Namespace:
podman inspect <name> --format '{{.HostConfig.NetworkMode}}' - Owner of a listener:
sudo ss -ltnp 'sport = :<port>'(host netns only — this is why a0.0.0.0listener can still be unreachable from a bridge net). - From inside the suspect container:
podman exec <name> cat /proc/net/route→ default route = gateway IP to dial. - Probe the candidate address inside that netns:
podman exec <name> sh -c 'timeout 2 bash -c "exec 3<>/dev/tcp/<gw-ip>/<port>"; echo rc=$?'
Interpretation (do not blur these)
- instant refusal = nothing listening in a reachable namespace (or rootlessport rejected an unpublished port map).
- timeout = no route to that address at all.
host.containers.internal(169.254.1.2) is an alias on the defaultpodmannet only; containers on a named network time out against it rather than being refused.
Probe-tool gotchas verified on this host (podman 5.x, netavark)
podman network inspect <net> --format '{{json .containers}}'errors (can't evaluate field containers in type interface {}) — membership is not exposed there. List from the container side instead:podman ps -a --format '{{.Names}} {{.Networks}}'- An empty
Networksfield in that output = host network or a shared namespace (--network=container:<other>), not "no network". - Quadlet
Network=<name>.networkyields runtime network namesystemd-<name>; probe withpodman network ls, never by the.networkfilename.
Fix options when a bridge-net container must reach a host-netns listener
(a) move it to Network=host, or (b) publish the port — (b) makes that port reachable
from every namespace and the LAN, so it is an exposure change needing explicit
operator approval, never a silent fix.
Repo source of truth for this fleet: serverAppConfigs-docs/Architecture/Container Network Namespaces.md (commit 2e179b0).