docker原理
docker run命令的作用是在一个全新的Docker容器内部运行一条指令。Docker在执行这条命令的时候,所做工作可以分为两部分:第一,创建Docker容器所需的rootfs;第二,创建容器的网络等运行环境,并真正运行用户指令。因此,在整个执行流程中,Docker Client给Docker Server发送了两次HTTP请求,第二次请求的发起取决于第一次请求的返回状态。Docker run命令执行流程如图5.2。
图5.2 docker run命令执行流程示意图
如图,图中标记的红色箭头表示docker run命令在发起后,Docker所做的一系列运行。以下逐一分析这些步骤。
(1) Docker Client接受docker run命令,解析完请求以及收集完请求参数之后,发送一个HTTP请求给Docker Server,HTTP请求方法为POST,请求URL为”/containers/create? “+”xxx”;
(2) Docker Server接受以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler;
(3) mux.Router将请求路由分发至相应的handler,具体为PostContainersCreate;
(4) 在PostImageCreate这个handler之中,一个名为”create”的job被创建,并开始让该job运行;
(5) 名为”create”的job在运行过程中,执行Container.Create操作,该操作需要获取容器镜像来为Docker容器创建rootfs,即调用graphdriver;
(6) graphdriver从Graph中获取创建Docker容器rootfs所需要的所有的镜像;
(7) graphdriver将rootfs所有镜像,加载安装至Docker容器指定的文件目录下;
(8) 若以上操作全部正常执行,没有返回错误或异常,则Docker Client收到Docker Server返回状态之后,发起第二次HTTP请求。请求方法为”POST”,请求URL为”/containers/“+container_ID+”/start”;
(9) Docker Server接受以上HTTP请求,并交给mux.Router,mux.Router通过URL以及请求方法来确定执行该请求的具体handler;
(10)mux.Router将请求路由分发至相应的handler,具体为PostContainersStart;
(11)在PostContainersStart这个handler之中,名为”start”的job被创建,并开始执行;
(12)名为”start”的job执行完初步的配置工作后,开始配置与创建网络环境,调用networkdriver;
(13)networkdriver需要为指定的Docker容器创建网络接口设备,并为其分配IP,port,以及设置防火墙规则,相应的操作转交至libcontainer中的netlink包来完成;
(14)netlink完成Docker容器的网络环境配置与创建;
(15)返回至名为”start”的job,执行完一些辅助性操作后,job开始执行用户指令,调用execdriver;
(16)execdriver被调用,初始化Docker容器内部的运行环境,如命名空间,资源控制与隔离,以及用户命令的执行,相应的操作转交至libcontainer来完成;
(17)libcontainer被调用,完成Docker容器内部的运行环境初始化,并最终执行用户要求启动的命令。
7.1 虚拟化技术
首先,Docker 容器虚拟化技术为基础的软件,那么什么是虚拟化技术呢?
简单点来说,虚拟化技术可以这样定义:
虚拟化技术是一种资源管理技术,是将计算机的各种实体资源)(CPUopen in new window、内存open in new window、磁盘空间open in new window、网络适配器open in new window等),予以抽象、转换后呈现出来并可供分割、组合为一个或多个电脑配置环境。由此,打破实体结构间的不可切割的障碍,使用户可以比原本的配置更好的方式来应用这些电脑硬件资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。
# 7.2 Docker 基于 LXC 虚拟容器技术
Docker 技术是基于 LXC(Linux container- Linux 容器)虚拟容器技术的。
LXC,其名称来自 Linux 软件容器(Linux Containers)的缩写,一种操作系统层虚拟化(Operating system–level virtualization)技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。通过统一的名字空间和共用 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。
LXC 技术主要是借助 Linux 内核中提供的 CGroup 功能和 namespace 来实现的,通过 LXC 可以为软件提供一个独立的操作系统运行环境。
cgroup 和 namespace 介绍:
namespace 是 Linux 内核用来隔离内核资源的方式。 通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。
(以上关于 namespace 介绍内容来自https://www.cnblogs.com/sparkdev/p/9365405.html ,更多关于 namespace 的呢内容可以查看这篇文章 )。
CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。