docker进程模型分析

举报
Tony Zhang 发表于 2019/12/25 16:40:51 2019/12/25
【摘要】 前言当我们启动了一个docker容器后,使用ps命令查看,会发现启动了多个docker相关的进程,如下,初步看起来:dockerd是docker engine守护进程,dockerd启动时会启动containerd子进程,二者通过rpc进行通信;containerd通过shim操作runc,runc真正控制容器生命周期;每个容器启动时,就会启动一个shim进程;shim与containerd...

前言

当我们启动了一个docker容器后,使用ps命令查看,会发现启动了多个docker相关的进程,如下,

1577263080652469.png

初步看起来:

  • dockerd是docker engine守护进程,dockerd启动时会启动containerd子进程,二者通过rpc进行通信;

  • containerd通过shim操作runc,runc真正控制容器生命周期;

  • 每个容器启动时,就会启动一个shim进程;

  • shim与containerd之前通过rpc通信;

  • 应用对应的启动进程由runc的init进程启动;

  • proxy用来做端口映射,底层通过iptables实现;

下面逐一分析下这几个进程分别是干嘛的和相互之间的关系。

进程关系

直接上图。

1577263127805375.png

Docker Daemon

作为 Docker 容器管理的守护进程,Docker Daemon 从最初集成在docker命令中(1.11 版本前),到后来的独立成单独二进制程序(1.11 版本开始),其功能正在逐渐拆分细化,被分配到各个单独的模块中去。从 Docker 服务的启动脚本,也能看见守护进程的逐渐剥离:

在 Docker 1.8 之前,Docker 守护进程启动的命令为:

docker -d

这个阶段,守护进程看上去只是 Docker client 的一个选项。

Docker 1.8 开始,启动命令变成了:

docker daemon

这个阶段,守护进程看上去是docker命令的一个模块。

Docker 1.11 开始,守护进程启动命令变成了:

dockerd

此时已经和 Docker client 分离,独立成一个二进制程序了。

虽然守护进程模块一直在重构,但其基本功能和定位没有变化。和一般的 CS 架构系统一样,守护进程负责和 Docker client 交互,并管理 Docker 镜像、容器。

1577263153503388.png

Containerd

containerd 是容器技术标准化之后的产物,为了能够兼容 OCI 标准,将容器运行时及其管理功能从 Docker Daemon 剥离。

从其项目介绍页面可以看出,containerd 主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)。

1577263179152720.png

containerd 向上为 Docker Daemon 提供了 gRPC 接口,使得 Docker Daemon 屏蔽下面的结构变化,确保原有接口向下兼容。向下通过 containerd-shim 结合 runC,使得引擎可以独立升级,避免之前 Docker Daemon 升级会导致所有容器不可用的问题。

shim

作用如下:

  • 允许runc在创建&运行容器之后退出

  • 用shim作为容器的父进程,而不是直接用containerd作为容器的父进程,是为了防止这种情况:当containerd挂掉的时候,shim还在,因此可以保证容器打开的文件描述符不会被关掉

  • 依靠shim来收集&报告容器的退出状态,这样就不需要containerd来wait子进程

归纳起来,就是将containerd和容器进程解耦。

runc

OCI 定义了容器运行时标准,runC 是 Docker 按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。

runC 是从 Docker 的 libcontainer 中迁移而来的,实现了容器启停、资源隔离等功能。Docker 默认提供了 docker-runc 实现,事实上,通过 containerd 的封装,可以在 Docker Daemon 启动的时候指定 runc 的实现。

我们可以通过启动 Docker Daemon 时增加--add-runtime参数来选择其他的 runC 现。例如:

docker daemon --add-runtime "custom=/usr/local/bin/my-runc-replacement"

总结

从 Docker 1.11 之后,Docker Daemon 被分成了多个模块以适应 OCI 标准。拆分之后,结构分成了以下几个部分。

1577263190860416.png

其中,containerd 独立负责容器运行时和生命周期(如创建、启动、停止、中止、信号处理、删除等),其他一些如镜像构建、卷管理、日志等由 Docker Daemon 的其他模块处理。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。