在Docker中,容器和图像的区别是什么?

Docker中容器和图像的区别是什么?在从Docker教程开始中,这两个术语都被使用,但我不明白其中的区别。

谁能给我点灯?

93345 次浏览

映像是根文件系统更改和容器运行时中使用的相应执行参数的有序集合。映像是只读的。

容器是映像的活动(退出时为非活动)状态实例化。

映像是活动容器的冻结的不可变快照。容器是正在运行(或已停止)某个映像的实例。

从名为“ubuntu”的基本图像开始。让我们在ubuntu映像中交互式地运行bash并创建一个文件。我们将使用-i-t标志来提供一个交互式bash shell。

$ 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

退出并重新启动映像时,不要期望该文件仍然存在。您将从与之前开始时完全相同的定义状态重新开始,而不是从您离开的地方重新开始。

$ 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

但是,容器现在不再运行,它有状态,可以保存(提交)到一个映像。

$ 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中创建一个图像:

$ docker commit 48cff2e9be75 ubuntu-foo
d0e4ae9a911d0243e95556e229c8e0873b623eeed4c7816268db090dfdd149c2

现在,我们有了一个非常重要的文件的新图像:

$ docker run ubuntu-foo /bin/cat foo
This is a really important file!!!!

试试docker images命令。你应该看到你的新图像ubuntu-foo与我们开始时的ubuntu标准图像一起列出。

映像基本上是用于创建容器的不可变模板。通过考虑将图像转换为容器所发生的变化,可以更容易地理解图像和容器之间的区别。

Docker引擎获取映像并在其顶部添加一个读写文件系统,然后初始化各种设置。这些设置包括网络选项(IP、端口等)、名称、ID和任何资源限制(CPU、内存)。如果Docker引擎被要求运行容器,它也会在容器中初始化一个进程。容器可以停止并重新启动,在这种情况下,它将保留所有设置和文件系统更改(但将丢失内存中的任何内容,所有进程将重新启动)。因此,一个停止或退出的容器与一个映像相同。

使用面向对象编程的类比,Docker镜像和Docker容器之间的区别就像类和对象之间的区别一样。对象是类的运行时实例。类似地,容器是映像的运行时实例。

对象在实例化时只创建一次。类似地,容器可以运行也可以停止。容器是根据映像创建的,尽管情况可能并不总是如此。下面的例子创建一个Apache服务器镜像,运行镜像,列出镜像,然后列出容器:

  1. 创建一个Dockerfile,内容如下:

    FROM httpd:2.4
    
  2. Install Apache server

    sudo docker build -t my-apache2 .
    
  3. Run the image

    sudo docker run -it --rm --name my-running-app my-apache2
    
  4. List Docker images

    sudo docker images
    
  5. List the running Docker containers

    docker ps
    
  6. List all containers

    docker ps -a
    
  7. List latest created containers

    docker ps -l
    

容器是基于图像的。需要将图像传递给Dockers run命令。

例子:

BusyBox形象

http://i.stack.imgur.com/eK9dC.png

这里我们指定了一个名为busybox的图像。Docker在本地没有这个映像,而是从公共注册表中获取它。

注册表是Docker镜像的目录,Docker客户端可以与之通信并从中下载镜像。一旦图像被拉出,Docker启动一个容器并执行echo hello world命令。

在Docker中,一切都从图像开始。映像是构成操作系统所需的所有文件。传统上,您需要为每个应用程序安装一个完整的操作系统。使用Docker,你可以把它配对,这样你就有一个小容器,里面有足够的操作系统来做你需要做的事情,你可以在一台计算机上高效地拥有很多很多这样的容器。

使用docker images查看已安装的映像,使用docker ps查看正在运行的映像。 当你输入docker run时,它会获取映像,并使其成为一个带有运行进程的活容器。我倾向于使用:

docker运行-ti <image>:<tag> bash

最后,图像有它们自己的id集,容器也有它们自己的id集——它们不重叠。

图片[像vm]

  • 用于创建容器的只读模板
  • 由您或其他Docker用户构建
  • 存储在Docker Hub或本地注册表中

容器[像运转的机器]

  • 隔离应用平台
  • 包含运行应用程序所需的所有内容
  • 基于图像

images链接显示什么是容器

< p >码头工人图片: 它包含一个关于如何构建和运行容器的命令和指令列表。因此,基本上Images包含启动容器(也称为blueprint)所需的所有数据和元数据。

< p > <代码> $docker images centos < /代码> < / p >

列出所有可用的centos版本。

< p >码头工人容器: 容器是图像的午餐,因此我们可以说容器是图像的运行实例。 Container是一个运行时构造,不像Images是构建时构造。< / p >

DockerFile——(构建)——> DockerImage——(运行)——> DockerContainer

< em > DockerFile < / em >是你或开发人员编写代码来做某事(安装前)

< em > < / em >码头工人形象是你在构建docker文件时得到的。

< em > < / em >码头工人容器是你运行Docker映像时得到的

我们可以通过拖动Docker hub来获取Docker Image,然后运行它来获取container。

官方的区别是容器层是最后一个可写的层,而下面的层只可读,它们属于你的图像。直观的区别是docker实例是由docker守护进程虚拟化的实例,它运行在内核的一个隔离部分中(这个过程对你是隐藏的)。然而,图像是静态的,它不运行,它只是一堆层(静态文件)。如果我们将此范例与面向对象编程联系起来,则映像是类定义,而docker实例是驻留在内存中的类派生对象。

我写了一个教程来加强你的docker知识直觉:

http://javagoogleappspot.blogspot.com/2018/07/docker-basics.html

图片:运行容器所需的文件系统和元数据。它们可以被认为是一种应用程序打包格式,其中包括运行应用程序的所有依赖项,以及执行该应用程序的默认设置。元数据包括要运行的命令的默认值、环境变量、标签和healthcheck命令。

容器:一个隔离应用程序的实例。容器需要映像来定义其初始状态,并使用映像中的只读文件系统以及容器特定的读写文件系统。正在运行的容器是正在运行的进程的包装器,为文件系统、网络和pid等提供进程名称空间。

当你执行docker run命令时,你在命令行上提供一个映像,以及任何配置,docker根据你提供的映像定义和配置返回一个容器。


参考文献:对于docker引擎,图像只是一个图像id。这是一个唯一的不可变哈希。对映像的更改将导致创建一个新的映像id。但是,您可以有一个或多个指向图像id的引用,这与符号链接类似。这些引用可以更新为指向新的图像id。注意,当你创建一个容器时,docker会在容器创建时解析这个引用,所以你不能更新正在运行的容器的镜像。相反,您将创建一个新映像,并基于该新映像创建一个新容器。

:再深入一点,你有文件系统层。Docker使用分层的文件系统组装图像。每一层都是对文件系统的只读更改集,该层由唯一的散列表示。使用这些只读层,多个图像可以扩展另一个图像,并且只有这些图像之间的差异需要通过网络存储或传输。当Docker容器运行时,它接收到一个容器特有的读写文件系统层,所有的映像层都使用联合文件系统与之组装。读取操作在每一层中进行,直到找到文件、删除或在底层中找不到文件为止。写入执行从映像只读层到容器特定的读写层的写时复制。删除被记录为对容器特定读写层的更改。构建映像的一个常见步骤是在基于先前映像文件系统状态的临时容器中运行命令,并将生成的特定于容器的层保存为新映像中的一层。

图像是用你的手机拍摄的照片。
容器为话机

.< br/>容器为话机