Docker 镜像和容器有什么区别?

新手上路,请多包涵

使用 Docker 时,我们从基础镜像开始。我们启动它,创建更改,这些更改保存在形成另一个图像的层中。

所以最终我有一个我的 PostgreSQL 实例的图像和一个我的 web 应用程序的图像,对它们的更改继续被持久化。

什么是容器?

原文由 Bibek Shrestha 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 396
2 个回答

图像的一个实例称为容器。您有一个图像,它是您描述的一组图层。如果你启动这个镜像,你就有了这个镜像的运行容器。您可以拥有多个运行同一映像的容器。

您可以使用 --- 查看所有图像,而使用 docker images 查看正在运行的容器(您可以使用 docker ps docker ps -a 查看所有容器)。

因此,图像的运行实例是一个容器。

原文由 Thomas Uhrig 发布,翻译遵循 CC BY-SA 3.0 许可协议

来自我关于 自动化 Docker 部署 的文章(已存档):

Docker 映像与容器

在 Dockerland 中,有 镜像,也有 容器。两者密切相关,但又截然不同。对我来说,掌握这种二分法已经极大地阐明了 Docker。

什么是图像?

映像是一个惰性的、不可变的文件,它本质上是一个容器的快照。图像是使用 build 命令创建的,当使用 run 启动时它们会生成一个容器。图像存储在 Docker 注册表中,例如 registry.hub.docker.com 。因为它们可以变得非常大,所以图像被设计为由其他图像层组成,从而在通过网络传输图像时允许发送最少量的数据。

可以通过运行 docker images 列出本地图像:

 REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                    13.10               5e019ab7bf6d        2 months ago        180 MB
ubuntu                    14.04               99ec81b80c55        2 months ago        266 MB
ubuntu                    latest              99ec81b80c55        2 months ago        266 MB
ubuntu                    trusty              99ec81b80c55        2 months ago        266 MB
<none>                    <none>              4ab0d9120985        3 months ago        486.5 MB

需要注意的一些事项:

  1. IMAGE ID 是图像真实标识符的前 12 个字符。您可以为给定图像创建多个标签,但它们的 ID 都相同(如上)。
  2. VIRTUAL SIZE 是 虚拟 的,因为它将所有不同底层的大小相加。这意味着该列中所有值的总和可能比所有这些图像使用的磁盘空间大得多。
  3. REPOSITORY 列中的值来自 docker build 命令的 -t 标志,或来自 docker tag 现有图像。您可以使用对您有意义的命名法来标记图像,但要知道 docker 将使用标记作为 docker pushdocker pull 中的注册表位置。
  4. 标签的完整形式是 [REGISTRYHOST/][USERNAME/]NAME[:TAG] 。对于 ubuntu 以上,REGISTRYHOST 被推断为 registry.hub.docker.com 。因此,如果您打算将名为 my-application 的图像存储在 docker.example.com 的注册表中,则应该标记该图像 docker.example.com/my-application
  5. TAG 列只是 完整 标签的 [:TAG] 部分。这是不幸的术语。
  6. latest 标签并不神奇,它只是您不指定标签时的默认标签。
  7. 您可以拥有只能通过其 IMAGE ID 识别的未标记图像。这些将获得 <none> TAG 和 REPOSITORY。很容易忘记它们。

有关图像的更多信息,请参阅 Docker 文档词汇表

什么是容器?

用编程的比喻来说,如果图像是一个类,那么容器就是一个类的实例——一个运行时对象。希望容器是您使用 Docker 的原因;它们是运行应用程序的环境的轻量级和可移植封装。

使用 docker ps 查看本地运行的容器:

 CONTAINER ID        IMAGE                               COMMAND                CREATED             STATUS              PORTS                    NAMES
f2ff1af05450        samalba/docker-registry:latest      /bin/sh -c 'exec doc   4 months ago        Up 12 weeks         0.0.0.0:5000->5000/tcp   docker-registry

在这里,我正在运行 docker 注册表的 docker 化版本,这样我就有了一个私有的地方来存储我的图像。再次,有几点需要注意:

  1. 与 IMAGE ID 一样,CONTAINER ID 是容器的真实标识符。它具有相同的形式,但它标识了不同种类的对象。
  2. docker ps 只输出 正在运行的 容器。您可以使用 docker ps -a 查看所有容器( 运行 或 _停止_)。
  3. NAMES 可用于通过 --name 标志来识别已启动的容器。

如何避免图像和容器堆积

我对 Docker 的早期挫败感之一是 看似不断地积累未标记的图像和停止的容器。在少数情况下,这种堆积会导致硬盘驱动器容量最大化,从而减慢我的笔记本电脑速度或停止我的自动构建管道。谈论“无处不在的容器”!

我们可以通过结合 docker rmi 与最近的 dangling=true 查询来删除所有未标记的图像:

 docker images -q --filter "dangling=true" | xargs docker rmi

Docker 将无法删除现有容器后面的映像,因此您可能必须首先使用 docker rm 删除已停止的容器:

 docker rm `docker ps --no-trunc -aq`

这些是 Docker 的 已知痛点,可能会在未来的版本中得到解决。但是,如果对图像和容器有清楚的了解,可以通过以下几种做法来避免这些情况:

  1. 始终使用 docker rm [CONTAINER_ID] 删除无用的已停止容器。
  2. 始终使用 docker rmi [IMAGE_ID] 删除无用的已停止容器后面的图像。

原文由 calebds 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题