Docker引擎(engine)学习总结

        今日要准备容器培训,学习了docker engine相关的知识,总结记录下。

1、Docker 引擎

        Docker 引擎是用来运行和管理容器的核心软件,采用模块化的设计原则,在许多专用部件的协同工作下实现创建和运行容器,之所以介绍这个是因为它和原理息息相关。

2、早期Docker引擎架构

        Docker 首次发布时,Docker 引擎由两个核心组件构成:LXC 和 Docker daemon。
        Docker daemon 是单一的二进制文件,包含诸如 Docker 客户端、Docker API、容器运行时、镜像构建等。
        LXC 提供了对诸如命名空间(Namespace)和控制组(CGroup)等基础工具的操作能力,它们是基于 Linux 内核的容器虚拟化技术。
        下图阐释了在 Docker 旧版本中,Docker daemon、LXC 和操作系统之间的交互关系。

        早期架构存在以下问题:

        1、对 LXC 的依赖。LXC 是基于 Linux 的。这对于一个立志于跨平台的项目来说是个问题。
如此核心的组件依赖于外部工具,这会给项目带来巨大风险,甚至影响其发展。因此,Docker 公司开发了名为 Libcontainer 的自研工具,用于替代 LXC。Libcontainer 的目标是成为与平台无关的工具,可基于不同内核为 Docker 上层提供必要的容器交互功能。 

        2、Docker daemon太过臃肿。随着时间的推移,Docker daemon 的整体性带来了越来越多的问题。难于变更、运行越来越慢。Docker 公司意识到了这些问题,开始努力着手拆解这个大而全的 Docker daemon 进程,并将其模块化。

3、目前Docker引擎架构

        该模型的显著优势:

        将所有的用于启动、管理容器的逻辑和代码从 daemon 中移除,意味着容器运行时与 Docker daemon 是解耦的,有时称之为“无守护进程的容器(daemonless container)”,如此,对 Docker daemon 的维护和升级工作不会影响到运行中的容器。在旧模型中,所有容器运行时的逻辑都在 daemon 中实现,启动和停止 daemon 会导致宿主机上所有运行中的容器被杀掉。这在生产环境中是一个大问题——想一想新版 Docker 的发布频次吧!每次 daemon 的升级都会杀掉宿主机上所有的容器,这太糟了!幸运的是,这已经不再是个问题。

4、各组件功能描述

组件 描述
/usr/bin/docker docker客户端,直接面向操作用户;docker与dockerd通过/var/run/docker.sock通讯
/usr/bin/dockerd  dockerd即Docker Daemon,是Docker的守护进程;dockerd本身实属是对容器相关操作的api的最上层封装,daemon的主要功能包括镜像管理、镜像构建、RESTAPI、身份验证、安全、核心网络以及编排;dockerd与containerd通信socket文件为/run/containerd/containerd.sock
/usr/bin/containerd dockerd实际真实调用的还是containerd的api接口,containerd是dockerd和runc之间的一个中间交流组件;containerd组件确保了Docker镜像能够以正确的OCI Bundle的格式传递给runc。
/usr/bin/containerd-shim containerd-shim是一个运行的容器的真实垫片载体,每启动一个容器都会起一个新的docker-shim进程。
他直接通过指定的三个参数:容器id,boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID),运行二进制(默认为runc)来调用runc的api创建一个容器(比如创建容器:最后拼装的命令如下:runc create );他主要有以下三个作用:
1.允许runc在创建&运行容器之后退出
Go编译出来的二进制文件,默认是静态链接,因此,如果一个机器上起N个容器,那么就会占用M*N的内存,其中M是一个runc所消耗的内存。但是出于上面描述的原因又不想直接让containerd来做容器的父进程,因此,就需要一个比runc占内存更小的东西来作父进程,也就是shim。
2.用shim作为容器的父进程,而不是直接用containerd作为容器的父进程,是为了防止这种情况:当containerd挂掉的时候,shim还在,因此可以保证容器打开的文件描述符不会被关掉
shim的主要作用,就是将containerd和真实的容器(里的进程)解耦
3.依靠shim来收集&报告容器的退出状态,这样就不需要containerd来wait子进程
/usr/bin/containerd-shim-runc RunC是运行容器的运行时,根据oci(开放容器组织)的标准来创建和运行容器,它负责利用符合标准的文件等资源运行容器,但是它不包含docker那样的镜像管理功能。所以要用runC运行容器,我们先得准备好容器的文件系统。所谓的OCI bundle就是指容器的文件系统和一个config.json文件。有了容器的文件系统后我们可以通过runc spec命令来生成config.json文件。
Runc实质上是一个轻量级的、针对Libcontainer进行了包装的命令行交互工具
/usr/bin/docker-init 我们都知道UNIX系统中,1号进程是init进程,也是所有孤儿进程的父进程。
而使用docker时,如果不加 --init 参数,容器中的1号进程就是所给的ENTRYPOINT,而加上 --init 之后,1号进程就会是 tini。
/usr/bin/docker-proxy 用来做容器和宿主机之间的端口映射,其底层是使用iptables来完成的。
Docker run -d -p 10010:10010 busybox sleep10000,ps aux|grep docker命令可以查看规则。
OCI标准 容器运行时,Container runtime是指管理和运行容器的工具,当前的容器工具很多,比如docker,rkt等,但是如果每个容器工具都使用
自己的运行时,那么就不利于容器领域的发展,因此,一些容器厂商就一起制定了容器镜像格式和容器运行时的标准,
即OpenContainerInitiative(OCI)。Docker公司参与了OCI着手定义的两个容器相关的规范:镜像规范和容器运行时规范。
OCIbundle OCI Bundle是指满足OCI标准的一系列文件,这些文件包含了运行容器所需要的所有数据,它们存放在一个共同的目录,该目录包含以下两项:1、config.json:包含容器运行的配置数据;2、容器的文件系统
镜像--OCI Bundle--runc--容器

5、参考

https://jiajunhuang.com/articles/2018_12_24-docker_components_part2.md.html

http://c.biancheng.net/view/3137.html

http://events.jianshu.io/p/d08fb1f5de9d

https://www.jianshu.com/p/2e0e33dac632

https://zhuanlan.zhihu.com/p/59796137

猜你喜欢

转载自blog.csdn.net/weixin_39855998/article/details/126895703