1、镜像

镜像是一个只读模板,包含创建Docker容器的说明。通常,一个镜像基于另一个镜像附带一些额外的配置。例如,可以构建一个基于Ubuntu镜像的镜像,但在里面安装Apache Web服务器和应用程序,以及一些确保网站可以详细运行的应用配置(如开放80端口)。

用户可以创建自己的镜像,或者使用其他人发布在注册中心的公开镜像。当创建自己的镜像时需要用特定的语法创建一个Dockerfile,每一个Dockerfile描述都会创建一个层级在你的镜像里,当改变Dockerfile重建镜像时,只有对应的层级会被改变。这样可使镜像轻量化,效率高,灵活性强。

通常使用docker container run和docker service create命令从某个镜像启动一个或多个容器。

一旦容器从镜像启动后,二者之间就变成了互相依赖的关系,并且在镜像上启动的容器全部停止之前,镜像是无法被删除的。尝试删除镜像而不停止或销毁使用它的容器,会导致出错。

镜像通常比较小,容器的目的就是运行应用或者服务,这意味着容器的镜像中必须包含应用服务运行所必需的操作系统和应用文件。

但是,容器又追求快速和小巧,这意味着构建镜像时通常需要裁剪掉不必要的部分,保持较小的体积。例如,Docker镜像通常不会包含6个不同的Shell让用户选择——通常Docker镜像中只有一个精简的Shell,甚至没有Shell。镜像中还不包含内核——容器都是共享所在Docker主机的内核。所以,有时会说容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象)。

在Docker的术语里,一个只读层被称为镜像,一个镜像是永远不会变的。

由于Docker使用一个统一文件系统,Docker进程认为整个文件系统是以读写方式挂载的。但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不可写,所以镜像是无状态的。

由于Docker使用一个统一文件系统,Docker进程认为整个文件系统是以读写方式挂载的。但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不可写,所以镜像是无状态的。

  • 父镜像

每一个镜像都可能依赖于由一个或多个下层而组成的另一个镜像。可以说,下层镜像是上层镜像的父镜像。

  • 基础镜像

一个没有任何父镜像的镜像,称为基础镜像。

  • 镜像ID

所有镜像都是通过一个64位十六进制字符串(内部是一个256 bit的值)来标识的。为简化使用,前12个字符可以组成一个短ID,可以在命令行中使用。短ID有一定的碰撞几率,所以服务器总是返回长ID

2、容器

容器是镜像的可运行实例。用户可以使用Docker API或CLI创建、启动、停止、移动或删除容器,还可以将容器连接到一个或多个网络,为其附加存储,甚至可以根据其当前状态创建新映像。

默认情况下,容器与其他容器及其主机相对隔离。用户可以控制容器的网络、存储或其他底层子系统与其他容器或主机之间的隔离程度。容器由其映像及在创建或启动它时提供给它的任何配置选项定义。当容器被移除时,未存储在持久存储中的对其状态的任何更改都会消失。

3、数据卷

Docker的镜像是由多个只读的文件系统叠加在一起形成的。启动一个容器时,Docker会加载这些只读层,并在这些只读层的上面(栈顶)增加一个读写层。此时,如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除Docker或者重新启动时,之前的更改将会消失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。

4、仓库

镜像仓库(Docker Repository)用于存储具体的Docker镜像,起到仓库存储的作用,比如Tomcat下面有很多版本的镜像,它们共同组成了Tomcat的Repository,通过tag来区分镜像版本,Registry上有很多Repositor。