提问者:小点点

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


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

所以最终我有了一个用于我的PostgreSQL实例的映像和一个用于我的web应用程序的映像,对这些映像的更改将持续保持。

什么是容器?


共2个答案

匿名用户

图像的实例称为容器。您有一个图像,它是您描述的一组层。如果启动这个映像,那么就有了这个映像的一个正在运行的容器。您可以有许多相同映像的运行容器。

您可以使用Docker images看到您的所有映像,而您可以使用Docker ps看到您正在运行的容器(您可以使用Docker PS-A)看到所有容器。

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

匿名用户

摘自我关于自动化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. 图像ID是图像的真实标识符的前12个字符。您可以创建给定图像的许多标记,但它们的ID都将相同(如上)。
  2. 虚拟大小是虚拟的,因为它是将所有不同的底层的大小相加。这意味着该列中所有值的总和可能比所有这些映像使用的磁盘空间大得多。
  3. 存储库列中的值来自docker build命令的-t标志,或者来自docker tag-ing现有映像。您可以自由地使用对您有意义的命名来标记图像,但要知道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]部分。这是一个不幸的术语。
  6. 最新标记并不神奇,它只是不指定标记时的默认标记。
  7. 您可以使用仅可通过其图像ID识别的未标记图像。这些将获得标记和存储库。很容易忘记它们。

有关图像的更多信息可从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注册表的dockerized版本,这样我就有了一个私有的地方来存储我的图像。还有一些需要注意的事情:

  1. 与映像ID一样,容器ID是容器的真正标识符。它的形式相同,但标识的对象不同。
  2. Docker PS仅输出正在运行的容器。您可以使用Docker ps-a查看所有容器(正在运行或已停止)。
  3. 名称可用于通过--name标志标识已启动的容器。

我早期对Docker的一个不满是,没有标记的图像和停止的容器似乎在不断地建立。在一些情况下,这种构建会导致硬盘耗尽,使我的笔记本电脑变慢,或者使我的自动构建管道中断。说说“到处都是集装箱”!

通过将Docker RMI与最近的dangling=true查询组合起来,我们可以删除所有未标记的图像:

docker映像-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]删除无用、已停止容器后面的映像。