背景:最近在看k8s的一些内容,发现里面的一些配置不知道他们在干嘛。因为还不懂容器原理,所以学起容器编排我觉得会事倍功半,所以回头看docker的知识,心中建立一套容器体系。参考书籍为《深入浅出docker》
目录
docker引擎历史
docker首次发布:
docker首次发布:核心引擎由LXC和Docker Daemon构成。
- 1、LXC提供基础工具的操作能力,如命名空间(Namespace)、控制组(CGroup)等。它是基于linux内核的容器虚拟化技术。
- 2、Docker Daemon时单一的二进制文件,包含了Docker客户端、Docker API、容器运行时、镜像构建等。
- 3、Docker Daemon与LXC关系如下:
摆脱LXC的Linux依赖
LXC的依赖:
- 1、LXC是基于Linux的对实现跨平台来说是个很大的问题。
- 2、LXC核心组件依赖于外部工具,会给项目带来巨大风险。
Libcontainer替代LXC: 为了解决这个问题Docker公司自研了Libcontainer工具,代替LXC。
- Libcontainer特性:可实现跨平台。
- 原理:可让docker基于不同内核,为docker上层提供容器交互功能。
拆解大而全的Docker Daemon
docker发展瓶颈:
- 整体性的DockerDaemon为发展带来很多问题:1、难于变更
- 2、运行越来越慢
- 3、并非符合生态和公司的发展路线
解决思路:拆卸DockerDaemon进程、将其模块化。模块用小而专的工具实现。工具可以替换或者被其他第三方使用。
目前阶段:
至目前为止,容器运行时和容器执行代码已全部从Docker Daemon移除。引擎加入如下图所示:
docker组件介绍
OCI(开放容器计划)
docker执行拆卸计划时、OCI着手定义容器相关的两个规范:1、镜像规范;2、容器运行时规范。2017年7月1日发布了0.1版本。
受OCI的影响:
- 1 、docker Daemon不包含容器运行时代码,所有容器运行时代码在单独的OCI兼容层实现,默认情况下就是RUNC
- 2、 Docker引擎中的Containerd的作用时,保证传给RUNC的镜像是以OCI Bunddle格式。
RUNC
描述:
- 他是OCI容器运行时的
规范
。 - 他是针对Libcontainer的
命令行交互工具
- 他是独立的容器运行是工具,可直接下载然后拆卸使用。
- 他只有一个作用,就是
创建容器
。 - runc这一层称为OCI层
Containerd
描述:
- 主要任务是管理容器生命周期。(start|stop|pause|rm…).
- 随着时间推移,功能也增加了,比如镜像管理。
- Containerd有docker公司开发,并捐赠给了CNCF云原生计算基金会。
shim(看不懂可结合后面内容一起思考)
作用时机:每次container指挥runc创建容器都会fork一个新runc实例,但是容器创建完后就会runc实例被销毁,但是容器依然存在。父进程runc退出后相关联的containerd-shim称为容器的父进程。
shim部分职责如下:
- 1、保持STDIN和STDOUT流是开启状态:daemon重启时,容器不会因为管道关闭而退出。
- 2、将容器状态反馈给daemon。
docker daemon
经过发展,执行逻辑和运行时代码都从daemon中剥离,还剩的功能:镜像管理、镜像构建、RESTAPI、身份认证、安全、核心网络以及编排(这些功能都可能会逐渐被剥离)
实例讲解
启动容器时,各组件运行过程
当执行 docker container run --name ctrl -it jdk8:last sh时:
- docker客户端将命令转为合适的API格式、发送到正确API端点,API在daemon中实现。
- daemon接收到创建容器命令,想docker containerd发出调用。(daemon不包含创建容器代码)
- containerd将镜像转为OCI bundle,并让runc基于此创建新的容器
- runc与操作系统内核借口进行通信,基于必要工具来创建容器(NameSpace、CGroup等)。
- runc 创建完毕后销毁实例,由container-shim关联为容器父进程。
过程如下
模型优势
旧模型,docker运行时的逻辑都在daemon中实现,当docker daemon升级时,宿主机容器将会被杀死;现在各个功能都被模块化,daemon已经不掌握docker容器的运行时逻辑,就算升级,容器也不会被杀死
在Linux系统中实现
起那面的所有组件由二进制进行实现。
- dockerd(docker daemon)
- docker-containerd(containerd)
- docker-container-shim(shim)
- docker-runc(runc)。
可在宿主机上通过ps查看进程。