阅读更多
1 容器
1.1 容器发展史
1.2 docker组件介绍
docker(/usr/bin/docker
):在早期版本中(1.11.x
之前),docker的所有功能都用这一个二进制完成,同时充当docker-cli
以及docker-daemon
。1.11.x
版本之后,docker只充当docker-cli
这一角色
dockerd(/usr/bin/dockerd
):以Docker Engine API
对外提供服务,可以通过三类socket进行API调用,分别是:unix
、tcp
、fd
(默认用的是unix
。实际上,dockerd
只是一个中间层,容器、镜像的生命周期管理动作,实际上是由containerd
完成的,dockerd
与containerd
之间通过grpc
通信
containerd(/usr/bin/docker-containerd
):containerd
是1.11.x
引入的组件,是OCI
规范的标准实现。功能大致包括
- 镜像管理
- 容器管理(实际上利用
RunC
) - 存储管理
- 网络管理
- 命名空间管理
- …
RunC(/usr/bin/docker-runc
):与其他组件不同,RunC
是个可执行程序(提供创建和运行容器的cli工具),而并非一个常驻进程。它的主要职责就是运行容器。RunC
直接与容器所依赖的cgroup/namespace
等进行交互,负责为容器配置cgroup/namespace
等启动容器所需的环境,创建启动容器的相关进程
containerd-ctr(/usr/bin/docker-containerd-ctr
):可以直接与containerd
交互的客户端,类似于docker-cli
和dockerd
之间的关系
containerd-shim(/usr/bin/docker-containerd-shim
):containerd
并不直接操作容器,而是通过containerd-shim
来间接地操作容器或与容器通信。从进程关系上讲,containerd-shim
进程由containerd
进程拉起,容器进程由containerd-shim
进程拉起(每个容器进程都会对应一个独立的containerd-shim
进程)。containerd-shim
主要起到以下作用:
- 由于
containerd-shim
与容器是父子进程关系,因此可以拿到容器的stdout
、stderr
,可以将容器的stdin
、stdout
转存到日志文件中(/var/lib/docker/containers/<容器id>/<容器id>-json.log
)。与此对应的功能是docker logs <container>
或kubectl logs <pod> -c <container>
- 由于
containerd-shim
与容器是父子进程关系,因此可以拿到容器的stdin
、stdout
、stderr
,通过socket将容器的stdin
、stdout
、stderr
暴露给外界,以提供流式传输的功能。与此对应的功能是docker exec -it <container>
或kubectl exec -it <pod>
- 用于追踪容器的
exit code
。在detached
模式下,RunC
在启动完容器后便退出了,此时容器进程的父子进程关系将会调整。如果没有containerd-shim
,那么容器的父进程将会变成containerd
,如果containerd
重启了或意外退出了,那么容器的父进程又会进一步变成pid = 1
的进程,于是容器的状态信息将会全部丢失;引入containerd-shim
后,容器的父进程就变成了containerd-shim
,而containerd-shim
会等待容器运行直至退出,从而能够捕获到容器的exit code
1.3 OCI
以下是维基百科对于OCI
的定义:
The Open Container Initiative (OCI) is a Linux Foundation project to design open standards for operating-system-level virtualization, most importantly Linux containers. There are currently two specifications in development and in use: Runtime Specification (runtime-spec) and the Image Specification (image-spec).
OCI develops runc, a container runtime that implements their specification and serves as a basis for other higher-level tools. runC was first released in July 2015 as version 0.0.1
翻译过来就是:
OCI
是Linux基础项目,旨在为操作系统层级的虚拟化技术(最主要的就是Linux容器)设计开放标准。当前有两个规范正在开发和使用中:运行时规范(runtime-spec
)和映像规范(image-spec
)
OCI
开发了Runc
,它一个容器运行时,该运行时实现了OCI
规范,并作为其他高级工具的基础。Runc
于2015年7月首次发布,版本为0.0.1。
2 CRI
CRI
在Kubernetes 1.5
中引入,在此之前,Kubernetes
与docker
强耦合(在代码中直接硬编码调用docker-api
)。虽然docker
是容器领域中最受瞩目的项目,但它并不是容器领域中的唯一选择,不同的容器实现方案都有其各自的优势,Kubernetes
为了在容器运行时的选择上更具灵活性,因此需要与docker
进行解耦,而软件如何解耦?那就加一层接口咯,这层接口就叫做CRI
。如此一来,docker
就是满足CRI
的一个实现,只要各个容器方案都实现了CRI
接口,Kubernetes
就能完成容器运行时的自由切换
整体架构大致如下(图中仅包含部分CRI实现,以及部分OCI实现)
其中
cri-o
是由Kubernetes
孵化的项目,天然支持CRI
cri-containerd
是为了在不改造containerd
的前提下,让containerd
支持CRI
规范docker-shim
是为了在不改造docker
的前提下,让docker
支持CRI
规范
Kubernetes
对于CRI
的定义,可以参考kubernetes/cri-api,主要包含两部分RuntimeService
以及ImageService
1 | // Runtime service defines the public APIs for remote container runtimes |
3 参考
- Docker的历史与发展
- Kubernetes 容器运行时演进
- 如何为Kubernetes选择合适的容器运行时?
- 40 年回顾,一文读懂容器发展史
- Runtime 技术概览
- Dockershim Deprecation: Is Docker Truly out of Game?
- containerd-doc
- kubernetes-blog
- 揭秘开放容器标准(OCI)规范
- docker进程模型,架构分析
- Implementing Container Runtime Shim: runc
- Docker components explained
- OCI,CRI到kubernetes runtime
- About the Open Container Initiative
- OCI,CRI,CRI-O,Containerd 名词解释
- Introducing Container Runtime Interface (CRI) in Kubernetes
- 关于Kubernetes废弃内置docker CRI功能的说明
- K8s、CRI与container
- CRI: the Container Runtime Interface
- kubernetes/cri-api