首页 文章

Docker镜像和容器之间有什么区别?

提问于
浏览
568

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

所以最终我有一个我的PostgreSQL实例的图像和我的Web应用程序的图像,继续保持持续的更改 .

所以问题是:什么是容器?

20 回答

  • 2

    简单地说,如果一个图像是一个类,那么一个容器是一个类的实例就是一个运行时对象 .

  • 3

    图像的实例称为容器 . 你有一个图像,这是你描述的一组图层 . 如果您启动此图像,则您拥有此图像的运行容器 . 您可以拥有许多相同图像的运行容器 .

    您可以使用 docker images 查看所有图像,而您可以使用 docker ps 查看正在运行的容器(并且您可以使用 docker ps -a 查看所有容器) .

    因此,图像的运行实例是容器 .

  • 785

    对于虚拟编程类比,您可以认为Docker有一个抽象的ImageFactory,它包含来自store的ImageFactories .

    然后,一旦您想要从该ImageFactory创建一个应用程序,您将拥有一个新容器,您可以根据需要进行修改 . DotNetImageFactory将是不可变的,因为它充当抽象工厂类,它只提供您想要的实例 .

    IContainer newDotNetApp = ImageFactory.DotNetImageFactory.CreateNew(appOptions);
    newDotNetApp.ChangeDescription("I am making changes on this instance");
    newDotNetApp.Run();
    
  • 17

    简而言之:

    容器是内核中的一个分区(虚拟),它共享一个公共操作系统并运行一个映像(Docker映像) .

    容器是一个自我可持续的应用程序,它将包和所有必需的依赖项一起运行代码 .

  • 74

    Dockerfile >(Build)> Image >(运行)> Container .

    • Dockerfile :包含一组docker指令,以您喜欢的方式配置您的操作系统,并安装/配置您的所有软件 .

    • Image :已编译的Dockerfile . 每次需要运行容器时,可以节省重建Dockerfile的时间 . 这是一种隐藏供应代码的方法 .

    • Container :虚拟操作系统本身,你可以ssh到它并运行你想要的任何命令,就好像它是一个真实的环境 . 您可以从同一个Image运行1000个容器 .

  • 1

    用简单的话说 .

    Images -

    用于创建容器的文件系统和配置(只读)应用程序 . 更多详情 .

    Containers -

    这些是Docker镜像的运行实例 . 容器运行实际的应用程序 . 容器包括应用程序及其所有依赖项 . 它与其他容器共享内核,并在主机操作系统的用户空间中作为独立进程运行 . 更多详情 .


    Other important terms to notice:


    Docker daemon -

    在管理构建,运行和分发Docker容器的主机上运行的后台服务 .

    Docker client -

    命令行工具,允许用户与Docker守护程序进行交互 .

    Docker Store -

    Store是Docker镜像的注册表 . 您可以将注册表视为所有可用Docker镜像的目录 .

    一张图片胜过千言万语 .

    (有关更深入的理解,请阅读this . )

    摘要:

    • 从Docker hub拉取 image 或从Dockerfile构建=>提供Docker镜像(不可编辑) .

    • 运行图像( docker run image_name:tag_name )=>提供正在运行的图像即容器(可编辑)

  • 66

    Image 等同于OOP中的类定义,层是该类的不同方法和属性 .

    Container 是图像的实际实例化,就像对象是实例化或类的实例一样 .

  • 32

    Dockerfile就像你的bash脚本一样产生tarball(Docker镜像) .

    Docker容器就像tarball的提取版本 . 您可以在不同的文件夹(容器)中拥有任意数量的副本

  • 29

    Docker容器正在运行映像的实例 . 您可以将图像与程序和带有进程的容器相关联:)

  • 8

    容器只是一个可执行的二进制文件,它将由主机OS在一组限制下运行,这些限制是使用知道如何告诉OS应用哪些限制的应用程序(例如,docker)预设的 .

    典型的限制是与进程隔离相关,与安全相关(如使用SELinux保护)和与系统资源相关(内存,磁盘,CPU,网络) .

    直到最近,只有基于Unix的系统中的内核才支持在严格限制下运行可执行文件的能力 . 这就是今天大多数容器谈话主要涉及Linux或其他Unix发行版的原因 .

    Docker是那些知道如何告诉操作系统(主要是Linux)运行可执行文件的限制的应用程序之一 . 可执行文件包含在Docker镜像中,它只是一个tarfile . 该可执行文件通常是预先配置为在其中运行一个或多个应用程序的Linux发行版(Ubuntu,centos,Debian等)的精简版本 .

    虽然大多数人使用Linux基础作为可执行文件,但只要主机操作系统可以运行它,它就可以是任何其他二进制应用程序 . (见creating a simple base image using scratch) . 无论Docker镜像中的二进制文件是操作系统还是仅仅是应用程序,对于OS主机而言,它只是另一个进程,由预设的操作系统边界控制的包含进程 .

    其他应用程序(如Docker)可以告诉主机操作系统在运行过程中应用于哪个边界包括LXC,_ libvirtsystemd . Docker曾经使用这些应用程序间接与Linux操作系统交互,但现在Docker使用自己的名为“libcontainer”的库直接与Linux交互 . 因此容器只是在受限模式下运行的进程,类似于chroot以前的工作 .

    IMO将Docker与其他任何容器技术区别开来的是它的存储库(Docker Hub)及其管理工具,这使得使用容器非常容易 .

    https://en.m.wikipedia.org/wiki/Docker_(Linux_container_engine)

  • 1

    Docker镜像打包应用程序运行所需的应用程序和环境,容器是图像的运行实例 .

    图像是docker的包装部分,类似于“源代码”或“程序” . 容器是docker的执行部分,类似于“进程” .

    在这个问题中,只有“程序”部分被引用,那就是图像 . docker的“运行”部分是容器 . 当一个容器运行并进行更改时,就好像该进程对其自己的源代码进行了更改并将其另存为新映像 .

  • 1

    图像是作为对象的容器的类 .

    容器是图像的实例,因为对象是类的实例 .

  • 0

    工作流程

    以下是端到端工作流程,显示各种命令及其相关的输入和输出 . 这应该澄清图像和容器之间的关系 .

    +------------+  docker build   +--------------+  docker run -dt   +-----------+  docker exec -it   +------+
    | Dockerfile | --------------> |    Image     | --------------->  | Container | -----------------> | Bash |
    +------------+                 +--------------+                   +-----------+                    +------+
                                     ^
                                     | docker pull
                                     |
                                   +--------------+
                                   |   Registry   |
                                   +--------------+
    

    要列出您可以运行的图像,请执行:

    docker image ls
    

    要列出容器,您可以在以下位置执行命令:

    docker ps
    
  • 451

    docker的核心概念是使创建“机器”变得容易,在这种情况下可以将其视为容器 . 容器有助于重用,允许您轻松创建和删除容器 .

    图像描绘了每个时间点的容器状态 . 所以基本的工作流程是:

    • 创建一个图像

    • 启动一个容器

    • 对容器进行更改

    • 将容器保存为图像

  • 0

    正如许多答案所指出的那样:你 build Dockerfile 获得 image 而你 run image 获得 container .

    但是,以下步骤帮助我更好地了解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

    你可以看到它非常像操作系统 .

  • 93

    在编程方面,

    Image 是源代码 .

    source code 被编译和构建时,它被称为应用程序 .

    Simillar到"when instance is created for the image",它被称为“ Container

  • 11

    从我在Automating Docker Deployments上的文章:

    Docker镜像与容器

    在Dockerland,有 images ,有 containers . 这两者密切相关,但截然不同 . 对我来说,掌握这种二分法已经极大地澄清了Docker .

    什么是图像?

    图像是一个惰性的,不可变的文件,它本质上是容器的快照 . 使用build命令创建图像,并在使用run启动时生成容器 . 图像存储在Docker注册表中,例如registry.hub.docker.com . 因为它们可能变得非常大,所以图像被设计成由其他图像层组成,允许在通过网络传输图像时发送大量数据 .

    可以通过运行 docker images 列出本 Map 像:

    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
    

    Some things to note:

    • IMAGE ID是图像的真实标识符的前12个字符 . 您可以创建给定图像的许多标记,但它们的ID都是相同的(如上所述) .

    • VIRTUAL SIZE是虚拟的,因为它会增加所有不同底层的大小 . 这意味着该列中所有值的总和可能远大于所有这些图像使用的磁盘空间 .

    • REPOSITORY列中的值来自 docker build 命令的 -t 标志,或者来自现有图像的 docker tag . 您可以使用对您有意义的命名法来标记图像,但是知道docker会将标记用作 docker pushdocker pull 中的注册表位置 .

    • 标签的完整形式是 [REGISTRYHOST/][USERNAME/]NAME[:TAG] . 对于上面的 ubuntu ,REGISTRYHOST被推断为 registry.hub.docker.com . 因此,如果您计划在 docker.example.com 的注册表中存储名为 my-application 的图像,则应标记该图像 docker.example.com/my-application .

    • TAG栏是只是完整标签的[:TAG]部分 . 这是一个不幸的术语 .

    • latest 标签并不神奇,'s simply the default tag when you don' t指定标签 .

    • 您可以使用仅可通过其图像ID识别的未标记图像 . 这些将获得 <none> TAG和REPOSITORY . 很容易忘记它们 .

    有关图像的更多信息,请参见Docker docsglossary .

    什么是容器?

    要使用编程隐喻,如果图像是类,则容器是类的实例 - 运行时对象 . 容器有望成为你使用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版本,因此我有一个私有的地方来存储我的图像 . 同样,有些事情需要注意:

    • 与IMAGE ID类似,CONTAINER ID是容器的真实标识符 . 它具有相同的形式,但它标识了不同类型的对象 .

    • docker ps 仅输出正在运行的容器 . 您可以使用 docker ps -a 查看所有容器(正在运行或已停止) .

    • NAMES可用于通过 --name 标志识别已启动的容器 .

    如何避免图像和容器堆积?

    我对Docker的早期挫折之一是 seemingly constant buildup of untagged images and stopped containers . 在少数几个场景中,这种累积导致硬盘驱动器的速度变慢,从而减慢了我的笔记本电脑或停止了自动构建管道 . 说说"containers everywhere"!

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

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

    Docker将无法删除现有容器后面的图像,因此您可能必须首先使用 docker rm 删除已停止的容器:

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

    这些是与Docker的known pain points,可能会在将来的版本中解决 . 但是,通过对图像和容器的清晰理解,可以通过以下几种方法避免这些情况:

    • 始终使用 docker rm [CONTAINER_ID] 删除无用的已停止容器 .

    • 始终使用 docker rmi [IMAGE_ID] 删除无用的已停止容器后面的图像 .

  • 11

    也许解释整个工作流程可以帮助 .

    一切都始于 Dockerfile . Dockerfile是Image的源代码 .

    创建Dockerfile后,构建它以创建容器的 image . 图像只是"source code"的"compiled version",它是Dockerfile .

    获得容器的图像后,应使用 registry 重新分发它 . 注册表就像一个git存储库 - 你可以推送和拉取图像 .

    接下来,您可以使用该图像运行 containers . 在许多方面,正在运行的容器与虚拟机非常相似(但没有hypervisor) .

    This post解释了很多关于docker容器的基本知识(它讨论的是Docker和Puppet,但是有很多概念可以在任何上下文中使用)

  • 3

    虽然它相当准确 .

    图像实际上是可以转换为容器的模板 . 要将图像转换为容器,Docker引擎会获取图像,在顶部添加读写文件系统并初始化各种设置,包括网络端口,容器名称,ID和资源限制 . 正在运行的容器具有当前正在执行的进程,但也可以停止容器(或以Docker的术语退出) . 退出的容器与图像不同,因为它可以重新启动并保留其设置和任何文件系统更改 .

  • 0

    尽管我在这里阅读了所有的问题,然后最终偶然发现了这个问题,我无法理解图像和图层的概念(呃!) .

    这个例子确实是理解整个概念的关键 . 这是一个冗长的帖子,所以我总结了需要真正掌握以获得清晰度的关键点 .

    • Image :Docker镜像是从一系列 read-only 层构建的

    • Layer :每个图层代表图像Dockerfile中的一条指令 .

    Example :下面的Dockerfile包含四个命令,每个命令都创建一个图层 .

    来自ubuntu:15.04 COPY . / app RUN make / app CMD python /app/app.py

    Importantly ,每一层只是与之前一层的一组差异 .

    • Container . 创建新容器时,可以在基础图层的顶部添加新的可写层 . 该层通常称为“容器层” . 对正在运行的容器所做的所有更改(例如写入新文件,修改现有文件和删除文件)都将写入此可写容器层 .

    因此,容器和图像之间的主要区别是顶部可写层 . 对添加新数据或修改现有数据的容器的所有写入都存储在此可写层中 . 删除容器时,也会删除可写层 . 基础图像保持不变 .

    Understanding images cnd Containers from a size-on-disk perspective

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

    • 尺寸:用于每个容器的可写层的数据量(在磁盘上)

    • 虚拟大小:容器使用的只读图像数据所使用的数据量 . 多个容器可以共享一些或所有只读图像数据 . Hence these are not additive. I.e. you can't add all the virtual sizes to calculate how much size on disk is used by the image

    Another important concept is the copy-on-write strategy

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

    我希望能帮助别人喜欢我 .

相关问题