Skip to content

fix(podman): keep the rootless network alive across a job teardown on Podman 4.9 (#458) - #463

Merged
edgehero merged 1 commit into
mainfrom
fix/458-podman49-netns-keeper
Sep 28, 2026
Merged

edgehero merged 1 commit into
mainfrom
fix/458-podman49-netns-keeper

Conversation

@edgehero

Copy link
Copy Markdown
Owner

Closes #458. #460 (#452) must merge after this.

The defect

On Podman 4.9.3, Ubuntu 24.04's packaged version and the one the required conformance job runs, podman network disconnect of the egress proxy from a per-job network tears down the account's shared rootless network helper while the proxy still runs. It happens whenever no other running container is on a bridge network. Every later egress job then gets 503 until the proxy restarts. Measured with the repo's own createJobNetwork/removeJobNetwork: 200, then 503 four times.

The fix: a keeper

One idle container that keeps the account's rootless network helper alive:

  • runs sleep infinity on a network of its own (--internal, DNS disabled);
  • no port, no mount, no capability, read-only root, no-new-privileges, uid 65534;
  • uses the proxy's own pinned image, so nothing new is pulled;
  • measured on 4.9.3: from inside it, the proxy and 1.1.1.1 are both unreachable, and five sequential egress jobs all get 200.

It ships as a Quadlet pair (deploy/pi-dispatch-netns-keeper.{container,network}, mirrored into worker/deploy/). It is installed wherever the proxy's units are (service install, up), on every Podman version: harmless on 5.x, and simpler than a version read. Restart=always brings it back after an out-of-band stop. SuccessExitStatus=143 keeps a clean stop from reading as failed.

doctor and CI

  • doctor checks the keeper when egress is armed: ✗ on Podman 4.x (or an unreported version) when it is not running.
  • In that state doctor --live does not run its egress canary, its stale-canary sweep or its peer networks, because their own teardown is the trigger. It says why.
  • The conformance job starts the keeper from the shipped units, then runs two egress-armed jobs through the real teardown, re-reading the provider after each. Without the keeper the case fails on 4.9.3; with it, it passes.

docs/podman.md step 6 documents the defect, the keeper, and the aardvark-dns repair for an account already damaged (upstream #20396).

Specs

DES-PODMAN-STACK-AS-QUADLET-UNITS, DES-PODMAN-NATIVE-ROOTLESS-BACKEND, DES-EGRESS-DENY-ON-A-DEDICATED-NETWORK, INT-EGRESS-POLICY-CONTRACT, INT-LIVE-PROBE-CONTRACT.

@edgehero
edgehero force-pushed the fix/458-podman49-netns-keeper branch 5 times, most recently from 8577cb0 to 9329ee2 Compare September 28, 2026 07:49
… Podman 4.9 (#458)

On Podman 4.9.3 (Ubuntu 24.04's), `network disconnect` of the egress
proxy from a per-job network tears down the account's shared rootless
network namespace and its slirp4netns while the proxy still runs,
whenever no other running container is on a bridge network: v4.9.3's
cleanup counts the disconnecting container as the caller. The next
bridge container starts a new namespace, the proxy loses eth0, and
every later egress job gets 503 (measured: 200, then 503 four times).
Podman 5's network rewrite counts attachments; 5.8.1 is unaffected.

A keeper container holds the helper open: one idle `sleep` on a
network of its own (internal, DNS disabled), no port, no mount, no
capability, read-only, uid 65534, the proxy's own pinned image,
RunInit, restarted after 1 s with no start limit, its network
recreated by ExecStartPre after a prune. It ships as a Quadlet pair
installed wherever the proxy's units are (service install, up), on
every Podman version.

It counts only when running in bridge mode on its own network, up for
3 s and not started more than 15 s after the proxy (a keeper that
restarted under a running proxy may have let a teardown break it). On
Podman below 5 with egress armed, the worker's pre-spend preflight
reads it after the proxy and retries the job before anything is
reserved when it does not hold (with its own reason and terminal
comment, and a boot-time warning); doctor fails on it and does not run
its canary or peer networks without it; up restarts the proxy after a
keeper restart; doctor also checks the keeper's network is internal
with DNS off.

service install and up refuse when the user manager's XDG_RUNTIME_DIR
or XDG_CONFIG_HOME is not the account's own (the generator and every
unit inherit them). The conformance job pins both for its account
before the manager starts, starts the keeper from the shipped units,
and runs two egress jobs through the real teardown; without the keeper
it fails.

Specs: DES-PODMAN-STACK-AS-QUADLET-UNITS, DES-PODMAN-NATIVE-ROOTLESS-BACKEND,
DES-EGRESS-DENY-ON-A-DEDICATED-NETWORK, INT-EGRESS-POLICY-CONTRACT,
INT-LIVE-PROBE-CONTRACT, INT-RUN-HISTORY-FILE-CONTRACT, REQ-DEPLOYMENT-BOOTSTRAP.

Signed-off-by: Rob Boerman <robboerman@live.nl>
@edgehero
edgehero force-pushed the fix/458-podman49-netns-keeper branch from 9329ee2 to 0c151da Compare September 28, 2026 08:05
@edgehero
edgehero merged commit d2e3e4e into main Sep 28, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

podman 4.9: a job network teardown cuts the egress proxy off, so every later egress job gets 503

1 participant