如何有效且更快地终止大量 docker 容器进程?
how to kill lots of docker container processes effectively and faster?
我们正在结合使用 Jenkins 和 Docker.. 我们已经将 Jenkins 设置为 master/slave 模型,并且容器在从属代理中启动。
有时由于 jenkins docker 插件中的错误或出于某些未知原因,容器会悬空。
杀死它们都需要时间,每个容器进程大约需要 5 秒,我们有大约 15000 个。完成清理工作需要大约 24 小时 运行。我怎样才能一次移除一堆容器?或者有效地减少时间?
- 会卸载 docker 客户端,删除容器吗?
- 是否有可以删除这些容器进程的卷(坏主意)
- 任何 threading/parallelism 可以更快地删除它们?
我打算每周 运行 执行 cron 作业来修补这些错误,但现在我没有一整天的时间来删除这些错误。
所以,
docker kill $(docker ps -a -q)
这不是你需要的吗?
编辑:显然不是。我的下一个目标是:
A) 以某种方式创建您要停止的所有容器的列表。
B) 对该列表进行分区(可能只是将其切成 n 部分)。
C) 并行启动 n 个作业,每个作业都在处理这些列表切片中的一个。
D) 希望 "docker" 足够健壮,能够处理 n 个进程并行发送 n 顺序终止请求。
E) 如果真的有效:也许开始试验以确定 n 的最佳设置。
试试这个:
- 卸载docker-引擎
- 重启主机
rm /var/lib/docker
重新启动会有效地停止所有容器,卸载 docker 会阻止它们在重新启动时返回。 (如果他们设置了 restart=always
)
如果您只想杀死进程,因为它们没有正常退出(我对您的意思的评估——如果我错了请纠正我),有一种方法可以走 运行容器使用容器元数据中的 Pid
信息处理并杀死它们。看起来您此时不一定关心干净的进程关闭(这就是 docker kill
每个容器花费这么长时间的原因——容器可能无法响应正确的信号,因此引擎会耐心等待,并且然后终止进程),然后 kill -9
是结束这些容器并清理的更 swift 和极端的方法。
使用最新 docker 版本的快速测试显示我可以在相对现代的笔记本电脑上在 11.5 秒内杀死约 100 个容器:
$ time docker ps --no-trunc --format '{{.ID}}' | xargs -n 1 docker inspect --format '{{.State.Pid}}' | xargs -n 1 sudo kill -9
real 0m11.584s
user 0m2.844s
sys 0m0.436s
对正在发生的事情的清晰解释:
- 我要求 docker 引擎提供所有 运行 容器(
docker ps
)的 "full container ID only" 列表
- 我正在通过
docker inspect
一个一个地传递它,要求只输出进程 ID (.State.Pid
),
- 然后我传给
kill -9
让系统直接杀掉容器进程;比等待引擎这样做要快得多。
同样,不建议将其用于一般用途,因为它不允许对容器化进程进行标准(干净)退出处理,但在您的情况下,这听起来并不重要。
如果这些退出的容器有剩余的容器元数据,您可以使用以下方法清除它:
docker rm $(docker ps -q -a --filter status=exited)
这将从引擎的元数据存储(/var/lib/docker
内容)中删除所有退出的容器,每个容器应该相对较快。
我们正在结合使用 Jenkins 和 Docker.. 我们已经将 Jenkins 设置为 master/slave 模型,并且容器在从属代理中启动。 有时由于 jenkins docker 插件中的错误或出于某些未知原因,容器会悬空。
杀死它们都需要时间,每个容器进程大约需要 5 秒,我们有大约 15000 个。完成清理工作需要大约 24 小时 运行。我怎样才能一次移除一堆容器?或者有效地减少时间?
- 会卸载 docker 客户端,删除容器吗?
- 是否有可以删除这些容器进程的卷(坏主意)
- 任何 threading/parallelism 可以更快地删除它们? 我打算每周 运行 执行 cron 作业来修补这些错误,但现在我没有一整天的时间来删除这些错误。
所以,
docker kill $(docker ps -a -q)
这不是你需要的吗?
编辑:显然不是。我的下一个目标是:
A) 以某种方式创建您要停止的所有容器的列表。
B) 对该列表进行分区(可能只是将其切成 n 部分)。
C) 并行启动 n 个作业,每个作业都在处理这些列表切片中的一个。
D) 希望 "docker" 足够健壮,能够处理 n 个进程并行发送 n 顺序终止请求。
E) 如果真的有效:也许开始试验以确定 n 的最佳设置。
试试这个:
- 卸载docker-引擎
- 重启主机
rm /var/lib/docker
重新启动会有效地停止所有容器,卸载 docker 会阻止它们在重新启动时返回。 (如果他们设置了 restart=always
)
如果您只想杀死进程,因为它们没有正常退出(我对您的意思的评估——如果我错了请纠正我),有一种方法可以走 运行容器使用容器元数据中的 Pid
信息处理并杀死它们。看起来您此时不一定关心干净的进程关闭(这就是 docker kill
每个容器花费这么长时间的原因——容器可能无法响应正确的信号,因此引擎会耐心等待,并且然后终止进程),然后 kill -9
是结束这些容器并清理的更 swift 和极端的方法。
使用最新 docker 版本的快速测试显示我可以在相对现代的笔记本电脑上在 11.5 秒内杀死约 100 个容器:
$ time docker ps --no-trunc --format '{{.ID}}' | xargs -n 1 docker inspect --format '{{.State.Pid}}' | xargs -n 1 sudo kill -9
real 0m11.584s
user 0m2.844s
sys 0m0.436s
对正在发生的事情的清晰解释:
- 我要求 docker 引擎提供所有 运行 容器(
docker ps
)的 "full container ID only" 列表 - 我正在通过
docker inspect
一个一个地传递它,要求只输出进程 ID (.State.Pid
), - 然后我传给
kill -9
让系统直接杀掉容器进程;比等待引擎这样做要快得多。
同样,不建议将其用于一般用途,因为它不允许对容器化进程进行标准(干净)退出处理,但在您的情况下,这听起来并不重要。
如果这些退出的容器有剩余的容器元数据,您可以使用以下方法清除它:
docker rm $(docker ps -q -a --filter status=exited)
这将从引擎的元数据存储(/var/lib/docker
内容)中删除所有退出的容器,每个容器应该相对较快。