如何有效且更快地终止大量 docker 容器进程?

how to kill lots of docker container processes effectively and faster?

我们正在结合使用 Jenkins 和 Docker.. 我们已经将 Jenkins 设置为 master/slave 模型,并且容器在从属代理中启动。 有时由于 jenkins docker 插件中的错误或出于某些未知原因,容器会悬空。

杀死它们都需要时间,每个容器进程大约需要 5 秒,我们有大约 15000 个。完成清理工作需要大约 24 小时 运行。我怎样才能一次移除一堆容器?或者有效地减少时间?

  1. 会卸载 docker 客户端,删除容器吗?
  2. 是否有可以删除这些容器进程的卷(坏主意)
  3. 任何 threading/parallelism 可以更快地删除它们? 我打算每周 运行 执行 cron 作业来修补这些错误,但现在我没有一整天的时间来删除这些错误。

所以,

docker kill $(docker ps -a -q)

这不是你需要的吗?

编辑:显然不是。我的下一个目标是:

A) 以某种方式创建您要停止的所有容器的列表。

B) 对该列表进行分区(可能只是将其切成 n 部分)。

C) 并行启动 n 个作业,每个作业都在处理这些列表切片中的一个。

D) 希望 "docker" 足够健壮,能够处理 n 个进程并行发送 n 顺序终止请求。

E) 如果真的有效:也许开始试验以确定 n 的最佳设置。

试试这个:

  1. 卸载docker-引擎
  2. 重启主机
  3. 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

对正在发生的事情的清晰解释:

  1. 我要求 docker 引擎提供所有 运行 容器(docker ps)的 "full container ID only" 列表
  2. 我正在通过 docker inspect 一个一个地传递它,要求只输出进程 ID (.State.Pid),
  3. 然后我传给kill -9让系统直接杀掉容器进程;比等待引擎这样做要快得多。

同样,不建议将其用于一般用途,因为它不允许对容器化进程进行标准(干净)退出处理,但在您的情况下,这听起来并不重要。

如果这些退出的容器有剩余的容器元数据,您可以使用以下方法清除它:

docker rm $(docker ps -q -a --filter status=exited)

这将从引擎的元数据存储(/var/lib/docker 内容)中删除所有退出的容器,每个容器应该相对较快。