如何终止Docker中运行的‘隐形’容器?及docker-proxy相关疑问
问题描述
在Ubuntu 22.04系统中,通过snap安装Docker后,使用docker run ...命令启动容器一切正常。之后通过apt安装docker-compose,尝试用其启动容器时,提示端口9091已被占用。
执行以下命令排查端口占用情况:
sudo lsof -i :9091
输出结果:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME docker-pr 1883 root 4u IPv4 28696 0t0 TCP *:9091 (LISTEN) docker-pr 1890 root 4u IPv6 27395 0t0 TCP *:9091 (LISTEN)
再执行:
sudo netstat -pna | grep 9091
输出结果:
tcp 0 0 0.0.0.0:9091 0.0.0.0:* LISTEN 1883/docker-proxy tcp6 0 0 :::9091 :::* LISTEN 1890/docker-proxy
结果显示端口被docker-proxy占用,但执行docker ps -a却看不到任何运行或已停止的容器。需解答以下问题:
- docker-proxy是什么服务?
- 为何这类“隐形”容器无法通过
docker rm $(docker ps -aq)命令终止? - 为何容器会变成隐形状态,只能通过重启Docker服务才能停止?
问题解答
1. docker-proxy是什么服务?
docker-proxy是Docker内置的网络代理进程,核心作用是实现宿主机端口与容器端口的流量转发。当你启动容器并使用-p或-P参数映射端口时,Docker会自动启动对应docker-proxy进程,负责将访问宿主机对应端口的请求转发到容器内的目标端口,IPv4和IPv6端口会分别启动独立的进程。
2. 为何这类“隐形”容器无法通过docker rm $(docker ps -aq)命令终止?
docker rm只能操作Docker daemon所追踪管理的容器实例。出现这种情况时,对应的容器已经意外终止,但docker-proxy进程没有被Docker daemon正确清理,属于脱离Docker管理的“孤儿进程”。此时docker ps -aq无法列出对应容器的ID,自然无法通过docker rm命令终止这些代理进程。
3. 为何容器会变成隐形状态,只能通过重启Docker服务才能停止?
这种状态异常通常是Docker daemon与容器、代理进程之间的状态同步失效导致的,常见原因包括:
- snap安装的Docker与apt安装的
docker-compose版本不兼容,跨包管理工具的安装方式导致容器管理时出现状态不同步。 - 容器被强制终止(比如直接用
kill命令结束容器进程而非docker stop),Docker daemon未能及时感知并清理对应的docker-proxy进程。 - Docker daemon本身存在状态追踪bug,导致进程关联关系丢失。
重启Docker服务会强制终止所有由Docker管控的进程(包括这些孤儿docker-proxy),并重新初始化状态同步,因此能解决端口占用问题。
内容的提问来源于stack exchange,提问作者hedche
相关产品推荐
相关产品推荐

