What is the difference between a Docker image and a container?
使用Docker时,我们从基本图像开始。我们启动它,创建更改,这些更改保存在形成另一个图像的层中。
因此,最终我有了一个PostgreSQL实例的映像和一个Web应用程序的映像,这些更改将继续保留。
所以问题是:什么是容器?
图像的实例称为容器。您有一个图像,它是您描述的一组层。如果启动此映像,则会有此映像的运行容器。可以有多个运行中的同一图像的容器。
使用
所以图像的运行实例是一个容器。
在我关于自动化Docker部署的文章中:
Docker图像与容器在Dockerland,有图像和容器。两者关系密切,但截然不同。对我来说,掌握这种二分法极大地澄清了码头工人。
什么是图像?图像是一个惰性的、不可变的文件,本质上是容器的快照。图像是用build命令创建的,当开始运行时,它们将生成一个容器。图像存储在docker注册表中,如registry.hub.docker.com。因为它们可以变得相当大,图像被设计成由其他图像的层组成,允许在通过网络传输图像时发送最小数量的数据。
运行
1 2 3 4 5 6 | 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 |
需要注意的一些事项:
更多关于图像的信息可以从Docker文档和术语表中获得。
什么是容器?要使用编程隐喻,如果图像是一个类,那么容器就是一个类的实例——一个运行时对象。希望容器是您使用Docker的原因;它们是运行应用程序的环境的轻量级和可移植的封装。
使用
1 2 | 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的不满之一是,它似乎总是不断地累积未加标签的图像和停止的容器。在少数情况下,这种累积会导致硬盘耗尽,减慢我的笔记本电脑速度,或停止我的自动生成管道。谈论"容器无处不在"!
我们可以将
Docker将无法删除现有容器后面的图像,因此您可能必须先使用
1 | docker rm `docker ps --no-trunc -aq` |
这些是Docker已知的症结所在,可以在将来的版本中解决。但是,如果对图像和容器有一个清晰的了解,可以通过以下几个实践来避免这些情况:
虽然将容器看作一个运行中的图像是最简单的,但这并不十分准确。
图像实际上是一个可以转换为容器的模板。要将图像转换为容器,Docker引擎会获取图像,在顶部添加一个读写文件系统,并初始化各种设置,包括网络端口、容器名称、ID和资源限制。一个正在运行的容器有一个当前正在执行的进程,但是容器也可以被停止(或者在Docker的术语中退出)。退出的容器与映像不同,因为它可以重新启动,并将保留其设置和任何文件系统更改。
用简单的话。
图像-
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 =>提供运行映像,即容器(可编辑)
也许解释整个工作流程会有所帮助。
一切都从Dockerfile开始。dockerfile是图像的源代码。
创建dockerfile后,您将构建它以创建容器的图像。图像只是"源代码"的"编译版本",即Dockerfile。
一旦拥有了容器的映像,就应该使用注册表重新分配它。注册表就像一个Git存储库——您可以推拉图像。
接下来,可以使用图像运行容器。正在运行的容器在许多方面与虚拟机非常相似(但没有虚拟机监控程序)。
这篇文章解释了关于Docker容器的许多基本内容(它是关于Docker和Puppet的,但是有许多概念可以在任何上下文中使用)。
工作流程
这里是显示各种命令及其相关输入和输出的端到端工作流。这应该可以澄清图像和容器之间的关系。
1 2 3 4 5 6 7 8 9 | +------------+ docker build +--------------+ docker run -dt +-----------+ docker exec -it +------+ | Dockerfile | --------------> | Image | ---------------> | Container | -----------------> | Bash | +------------+ +--------------+ +-----------+ +------+ ^ | docker pull | +--------------+ | Registry | +--------------+ |
要列出可以运行的图像,请执行:
1 | docker image ls |
要列出可以对其执行命令的容器,请执行以下操作:
1 | docker ps |
我无法理解图像和层的概念,尽管我阅读了这里的所有问题,然后最终偶然发现了Docker(duh!).
这个例子确实是理解整个概念的关键。这是一篇冗长的文章,所以我总结了需要真正把握的要点,以获得清晰。
图片:Docker图片是由一系列只读层构成的。
层:每个层表示图像Dockerfile中的一条指令。
FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py
重要的是,每个层与之前的层只是一组差异。
- 容器。创建新容器时,将在基础层的顶部添加新的可写层。这一层通常被称为"容器层"。对正在运行的容器所做的所有更改(如写入新文件、修改现有文件和删除文件)都将写入此可写容器薄层。
Hence, the major difference between a container and an image is
the top writable layer. All writes to the container that add new or
modify existing data are stored in this writable layer. When the
container is deleted, the writable layer is also deleted. The
underlying image remains unchanged.
从磁盘大小的角度理解图像CND容器
要查看正在运行的容器的大致大小,可以使用
大小:用于每个容器的可写层的数据量(在磁盘上)
虚拟大小:用于容器使用的只读图像数据的数据量。多个容器可以共享部分或全部只读图像数据。因此,这些不是添加剂。也就是说,不能添加所有虚拟大小来计算映像在磁盘上使用的大小
另一个重要的概念是copy-on-write策略
如果一个文件或目录存在于图像的较低层中,而另一层(包括可写层)需要对其进行读访问,则它只使用现有文件。第一次其他层需要修改文件时(在构建图像或运行容器时),文件将被复制到该层并进行修改。
我希望这能帮助像我这样的人。
dockerfile>(build)>image>(run)>container。
dockerfile:包含一组docker指令,可以按照您喜欢的方式设置操作系统,并安装/配置所有软件。
图片:编译的dockerfile。每次需要运行容器时,都可以节省重新构建dockerfile的时间。这是一种隐藏供应代码的方法。
容器:虚拟操作系统本身,您可以通过ssh访问它,并运行任何您想要的命令,就好像它是一个真实的环境一样。您可以从同一个图像运行1000多个容器。
简单地说,如果一个图像是一个类,那么容器就是一个类的实例就是一个运行时对象。
容器只是一个可执行的二进制文件,由主机操作系统在一组预先设置的限制下运行,这些限制使用一个知道如何告诉操作系统要应用哪些限制的应用程序(例如Docker)。
典型的限制包括进程隔离相关、安全相关(如使用SELinux保护)和系统资源相关(内存、磁盘、CPU、网络)。
直到最近,在基于Unix的系统中,只有内核支持在严格限制下运行可执行文件的能力。这就是今天大多数容器讨论主要涉及Linux或其他Unix发行版的原因。
Docker是那些知道如何告诉操作系统(主要是Linux)在什么限制下运行可执行文件的应用程序之一。可执行文件包含在Docker映像中,它只是一个tarfile。该可执行文件通常是Linux发行版(Ubuntu、CentOS、Debian等)的精简版,预配置为在其中运行一个或多个应用程序。
尽管大多数人使用Linux库作为可执行文件,但只要主机操作系统能够运行它,它就可以是任何其他二进制应用程序。(请参见使用草稿创建简单的基础图像)。无论docker映像中的二进制文件是操作系统还是简单的应用程序,对于操作系统主机来说,它只是另一个进程,由预设操作系统边界控制的包含进程。
其他应用程序,如Docker,可以告诉主机操作系统在进程运行时应用于进程的边界包括lxc、libvirt和systemd。Docker曾经使用这些应用程序间接地与Linux操作系统交互,但现在Docker使用自己的库"libcontainer"直接与Linux交互。
所以容器只是在受限模式下运行的进程,类似于chroot以前所做的。
在我看来,Docker与其他任何集装箱技术不同之处在于它的仓库(Docker Hub)及其管理工具,这使得与集装箱的工作非常容易。
见https://en.m.wikipedia.org/wiki/docker_u(linux_container_engine)
Docker的核心概念是使创建"机器"变得容易,在这种情况下,可以将其视为容器。容器有助于重用,允许您轻松创建和放置容器。
图像描述了容器在每个时间点的状态。所以基本的工作流程是:
正如许多答案指出的那样:构建dockerfile以获取图像,运行image以获取容器。
但是,以下步骤帮助我更好地了解Docker图像和容器是什么:
1)构建dockerfile:
2)将图像保存到
3)要查看容器内部,可以执行以下操作:
你可以看到这非常像一个操作系统。
图像在OOP中等价于类定义,层是该类的不同方法和属性。
容器是图像的实际实例化,就像对象是类的实例化或实例一样。
在编程方面,
图像是源代码。
当编译和生成源代码时,它被称为应用程序。
与"为映像创建实例时"类似,它被称为"容器"
Docker映像打包应用程序运行所需的应用程序和环境,容器是映像的运行实例。
图像是Docker的打包部分,类似于"源代码"或"程序"。容器是Docker的执行部分,类似于"过程"。
在这个问题中,只提到"程序"部分,这就是图像。Docker的"运行"部分是容器。当运行容器并进行更改时,就好像进程在自己的源代码中进行了更改并将其保存为新图像一样。
简而言之:
容器是内核中的一个划分(虚拟),它共享一个公共操作系统并运行一个映像(docker映像)。
容器是一个自我可持续的应用程序,它将包含运行代码所需的包和所有必要的依赖项。
Docker容器正在运行映像的实例。您可以将图像与程序关联,将容器与进程关联:)
图像将作为对象的容器传递给类。
容器是图像的实例,因为对象是类的实例。
图像–它是容器的构建块。它实际上是虚拟的一种快照,但更轻。
容器-它是一种虚拟化操作系统的方法,以便应用程序及其相关依赖项可以在资源隔离的进程中执行。
当我们使用docker时,我们现在得到一个基础图像。然后我们引导它,进行相关的更改,并将这些更改保存在形成另一个图像的层中。容器基本上是图像的一个实例。这意味着正在运行的映像是一个容器。如果一个人启动了一个图像,他实际上正在运行一个容器。一个人可能在同一个映像的同一时间有多个正在运行的容器。
可以使用以下代码查看所有图像:
码头工人图像
可通过以下方式查看正在运行的容器:
码头工人
如果要查看所有容器,无论是否正在运行:
码头工人PS-A
对于一个虚拟的编程类比,您可以想到Docker有一个抽象的ImageFactory,它保存了来自商店的ImageFactory。
然后,一旦您想从ImageFactory中创建一个应用程序,您将拥有一个新的容器,并且您可以根据需要修改它。DotNetImageFactory将是不可变的,因为它充当抽象工厂类,只提供您想要的实例。
1 2 3 | IContainer newDotNetApp = ImageFactory.DotNetImageFactory.CreateNew(appOptions); newDotNetApp.ChangeDescription("I am making changes on this instance"); newDotNetApp.Run(); |
dockerfile就像你的bash脚本,可以生成tarball(docker image)。
Docker容器就像提取出来的tarball。您可以在不同的文件夹(容器)中拥有任意多个副本。