什么是Docker Engine

Docker是一个CS架构的应用,主要组件包含:

  • 一个长时间运行的守护进程服务
  • 一个可以与守护进程通信并向守护进程发送操作命令的REST API
  • 一个命令行客户端

Alt Image Text

为什么用Docker

  • 快速一致分发应用
  • 部署和伸缩更简单
  • 在同样的硬件上运行更多的工作量
  • 快速的部署使管理更简单

Docker的架构

Alt Image Text

Docker daemon

Docker Daemon运行在主机之上。用户可以使用Docker客户端与守护进程交互。

Docker client

docker二进制格式的文件,Docker的主要用户接口。

Docker内部

Docker images

Docker镜像是一个只读模板,包含创建Docker容器的说明。

Docker container

Docker容器是一个可以运行的Docker images的实例。可以通过Docker API或Docker命令行接口运行、启动、停止、移动或删除容器。

Docker registries

Docker registry是一个镜像的库,可以是私有的,也可以是公开的,可以与Docker daemon或Docker client在同一台服务器或者在一台独立的服务器上。

Docker services

Docker服务允许一组Docker节点一起工作,运行定义数量的副本任务实例,本身是一个Docker镜像。 您可以指定要运行的并发复制副本任务的数量,并且swarm管理器确保负载均匀分布在工作节点上。 对于消费者,Docker服务似乎是一个单一的应用程序。 Docker Engine支持Docker 1.12及更高版本中的swarm模式。

Docker 镜像怎么工作?

Docker镜像是只读模板,从中Docker容器被实例化。每个图像由一系列层组成。 Docker使用联合文件系统将这些图层组合成单个图像。联合文件系统允许单独文件系统的文件和目录(称为分支)被透明地覆盖,形成单个一致的文件系统。

这些层是Docker如此轻量级的原因之一。 当您更改Docker镜像时,例如,当您将应用程序更新到新版本时,会创建一个新图层,并仅替换其更新的图层。其他层保持完整。 要分发更新,您只需传输更新的层。分层加速了Docker镜像的分布。Docker确定哪些层需要在运行时更新。

镜像在Dockerfile中定义。每个镜像从基本镜像开始,例如ubuntu,基本Ubuntu镜像,或Fedora,基本Fedora镜像。您还可以使用自己的镜像作为新镜像的基础,例如,如果您有一个基本Apache镜像,您可以将其用作所有Web应用程序镜像的基础。基本镜像是使用dockerfile中的FROM关键字定义的。

docker镜像是使用我们称为指令的简单的描述性步骤从基本镜像构建的,这些步骤存储在Dockerfile中。 每个指令在图像中创建一个新图层。 Dockerfile指令的一些示例是:

  • 指定基础镜像 [FROM]
  • 指定维护者 [MAINTAINER]
  • 运行一个命令 [RUN]
  • 添加一个文件或目录 [ADD]
  • 创建一个环境变量 [EVN]
  • 从一个镜像启动一个容器时执行什么命令 [CMD]

当请求创建一个镜像,执行这些指令,返回一个镜像时,Docker读取这个Dockerfile

容器怎么工作?

容器使用主机的Linux内核,包括在创建映像时添加的任何额外文件,以及在创建或容器启动时与容器关联的元数据。每个容器由镜像构建。该镜像定义容器的内容,启动容器时运行的进程以及各种其他配置详细信息。Docker镜像是只读的。当Docker从镜像运行容器时,它会在镜像的顶部(使用我们之前看到的UnionFS)添加一个读写层,您的应用程序在该镜像上运行。

当运行一个容器时发生了什么?

当您使用docker运行CLI命令或等效的API时,Docker Engine客户端指示Docker守护程序运行容器。此示例告诉Docker守护程序使用ubuntu Docker镜像运行容器,以交互模式(-i)保持在前台,并运行/bin/bash命令。

$ docker run -i -t ubuntu /bin/bash

当您运行此命令时,Docker Engine执行以下操作:

1、拉取ubuntu镜像:Docker Engine检查ubuntu镜像的存在。如果镜像已在本地存在,Docker Engine会将其用于新容器。否则,Docker Engine会从Docker Hub中获取它。

2、创建一个新容器:Docker使用镜像创建一个容器。

3、分配文件系统并装载读写层:容器在文件系统中创建,并将读写层添加到镜像。

4、分配网络/网桥接口:创建一个允许Docker容器与本地主机通信的网络接口。

5、设置一个IP地址:从地址池中查找并附加可用的IP地址。

6、执行您指定的进程:执行/bin/bash可执行文件。

7、捕获并提供应用程序输出:连接并记录标准输入,输出和错误,以便查看应用程序是如何运行的,因为您请求了交互模式。

您的容器现在正在运行。您可以管理和交互,使用它提供的服务和应用程序,并最终停止和删除它。

基础技术

Docker是用Go编写的,并利用Linux内核的几个功能来提供他的功能。

命名空间

Dcoker使用一种叫namespaces的技术来提供为容器的隔离工作空间。当你运行一个容器是,Docker为该容器创建一组命名空间。

这些命名空间提供了一个隔离层。容器的每个方面都运行在单独的命名空间中,并且其访问仅限于该命名空间。

Docker Engine在Linux上使用如下命名空间:

  • pid命名空间:隔离进程 [PID:Process ID]
  • net命名空间:管理网络接口 [NET:Networking]
  • ipc命名空间:管理IPC资源的访问 [IPC:InterProcess Communication]
  • mnt命名空间:管理文件系统挂载点 [MNT:Mount]
  • uts命名空间:隔离内核和版本标识符 [UTS:Unix Timesharing System]
控制组

Linux上的Docker Engine还依赖于另一种称为控制组(cgroups)的技术。cgroups将应用程序限制为特定的一组资源。控制组允许Docker Engine将可用的硬件资源共享到容器,并且可选的实施限制和约束。例如:您可以限制特定容器可用的内存。

联合文件系统

联合文件系统或者UnionFS是通过创建层操作的文件系统,使它们非常轻便和快速。Docker Engine使用UnionFS提供容器的构建块。Docker Engine可以使用多个UnionFs的变体,包括AUFS,btrfs,vfs和DeviceMapper。

容器格式

Docker Engine将命名空间,控制组和UnionFS组合成一个称为容器格式的包装器。默认容器格式为libcontainer。在将来,Docker可以通过与诸如BSD Jails或Solaris Zones等技术集成来支持其他容器格式。

文章内容大部分来自https://docs.docker.com/engine/understanding-docker/

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐