Docker引擎-----简介
Docker引擎是用来运行和管理容器的核心软件。通常人们会简单的将其代指为Docker或Docker平台,如果你对VM有所了解,可以将Docker引擎理解为ESXi的角色。
基于开放容器计划(OCI)相关标准要求,Docker引擎采用了模块化的设计原则,其组件是可以替换的。
Docker引擎的组成:① Docker客户端(Docker Client),② Docker守护进程(Docker daemon),③ containerd,④ runc。他们共同负责容器的创建和运行。
目前Docker引擎的架构示意图如下:
runc:
runc是OCI容器运行时规范的参考实现,其实质上是一个轻量级。针对Libcontainer进行了包装的命令行交互工具(Libcontainer取代了早起Docker架构中的LXC)
runc生来只有一个作用 ---创建容器
containerd:
在对Docker daemon的功能进行拆解后,所有的容器执行逻辑呗重构到一个新的心的名为containerd的工具中,主要任务是容器的生命管理周期-------start | stop | pause | rm ...
在Docker引擎技术栈中,containerd位于daemon和runc所在的OCI层之间。
shim:
shim是实现无daemon的容器不可或缺的工具。下面会提到,containerd指挥runc来创建新容器,事实上,每次创建容器时它都会fork一个新的runc实例,不过一旦容器创建完毕,对应的runc进程就会退出,因此,即使运行上百个容器,也无须保持上百个运行中的runc实例。一旦容器进程的父进程runc退出,相关联的containerd-shim进程就会成为容器的父进程,作为父进程,其作用:
①:保持所有STIND和STDOUT流是开启状态,从而当daemon重启的时候,容器不会因为管道的关闭而终止
②:将容器的退出状态反馈给daemon
daemon:
随着越来越多的功能从daemon中拆解出来并被模块化,daemon的主要功能包括镜像管理,镜像构建,REST API,身份验证,安全,核心网络以及编排等
Docker启动一个容器过程:
上面我们对docer引擎有了一个基本的认识,下面我们了解一下创建新容器的过程
最常用的启动容器的方式就是使用docker命令行工具,如下:
docker container run --name ctrl -it alpine:latest sh
①:当使用上述命令时,docker客户端会将其转换为合适的API格式,并发送至正确的API端点
②:Api是在daemon中实现的
③:一旦daemon接收到创建新容器的命令,它就会想containerd发出调用,daemon已经不再包含创建容器的代码了
④:daemon使用一种CRUD风格的API,通过gRPC与containerd进行通信
⑤:虽然叫containerd,但是它并不负责创建容器,而是指挥runc去做,containerd将docker镜像转换为OCI bundle,并让runc基于此创建一个新容器
⑥:runc与操作系统内核接口进行通信,基于所有必要的工具(Namespace,CGroup等)来创建容器,容器进程作为runc的子进程启动,启动完毕后,runc退出
该模式优点:
将所有用于启动,管理容器的逻辑和代码从daemon中移除,意味着容器运行时与docker daemon是解耦的,有时称之为“无守护进程的容器”,因此,对docker daemon的维护升级不会影响到运行中的容器