In Docker, what's the difference between a container and an image?
Docker中的容器和图像有什么区别?在Docker入门教程中,这些术语都被使用,但是我不理解它们之间的区别。
有人能开灯吗?
图像是活动容器的固定快照。容器正在运行(或停止)某些映像的实例。
从名为"ubuntu"的基本图像开始。让我们在Ubuntu映像中交互运行bash并创建一个文件。我们将使用
1 2 3 4 5 6 | $ docker run -i -t ubuntu /bin/bash root@48cff2e9be75:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@48cff2e9be75:/# cat > foo This is a really important file!!!! root@48cff2e9be75:/# exit |
当您退出并重新启动图像时,不要期望该文件会一直存在。您重新启动时的定义状态与之前启动时完全相同,而不是停止时的状态。
1 2 3 4 | $ docker run -i -t ubuntu /bin/bash root@abf181be4379:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@abf181be4379:/# exit |
但是,现在不再运行的容器具有状态,可以保存(提交)到映像。
1 2 3 4 5 | $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abf181be4379 ubuntu:14.04 /bin/bash 17 seconds ago Exited (0) 12 seconds ago elegant_ardinghelli 48cff2e9be75 ubuntu:14.04 /bin/bash About a minute ago Exited (0) 50 seconds ago determined_pare ... |
让我们从创建文件的容器ID 48CFF2E9BE75创建一个图像:
1 2 | $ docker commit 48cff2e9be75 ubuntu-foo d0e4ae9a911d0243e95556e229c8e0873b623eeed4c7816268db090dfdd149c2 |
现在,我们有了一个非常重要的文件:
1 2 | $ docker run ubuntu-foo /bin/cat foo This is a really important file!!!! |
尝试命令
映像是根文件系统更改和相应执行参数的有序集合,用于容器运行时中。图像是只读的。
- https://docs.docker.com/glossary/?术语=图像
容器是映像的活动(如果退出,则为非活动)状态实例化。
- https://docs.docker.com/glossary/?术语=容器
使用面向对象的编程类比,Docker图像和Docker容器之间的区别与类和对象之间的区别相同。对象是类的运行时实例。类似地,容器是映像的运行时实例。
对象在实例化时只创建一次。类似地,容器可以运行或停止。容器是用图像创建的,尽管情况并非总是如此。以下示例创建Apache服务器映像,运行映像,列出映像,然后列出容器:
使用以下内容创建Dockerfile:
1 | FROM httpd:2.4 |
安装Apache服务器
1 | sudo docker build -t my-apache2 . |
运行图像
1 | sudo docker run -it --rm --name my-running-app my-apache2 |
列出Docker图像
1 | sudo docker images |
列出正在运行的Docker容器
1 | docker ps |
列出所有容器
1 | docker ps -a |
列出最新创建的容器
1 | docker ps -l |
用简单的话。
图像-
The file system and configuration(read-only) application which is used to
create containers. More detail.
集装箱-
These are running instances of Docker images. Containers run the actual
applications. A container includes an application and all of its
dependencies. It shares the kernel with other containers and runs as
an isolated process in user space on the host OS. More detail.
其他重要注意事项:
道克守护进程
The background service running on the host that manages the building,
running and distributing Docker containers.
码头客户
The command line tool that allows the user to interact with the Docker
daemon.
码头店
Store is, among other things, a registry of Docker images. You can
think of the registry as a directory of all available Docker images.
一幅画胜过千言万语。
(为了更深入的理解,请阅读此部分。)
总结:
- 从Docker Hub拉图像或从DockerFile构建=>提供Docker图像(不可编辑)。
- 运行映像(
docker run image_name:tag_name =>提供运行映像,即容器(可编辑)
图像基本上是用于创建容器的不可变模板。通过考虑将图像转化为容器会发生什么,更容易理解图像和容器之间的区别。
Docker引擎获取图像并在顶部添加一个读写文件系统,然后初始化各种设置。这些设置包括网络选项(IP、端口等)、名称、ID和任何资源限制(CPU、内存)。如果要求Docker引擎运行容器,它也会初始化其中的进程。容器可以停止并重新启动,在这种情况下,它将保留所有设置和文件系统更改(但会丢失内存中的任何内容,所有进程都将重新启动)。因此,停止或退出的容器与图像不同。
图像[像虚拟机]
- 用于创建容器的只读模板
- 由您或其他码头用户创建
- 存储在Docker Hub或本地注册表中
集装箱[像一台运转的机器]
- 独立应用平台
- 包含运行应用程序所需的所有内容
- 基于图像
dockerfile——(build)->dockerImage——(run)->dockerContainer
Dockerfile是您或开发人员编写代码来完成某项工作的工具(例如安装)
Docker图像是在构建Docker文件时得到的。
Docker容器是运行Docker图像时得到的
我们可以通过拉动从Docker Hub获取Docker图像,然后运行它来获取容器。
在Docker中,一切都是从一个图像开始的。映像是构成操作系统的每个文件,足以完成您需要执行的操作。传统上,您将安装一个完整的操作系统,其中包含您所做的每个应用程序的所有内容。有了Docker,你可以把它配对,这样你就有了一个小容器,里面有足够的操作系统来做你需要做的事情,而且你可以在电脑上高效地拥有很多这样的东西。
使用
docker run -ti
bash :
最后,图像有自己的ID集,容器有自己的ID集——它们不重叠。
容器基于图像。需要将图像传递给dockers run命令。
例子:
Basybox图像
http://i.stack.imgur.com/ek9dc.png
这里我们指定一个名为
注册表是Docker客户机可以与之通信并从中下载图像的Docker图像目录。一旦图像被拉出来,Docker就会启动一个容器并执行echo hello world命令。
映像:运行容器所需的文件系统和元数据。它们可以被认为是一种应用程序打包格式,包括运行应用程序的所有依赖项,以及执行该应用程序的默认设置。元数据包括要运行的命令、环境变量、标签和healthcheck命令的默认值。
容器:独立应用程序的实例。容器需要映像来定义其初始状态,并使用来自映像的只读文件系统以及特定于容器的读写文件系统。正在运行的容器是围绕正在运行的进程的包装器,它为文件系统、网络和PID等对象提供进程名称空间。
当执行
引用:对于Docker引擎,图像只是一个图像ID。这是一个唯一的不可变哈希。对图像的更改会导致创建新的图像ID。但是,可以有一个或多个指向图像ID的引用,这与符号链接不同。这些引用可以更新为指向新的映像ID。请注意,创建容器时,Docker将在创建容器时解析该引用,因此无法更新正在运行的容器的映像。相反,您可以创建一个新图像,并基于该新图像创建一个新容器。
层:再深入一点,就有了文件系统层。Docker使用分层文件系统组装图像。每个层都是对文件系统的一组只读更改,并且该层由一个唯一的哈希表示。使用这些只读层,多个图像可以扩展另一个图像,并且只需要通过网络存储或传输这些图像之间的差异。当Docker容器运行时,它会收到一个容器特有的读写文件系统层,并且所有的映像层都使用联合文件系统与之组装在一起。在找到文件、删除文件或在底层找不到文件之前,将对每个层进行读取。写操作执行从图像只读层到容器特定读写层的写时复制。删除记录为对容器特定读写层的更改。构建映像的一个常见步骤是在临时容器中基于以前的映像文件系统状态运行一个命令,并将生成的特定于容器的层保存为新映像中的一个层。
官方的区别是容器是最后一个可写的层,而下面的层只是可读的,它们属于您的图像。直观的区别是docker实例是由docker守护进程虚拟化的实例,运行映像时,它在内核的一个独立部分内运行(这个过程对您来说是隐藏的)。但是图像是静态的,它不运行,它只是一堆层(静态文件)。如果我们将这个范例与面向对象的编程联系起来,那么图像就是你的类定义,而你的Docker实例就是你的类生成的、驻留在内存中的对象。
我写了一个教程来加强你的码头知识直觉:
http://javagoglappspot.blogspot.com/2018/07/docker-basics.html
码头工人形象:它包含关于如何构建和运行容器的命令和指令列表。所以图像基本上包含了启动一个容器(也称为蓝图)所需要的所有数据和元数据,我们不能在没有指定图像的情况下午餐。
$docker images centos
列出所有可用的CentOS版本。
码头集装箱:容器是来自图像的午餐,因此我们可以说容器是图像的运行实例。容器是一个运行时构造,与构建时构造的图像不同。
图片是从你的手机上拍摄的照片。
容器是电话。