"docker container prune" 和 "docker rm $(docker container ls -aq)" 的区别是什么?

7
我正在阅读Docker文档,但是我不理解以下两个命令的区别: docker container prunedocker rm $(docker container ls -aq) 请注意,在链接中,我列出的第二个命令是docker rm $(docker ps -a -q),但这与我写的没有区别。 container ls只是ps命令的新版本
看起来这两个命令都会删除所有已停止的容器。除此之外,还有其他的区别吗?或者它们只是同义词?

你为什么期望做不同的事情呢?我的意思是一个是命令,而另一个是两个命令被管道连接起来。其实它们没有区别,prune只是旧版docker rm $(docker ps -a -q)的简写,正如你所指出的,docker container ls只是一个新的API。我猜测ps太过于依赖UNIX操作系统,而另一个则更加清晰易懂。但这只是我的猜测。 - nax
@nax:我认为文档通常会尽可能避免冗余。如果它们纯粹是同义词,那么它们在同一文档中有不同的、未链接的专用部分,这让我感到很奇怪。 - marcman
3个回答

3
这两个命令的效果确实相似,但需要考虑一些细微差别:
  • docker container prune 可以使用 --filter 选项。
  • docker container prune 具有同步保护功能,可以阻止守护程序上并发执行 prune
  • docker container prune 尝试仅删除未运行的容器,而不是尝试删除所有容器并依靠守护程序抛出异常来删除那些未停止的容器。因此,它更快,并且在跟踪守护程序日志的情况下不会生成不必要的错误日志。
  • docker container prune 在执行结束时生成报告,提供了回收的空间。该报告添加在 daemon.EventsService 中,并隐式显示在屏幕上。
  • docker container prune 更短

最后我有一个问题:为什么有人要多输入15个字符来获得相同或更差的结果呢?


2

我认为两者没有实质性的区别。然而,-a 的含义是列出所有容器,因此 docker rm ... 命令也会尝试删除正在运行的容器。这将导致下面所示的错误:

来自守护程序的错误响应:您无法删除正在运行的容器 [...] 在尝试强制删除之前,请停止容器。

示例

$ docker container run --rm -itd alpine:latest 
0ec4d7459d35749ecc24cc5c6fd748f4254b0782f73f1ede76cf49b1fc53b2d4

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
0ec4d7459d35        alpine:latest       "/bin/sh"           4 seconds ago       Up 1 second                             jovial_ritchie

$ docker rm $(docker container ls -aq)
Error response from daemon: You cannot remove a running container 0ec4d7459d35749ecc24cc5c6fd748f4254b0782f73f1ede76cf49b1fc53b2d4. Stop the container before attempting removal or force remove

$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

但是...当使用--force-f时有所不同:

在这种情况下,这两个命令会执行两件不同的事情:

  • docker rm -f ... Forces the removal of a running container (uses SIGKILL) which means that it will remove running containers.

    $ docker rm -f $(docker container ls -aq)
    0ec4d7459d35
    
  • docker container prune -f will remove all stopped containers without asking for confirmation (no [y/N] prompt will be printed).

    $ docker container prune -f
    Total reclaimed space: 0B
    

1
你说得对。prune 命令只是当这个命令不存在时每个人都会做的事情的演变,事实上我已经习惯了旧命令,从不使用 prune,但它们是一样的。 - nax
@nax,你知道“prune”命令是什么时候引入的吗?出于好奇,我挖掘了我旧代码中能找到的最早版本的Docker,它的日期可以追溯到5年前,而“prune”命令已经存在了。我记得自从开始使用Docker的第一天起就一直在使用“prune”。 - Neo Anderson
2
Docker引擎发布说明在此处找到:1.13.1 (2017-02-08),指向了这个讨论:https://github.com/moby/moby/pull/26108,因此应该是在2016年底/2017年初。 - tgogos
2
@NeoAnderson 在文档中可以看到它需要 Docker 1.25+,所以在那个时候已经正式发布了,但正如 tgogos 指出的那样,它在 1.31.1 上已经开始流传了。我变老了... - nax

1

docker system prune -f:删除所有已停止的容器(Docker 不会触及正在运行的容器)

docker system prune -a:删除所有已停止的容器(Docker 不会触及正在运行的容器)+ 未使用的镜像

docker rm <container_id>:删除特定容器,应先停止它(docker stop <container_id>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接