docker容器将无法启动,因为现有的pid文件

seb*_*elk 23 pid docker

当我启动一个docker容器时,它失败了,因为现有的pid文件:

[root@newhope sergio]# docker logs sharp_shockley 
httpd (pid 1) already running
httpd (pid 1) already running
httpd (pid 1) already running
httpd (pid 1) already running
Run Code Online (Sandbox Code Playgroud)

如何删除这样的文件,因为我找不到它.

[root@newhope sergio]# docker version
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8/1.4.1
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8/1.4.1

[root@newhope sergio]# find / -name "httpd.pid"
find: ‘/run/user/1000/gvfs’: Permiso denegado
Run Code Online (Sandbox Code Playgroud)

sty*_*nsk 29

尝试:

docker-compose down
Run Code Online (Sandbox Code Playgroud)

销毁任何已在运行的环境.

  • 这是错误的 - 做docker-compose down - Stp [并删除容器,在那里丢失容器中的所有已保存数据!检查docker-compose down文档 (3认同)

S'p*_*'Kr 22

经过太多的挫折,我在破碎的phabricator容器中解决了这个问题:

您必须知道http pid文件的名称/路径是什么.在下面的示例中,它位于/run/apache2/apache2.pid容器内部.完成后,运行以下命令:

docker start [container_id]; docker exec [container_id] rm /run/apache2/apache2.pid
Run Code Online (Sandbox Code Playgroud)

这样做是启动容器,然后立即尝试运行命令删除PID文件 - 希望在任何进程docker应该启动之前有时间失败.如果您的容器进程无法快速执行,则可能对您无效.尝试运行几次,你可能会打败它.

为了找到我的PID文件的位置,我做了类似于@sebelk的事情,但是我没有扩展tar文件,而是通过列出其内容并查找正确的文件名来节省一些时间......就像这样:

docker export [container_id] > /tmp/brokecontainercontents.tar
tar -tf /tmp/brokecontainercontents.tar | less 
Run Code Online (Sandbox Code Playgroud)

这很愚蠢,而且可能有更好的方法来查看容器的内容.理想情况下,您可以通过其他方式找到PID文件的名称(欢迎评论!).

顿悟

上面的答案很有用,但我现在意识到我和其他许多人在基础层面上误解了Docker.事实上,@ styonsk的下面的回答是正确的.并且,@ avijendr对它的批评性评论也是正确的:这会破坏容器中的数据 - 但这并不重要.我会解释一下.

我最初被告知Docker"像chroot但更好." 这是真实但有误导性的.在chroot jail中,你的数据存在于jail中(当然它确实存在,被监禁的进程还会看到它吗?).因此,当我开始使用Docker时,我认为Volumes功能是一种获取容器中数据的方法 - 您可以将Volume安装到本地系统并查看其中的内容.当我尝试的时候,我真的被勾掉了,因为好像容器丢失了我的所有数据 - 容器应用程序采取了这种方式,并且本地安装位置没有任何东西!错误的错误.

Docker中的卷将您的本地数据/文件装入容器,而不是相反.因此,当我将卷安装到一个空的本地目录(期望容器中的文件出现)时,将空的本地目录挂载到容器中,隐藏容器中存在的文件并使应用程序看起来像它有丢失了数据(好吧,因为它).实际上,Docker容器甚至在没有安装Volume的情况下工作的事实是一种副作用,并且可以说是有害的.这不是它打算工作的方式.任何写入容器内容量位置的数据都应该是一次性的!

(顺便提一下,我开始通过Kitematic使用Docker,它将在一步中拉动,创建和启动一个容器,而不会询问你想要在哪里安装你的卷,这是我想到的错误想法的一部分......我现在个人认为它不应该启动容器,直到您将卷安装在某处或明确决定不这样做.)

因此,Docker容器的预期用途通常(并且应该)在容器运行应用程序,该容器作用于容器外部数据,即通过本地系统挂载的卷.这意味着,如果容器出现问题,您应该能够销毁容器并启动另一个安装到相同卷的副本 - 您将获得所有数据,因为它首先不在容器中.

因此,@ styonsk的答案是正确的答案:如果你正确使用Docker,你应该能够销毁容器并启动一个新的容器.一方面,这听起来有点矫枉过正,但另一方面,容器化应用程序的要点是你不必知道它内部发生了什么,可以说你不知道...你怎么知道唯一的在一次不干净的关机后,httpd.pid文件仍然存在?可能会有更多搞砸你不知道的事情!这可以说是抽象的目的.

如果该模型不适用于您的用例 - 或者您根本不喜欢它 - 答案可能是您不应该使用Docker容器.这也不是一件坏事,只是你可能试图用菲利普斯的驱动程序安装一个平头螺钉.您可能只需要一个轻量级但全栈的VM环境.


luc*_*ald 5

重建/重建可能会有所帮助. docker-compose up --build --force-recreate <service-name>

此外,主机(物理服务器)可能没有剩余磁盘空间.


seb*_*elk 1

根据 Paul 的评论和 docker 文档,我找到了解决方案:

docker export sharp_shockley > /tmp/sharp_shockley.tar
mkdir /tmp/sharp_shockley
cd /tmp/sharp_shockley/
tar xvf sharp_shockley.tar
rm run/httpd/httpd.pid
rm sharp_shockley.tar
tar -c . | sudo docker import - apache3
Run Code Online (Sandbox Code Playgroud)

然后我必须执行一些小修复,删除 /var/run/httpd 上的临时文件,提交更改,然后我可以再次启动我的容器。

更多信息请访问https://docs.docker.com/reference/commandline/cli/#import Docker 命令行