Docker 引擎(engine)
(一)概述
1.简述
docker引擎是用来运行和管理容器的核心软件。代称Docekr或者Docker平台
类比于VMware,将Docker引擎理解为ESXi的角色
2.OCI标准
基于开放容器计划,Docker引擎采用了模块化的设计原则,组件是可替换的。
-
构成
(1) Docker客户端(Docker Client)
(2) Docker守护进程(Docker daemon)
(3) containerd
(4) runc
-
发展
Docker首次发布时,采用的构成如下:
LXC:提供了对命名空间(Namespace)和控制组(CGroup)等基础工具的操作能力,基于Linux内核的容器虚拟化技术。
Docker daemon是单一的二进制文件,包含Docker客户端、Docker API、容器运行时、镜像构建等
摆脱LXC
LXC是基于linux的,对于一个跨平台的项目来说是一个问题。
并且,核心的组件需要依赖于外部的凭条,这会给项目带来风险。
Docker公司发明了Libcontainer的自研工具,用于替代LXC
Libcontainer的目标是成为与平台无关的工具,可基于不同内核为Docker上提供必须的容器交互工能。
docker0.9版本后,Libcontainer取代了LXC成为默认的执行驱动。
模块化daemon
Docker daemon整体涵盖的东西过多,导致了难以变更,运行越来越慢。Docker意识到这个问题之后,开始将大而全的Docker daemon进行拆解,并将其模块化。
runc
- 定义:runc是一个轻量级的、针对libcontainer进行包装的命令行交互工具。
- 作用:创建容器。(CLI包装器,实质上是一个独立的容器运行时工具)
- 拓:runc所在的那一层,也称之为OCI层。
containerd
- 功能:所有容器执行逻辑,主要任务是容器的生命周期管理(strat|stop|pause|rm…)
- 位于daemon和runc所在的OCI层之间,从1.11版本之后Docker开始在linux上使用。
启动一个新容器
$ docker container run --name ctr1 -it alpine:latest sh
当使用Docekr命令行工具执行上诉命令时,Docker客户端会将其转换成为合适的API格式,并将其发送到正确的API端点。
(API实在daemon中实现的,这套功能丰富、基于版本的REST API成为Docker的标志)
一旦daemon接收到创建容器的命令,它就会向container发出调用。
(daemon使用一种CRUD风格API,通过gRPC与container进行通信)
container将Docker镜像转换成OCI bundle,并让runc基于此创建一个新的容器。
runc与操作系统内核接口进行通信,基于所有必要工具(Namespace、CGroup等)来创建容器。容器进程作为runc的子进程启动,启动完毕后,runc将会退出。
shim
shim是实现无daemon的容器(用于将运行中的容器与daemon解耦,以便进行daemon升级等操作)不可或缺的工具。
每次创建容器,都会fork一个新的runc实例。创建容器完毕后,对应的runc进程就会退出。因此,即使运行上百个容器,也无需保持runc实例。
当然,一旦容器进程runc退出,相关联的containerd-shim进程就会成为容器的父进程。作为容器的父进程,shim的职责:
- 保持所有STDIN和STDOUT流是开启状态,从而当daemon重启的时候,容器不会因为管道(pipe)的关闭而终止。
- 将容器的退出状态反馈给daemon。
daemon的作用
将所有用于启动、管理容器的逻辑和代码从daemon中移除,意味着容器运行时与Docker daemon是解耦的,有时称之为无守护进程的容器(daemonless container)
那么剩余的功能还有什么:
- 镜像管理
- 镜像构建
- REST API
- 身份验证
- 安全
- 核心网络
- 编排
个人学习使用
文章总结出处