Both the per-edge teardown and the startup purge remove a container's /etc/hosts entries via docker exec.
Docker refuses exec on a paused container ("Container … is paused, unpause the container before exec"), and the failure is swallowed — container_hosts returns None and the container is skipped.
Paused containers are enumerated by docker ps -q, so they look handled.
Stopped containers aren't enumerated at all.
The result is a container holding a mapping to an overlay IP whose tunnel no longer exists.
On resume it resolves the name to a dead address and hangs, which is strictly worse than falling through to public DNS.
This is not a corner case.
The server sends the teardown and then the suspend (decrement_chain), both unacked, and the client handles each in its own task.
The pause fires exactly when the last client goes away, which is exactly when the teardown fires.
If the suspend wins, the entry is stranded.
Fix: write /var/lib/docker/containers/<id>/hosts directly instead of going through docker exec, and enumerate with docker ps -aq.
That file is bind-mounted into the container and stays readable and writable while it is paused or stopped, so it covers all three cases and removes the exec round trip as well.
Both the per-edge teardown and the startup purge remove a container's
/etc/hostsentries viadocker exec.Docker refuses
execon a paused container ("Container … is paused, unpause the container before exec"), and the failure is swallowed —container_hostsreturnsNoneand the container is skipped.Paused containers are enumerated by
docker ps -q, so they look handled.Stopped containers aren't enumerated at all.
The result is a container holding a mapping to an overlay IP whose tunnel no longer exists.
On resume it resolves the name to a dead address and hangs, which is strictly worse than falling through to public DNS.
This is not a corner case.
The server sends the teardown and then the suspend (
decrement_chain), both unacked, and the client handles each in its own task.The pause fires exactly when the last client goes away, which is exactly when the teardown fires.
If the suspend wins, the entry is stranded.
Fix: write
/var/lib/docker/containers/<id>/hostsdirectly instead of going throughdocker exec, and enumerate withdocker ps -aq.That file is bind-mounted into the container and stays readable and writable while it is paused or stopped, so it covers all three cases and removes the exec round trip as well.