Answers:
图像的实例称为容器。您有一张图像,该图像是您描述的一组图层。如果启动此映像,则该映像具有正在运行的容器。您可以有多个运行相同图像的容器。
您可以使用来查看所有图像,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
注意事项:
-t
标志docker build
,或来自docker tag
-ing现有图像。您可以使用对您有意义的命名法来随意标记图像,但是您知道Docker将在服务器中使用标记作为注册表位置。docker push
或中docker pull
。[REGISTRYHOST/][USERNAME/]NAME[:TAG]
。对于ubuntu
上述情况,REGISTRYHOST推断为registry.hub.docker.com
。因此,如果您打算将映像存储my-application
在注册表中docker.example.com
,则应标记该映像docker.example.com/my-application
。latest
标签不是神奇的,它只是未指定标签时的默认标签。<none>
标签和存储区。忘记它们很容易。要使用编程隐喻,如果图像是类,则容器是类的实例-运行时对象。容器是希望您使用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版本,以便我有一个私人位置来存储我的图像。同样,需要注意一些事项:
docker ps
仅输出运行中的容器。您可以使用来查看所有容器(正在运行或已停止)docker ps -a
。--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的已知痛点,可能会在将来的版本中解决。但是,只要对图像和容器有清楚的了解,可以通过以下两种方法避免这些情况:
docker rm [CONTAINER_ID]
。docker rmi [IMAGE_ID]
。docker image prune
用来清理悬空的图像。修剪未使用的Docker对象
docker system prune
用来清洁一切
简单来说。
图片 -
用于创建容器的文件系统和配置(只读)应用程序。更多细节。
容器 -
这些正在运行的Docker映像实例。容器运行实际的应用程序。容器包含一个应用程序及其所有依赖项。它与其他容器共享内核,并在主机OS上的用户空间中作为隔离进程运行。更多细节。
其他重要注意事项:
Docker守护程序 -
在管理构建,运行和分发Docker容器的主机上运行的后台服务。
Docker客户端 -
允许用户与Docker守护程序进行交互的命令行工具。
Docker商店 -
除其他事项外,Store是Docker映像的注册表。您可以将注册表视为所有可用Docker映像的目录。
这篇博客文章的图片值得一千个字。
(如需进一步了解,请阅读此内容。)
摘要:
docker run image_name:tag_name
)=>给出运行的图像,即容器(可编辑)虽然将容器视为运行中的映像是最简单的,但这并不完全准确。
图像实际上是可以转换为容器的模板。为了将映像转换为容器,Docker引擎会获取映像,在顶部添加一个读写文件系统,并初始化各种设置,包括网络端口,容器名称,ID和资源限制。正在运行的容器具有当前正在执行的进程,但是也可以停止容器(或在Docker的术语中退出容器)。一个退出容器是不一样的图像,因为它可以重新启动,将保留其设置和文件系统的任何变化。
docker create
。
这是显示各种命令及其相关输入和输出的端到端工作流程。那应该阐明图像和容器之间的关系。
+------------+ docker build +--------------+ docker run -dt +-----------+ docker exec -it +------+
| Dockerfile | --------------> | Image | ---------------> | Container | -----------------> | Bash |
+------------+ +--------------+ +-----------+ +------+
^
| docker pull
|
+--------------+
| Registry |
+--------------+
要列出您可以运行的图像,请执行:
docker image ls
要列出容器,您可以在以下位置执行命令:
docker ps
尽管阅读了这里的所有问题,但我还是无法理解图像和图层的概念,然后最终偶然发现了Docker的出色文档(documentation!)。
这个例子确实是理解整个概念的关键。这是一篇冗长的文章,所以我在总结一些要清楚地理解的关键点。
图像:Docker图像由一系列只读层构建而成
层:每层代表映像的Dockerfile中的一条指令。
Example
:下面的Dockerfile包含四个命令,每个命令创建一个图层。
来自ubuntu:15.04
复制。/ app
运行make / app
CMD python /app/app.py
重要的是,每一层只是与它之前的一层的一组差异。
因此,容器和图像之间的主要区别是可写顶层。在容器中添加新数据或修改现有数据的所有写操作都存储在此可写层中。删除容器后,可写层也会被删除。基础图像保持不变。
从磁盘大小的角度了解映像cnd容器
要查看正在运行的容器的大致大小,可以使用以下docker ps -s
命令。您将获得size
和virtual size
作为两个输出:
大小:用于每个容器的可写层的数据量(磁盘上)
虚拟大小:用于容器使用的只读图像数据的数据量。多个容器可以共享部分或全部只读图像数据。因此,这些不是累加的。也就是说,您无法添加所有虚拟大小来计算映像使用了多少磁盘空间
另一个重要概念是写时复制策略
如果文件或目录位于映像的较低层中,而另一层(包括可写层)需要对其进行读取访问,则它仅使用现有文件。另一层第一次需要修改文件时(在构建映像或运行容器时),将文件复制到该层并进行修改。
希望对我这样的人有帮助。
Dockerfile →(构建)→ 图像 →(运行)→ 容器。
Dockerfile:包含一组Docker指令,它们以您喜欢的方式配置您的操作系统,并安装/配置所有软件。
图片:已编译的Dockerfile。每次需要运行容器时,都可以节省重建Dockerfile的时间。这是一种隐藏您的供应代码的方法。
容器:虚拟操作系统本身。您可以将其放入ssh并运行所需的任何命令,就好像它是一个真实的环境一样。您可以从同一映像运行1000多个容器。
容器只是可执行的二进制文件,将由主机OS在一组限制下运行,这些限制是使用应用程序(例如Docker)预先设置的,该应用程序知道如何告诉OS应用哪些限制。
典型的限制是与进程隔离有关,与安全有关(例如使用SELinux保护)和与系统资源有关(内存,磁盘,CPU和网络)。
直到最近,只有基于Unix的系统中的内核才支持在严格限制下运行可执行文件的功能。这就是为什么当今大多数容器讨论都涉及Linux或其他Unix发行版的原因。
Docker是知道如何告诉OS(主要是Linux)如何在其下运行可执行文件的限制的那些应用程序之一。可执行文件包含在Docker映像中,它只是一个tarfile。该可执行文件通常是Linux发行版(Ubuntu,CentOS,Debian等)的精简版,已预先配置为在其中运行一个或多个应用程序。
尽管大多数人使用Linux基础作为可执行文件,但只要主机OS可以运行它,它就可以是任何其他二进制应用程序(请参阅使用草稿创建简单的基础映像)。Docker映像中的二进制文件是操作系统还是简单的应用程序,对于OS主机而言,它只是另一个进程,其中包含的进程由预设的OS边界决定。
诸如Docker之类的其他应用程序可以告诉主机OS在其运行时将哪些边界应用于该进程,包括LXC,libvirt和systemd。Docker曾经使用这些应用程序与Linux OS进行间接交互,但是现在Docker使用自己的名为“ libcontainer ” 的库直接与Linux交互。
因此,容器只是在受限模式下运行的进程,类似于chroot过去所做的事情。
IMO,使Docker与任何其他容器技术区分开来的是它的存储库(Docker Hub)及其管理工具,这使使用容器变得非常容易。
请参阅Docker(软件)。
许多答案指出了这一点:您构建 Dockerfile来获取映像,然后运行 image来获取容器。
但是,以下步骤有助于我更好地了解什么是Docker映像和容器:
1)构建Dockerfile:
docker build -t my_image dir_with_dockerfile
2)将图像保存到.tar
文件
docker save -o my_file.tar my_image_id
my_file.tar
将存储图像。使用打开它tar -xvf my_file.tar
,您将看到所有图层。如果您更深入地研究每一层,则可以看到在每一层中添加了哪些更改。(它们应该非常接近Dockerfile中的命令)。
3)要查看容器内部,您可以执行以下操作:
sudo docker run -it my_image bash
您会发现它非常像一个操作系统。
图像等效于OOP中的类定义,并且图层是该类的不同方法和属性。
容器是图像的实际实例,就像对象是实例的实例还是类的实例一样。
我认为最好在开始时进行解释。
假设您运行命令docker run hello-world
。怎么了?
它调用Docker CLI,后者负责接收Docker命令并转换为调用Docker服务器命令。Docker服务器一旦获得运行映像的命令,就会检查映像缓存中是否包含具有该名称的映像。
假设hello-world不存在。Docker服务器转到Docker Hub(Docker Hub只是一个免费的映像存储库),问,嘿,Hub,您是否有一个名为的映像hello-world
?集线器响应-是的,我愿意。然后把它给我。然后下载过程开始。一旦泊坞窗图像被下载,在泊坞服务器把它的图像缓存。
因此,在解释什么是Docker映像和Docker容器之前,我们先介绍一下计算机上的操作系统及其运行软件的方式。
例如,当您在计算机上运行Chrome时,它会调用操作系统,操作系统本身会调用内核并询问,嘿,我想运行此程序。内核设法从硬盘上运行文件。
现在,假设您有两个程序,Chrome和Node.js。Chrome需要运行Python 2版本,而Node.js需要运行Python 3版本。如果您仅在计算机上安装了Python v2,则将仅运行Chrome。
为了使两种情况都起作用,您需要以某种方式使用称为命名空间的操作系统功能。命名空间是一项功能,使您有机会隔离进程,硬盘驱动器,网络,用户,主机名等。
因此,当我们谈论映像时,实际上是在谈论文件系统快照。的图像是包含方向和元数据,以建立一个特定的物理文件容器。的容器本身是一个实例图像 ; 它使用命名空间隔离硬盘驱动器,该命名空间仅可用于此容器。因此,容器是对分配给它的不同资源进行分组的一个或一组过程。
与编程方面一样,
图像是源代码。
当源代码被编译和构建,它被称为一个应用程序。
类似于“为图像创建实例时”,它称为“ 容器 ”。
一个图像是一个的“快照” 容器。您可以从容器制作图像(新的“快照”),也可以从图像启动新容器(实例化“快照”)。
例如,您可以从基础映像实例化一个新容器,在容器中运行一些命令,然后将其快照为新映像。然后,您可以从该新映像运行100个容器。
要考虑的其他事项:
docker images
。对于虚拟编程类比,您可以想到Docker有一个抽象的ImageFactory,其中包含来自商店的 ImageFactory 。
然后,一旦您要使用该ImageFactory创建应用程序,您将拥有一个新容器,您可以根据需要对其进行修改。DotNetImageFactory将是不可变的,因为它充当抽象工厂类,仅在其中提供您所需的实例。
IContainer newDotNetApp = ImageFactory.DotNetImageFactory.CreateNew(appOptions);
newDotNetApp.ChangeDescription("I am making changes on this instance");
newDotNetApp.Run();
简而言之:
容器是内核中的一个分区(虚拟),共享一个共同的操作系统并运行一个映像(Docker映像)。
容器是一个可自我维持的应用程序,它将具有程序包和所有必要的依赖项一起运行代码。
Docker容器正在运行映像的实例。您可以将图像与程序相关联,将容器与进程相关联:)