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

因此,最终我为我的PostgreSQL实例和我的web应用程序提供了一个图像,对这些图像的更改将持续保存。

什么是容器?


当前回答

我想用以下类比来说明:

+-----------------------------+-------+-----------+
|             Domain          | Meta  | Concrete  |
+-----------------------------+-------+-----------+
| Docker                      | Image | Container |
| Object oriented programming | Class | Object    |
+-----------------------------+-------+-----------+

其他回答

尽管阅读了这里所有的问题,我还是无法理解图像和图层的概念,然后最终偶然发现了Docker的这个优秀文档(废话!)

这里的例子是理解整个概念的关键。这是一篇很长的文章,所以我总结了需要真正抓住的要点,以使文章变得清晰。

镜像:Docker镜像由一系列只读层构建而成 层:每一层代表图像Dockerfile中的一条指令。

示例:下面的Dockerfile包含四个命令,每个命令创建一个层。

从ubuntu: 15.04 副本。/应用程序 运行make /app CMD python /app/app.py

重要的是,每一层都只是与前一层的一组差异。

容器。 当你创建一个新的容器时,你在底层的层上添加了一个新的可写层。这一层通常被称为“容器层”。对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都将写入这个薄的可写容器层。

因此,容器和映像之间的主要区别是 最上面的可写层。所有写入添加new或 修改现有数据都存储在这个可写层中。当 容器被删除,可写层也被删除。的 底层图像保持不变。

从磁盘大小的角度理解映像cnd容器

要查看正在运行的容器的大致大小,可以使用docker ps -s命令。你得到size和virtual size作为两个输出:

大小:用于每个容器的可写层的数据量(在磁盘上) 虚拟大小:容器使用的只读映像数据所使用的数据量。多个容器可以共享部分或全部只读映像数据。因此它们不是相加的。也就是说,你不能把所有的虚拟大小相加来计算镜像占用了多少磁盘空间

另一个重要的概念是写时复制策略

如果一个文件或目录存在于映像的较低层中,而另一层(包括可写层)需要对其进行读访问,则它只使用现有文件。当另一层第一次需要修改该文件时(当构建映像或运行容器时),该文件被复制到该层并进行修改。

我希望这能帮助到像我一样的人。

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

Docker Images vs. Containers

在Dockerland,有图像,也有容器。这两者密切相关,但又截然不同。对我来说,把握这种二分法极大地澄清了Docker。

什么是图像?

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

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

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

需要注意的一些事情:

IMAGE ID is the first 12 characters of the true identifier for an image. You can create many tags of a given image, but their IDs will all be the same (as above). VIRTUAL SIZE is virtual because it's adding up the sizes of all the distinct underlying layers. This means that the sum of all the values in that column is probably much larger than the disk space used by all of those images. The value in the REPOSITORY column comes from the -t flag of the docker build command, or from docker tag-ing an existing image. You're free to tag images using a nomenclature that makes sense to you, but know that docker will use the tag as the registry location in a docker push or docker pull. The full form of a tag is [REGISTRYHOST/][USERNAME/]NAME[:TAG]. For ubuntu above, REGISTRYHOST is inferred to be registry.hub.docker.com. So if you plan on storing your image called my-application in a registry at docker.example.com, you should tag that image docker.example.com/my-application. The TAG column is just the [:TAG] part of the full tag. This is unfortunate terminology. The latest tag is not magical, it's simply the default tag when you don't specify a tag. You can have untagged images only identifiable by their IMAGE IDs. These will get the <none> TAG and REPOSITORY. It's easy to forget about them.

更多关于图像的信息可以从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

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

和IMAGE ID一样,CONTAINER ID是容器的真实标识符。它有相同的形式,但它识别了不同种类的物体。 Docker ps只输出正在运行的容器。你可以使用docker ps -a查看所有的容器(正在运行或已停止)。 NAMES可以通过——name标志来标识一个启动的容器。

如何避免图像和容器堆积

我早期使用Docker时遇到的一个挫折是,未标记的图像和停止的容器似乎不断堆积。在少数情况下,这种堆积导致硬盘驱动器过载,使我的笔记本电脑变慢或停止自动构建管道。谈论“无处不在的容器”!

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

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

Docker将不能删除现有容器后面的图像,所以你可能必须先用Docker rm删除停止的容器:

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

这些都是Docker的已知痛点,可能会在未来的版本中得到解决。然而,通过对映像和容器的清晰理解,可以通过以下几个实践来避免这些情况:

总是使用docker rm [CONTAINER_ID]删除无用的、停止的容器。 总是使用docker rmi [IMAGE_ID]删除无用的、停止的容器后面的映像。

Dockerfile→(Build)→Image→(Run)→Container。

Dockerfile:包含一组Docker指令,以您喜欢的方式配置您的操作系统,并安装/配置所有软件。 图片:编译好的Dockerfile。节省了每次需要运行容器时重新构建Dockerfile的时间。这是一种隐藏供应代码的方法。 容器:虚拟操作系统本身。您可以ssh进入其中并运行任何命令,就像它是一个真实的环境一样。您可以从同一个映像运行1000多个容器。

正如许多回答指出的那样:你构建Dockerfile来获取一个图像,然后运行image来获取一个容器。

但是,下面的步骤帮助我更好地了解Docker映像和容器是什么:

1)构建Dockerfile:

Docker build -t my_image dir_with_dockerfile

2)保存镜像到.tar文件

-o my_file.tar my_image_id

My_file.tar将存储映像。使用tar -xvf my_file.tar打开它,您将看到所有的层。如果你深入每一层,你可以看到每一层添加了什么变化。(它们应该非常接近Dockerfile中的命令)。

3)要查看容器内部,您可以:

Sudo docker运行- my_image bash

你可以看到它很像一个操作系统。

Dockerfile类似于生成tarball (Docker映像)的Bash脚本。

Docker容器就像tarball的提取版本。您可以在不同的文件夹(容器)中拥有尽可能多的副本。