【Docker深入浅出】Docker引擎架构介绍

文章目录

  • [一. docker引擎介绍](#一. docker引擎介绍)
    • [1. Docker daemon:实现Docker API,通过API管理容器](#1. Docker daemon:实现Docker API,通过API管理容器)
    • [2. containerd:负责容器的生命周期](#2. containerd:负责容器的生命周期)
    • [3. runc:用于创建和启动容器](#3. runc:用于创建和启动容器)
  • [二. 启动容器的过程](#二. 启动容器的过程)
    • [1. 启动过程](#1. 启动过程)
    • [2. docker daemon的维护不会影响到运行中的容器](#2. docker daemon的维护不会影响到运行中的容器)
    • [3. shim:让容器独立于docker daemon](#3. shim:让容器独立于docker daemon)

一. docker引擎介绍

docker基于OCI的开放标准,引擎采用模块化设计

  • OCI 规范定义了容器镜像的格式,使得不同的工具和平台能够创建、分享和运行容器镜像而不受限于特定的实现。兼容 OCI 镜像格式的系统可以使用标准化的镜像文件进行容器部署。
  • OCI 还定义了容器运行时的规范,确保容器能够在任何支持 OCI 运行时规范的环境中启动和运行。这使得容器的运行不依赖于特定的实现或平台。

Docker引擎的组成

Docker引擎由如下主要的组件构成:Docker客户端(Docker Client)​、Docker守护进程(Docker daemon)​、containerd以及runc。它们共同负责容器的创建和运行。如下图:

1. Docker daemon:实现Docker API,通过API管理容器

Docker daemon:

  • Docker daemon实现了Docker API,Docker API 是 Docker 提供的应用编程接口,允许开发者通过编程方式与 Docker 引擎进行交互。
  • Docker daemon中的功能包括但不限于API、镜像管理、身份认证、安全特性、核心网络以及卷。
  • daemon使用一种CRUD风格的API,通过gRPC与containerd进行通信。
shell 复制代码
Docker API 的作用包括:
1. 容器管理
创建和启动容器:通过 API,可以程序化地创建新的容器并启动它们。例如,
通过 POST /containers/create 和 POST /containers/(id or name)/start。
停止和删除容器:可以通过 POST /containers/(id or name)/stop 停止容器,
通过 DELETE /containers/(id or name) 删除容器。

2. 镜像管理
拉取和推送镜像:可以使用 API 拉取新的镜像(POST /images/create)或将镜像推送到 Docker 仓库(POST /images/(name)/push)。
列出和删除镜像:通过 GET /images/json 列出本地镜像,通过 DELETE /images/(name) 删除镜像。

3. 网络管理
创建和删除网络:可以通过 API 创建新的网络(POST /networks/create)或删除现有网络(DELETE /networks/(id))。
管理网络设置:可以查看网络配置和连接状态(GET /networks/(id))。

4. 卷管理
创建和删除卷:通过 API 可以创建新的数据卷(POST /volumes/create)或删除现有卷(DELETE /volumes/(name))。
查看卷信息:可以获取卷的详细信息(GET /volumes/(name))。

5. 日志和监控
获取容器日志:可以获取特定容器的日志输出(GET /containers/(id or name)/logs),帮助调试和监控容器运行状态。
查看容器状态:通过 GET /containers/(id or name)/json 获取容器的详细状态信息。

6. 系统信息
查看 Docker 版本:通过 GET /version 获取 Docker 引擎的版本信息。
获取系统统计信息:通过 GET /system/df 获取 Docker 使用的磁盘空间统计信息。

7. 安全性和权限
管理访问权限:API 可以用于设置和管理 Docker 引擎的访问权限,控制不同用户或应用的操作权限。


8. 自动化和集成
与 CI/CD 工具集成:Docker API 允许在持续集成和持续部署(CI/CD)流程中自动化容器的构建、测试和部署。
自定义管理工具:开发者可以使用 Docker API 创建自定义的管理界面或工具,以满足特定的业务需求。

使用场景

  1. 自动化管理:通过 API 可以编写脚本或程序自动化容器的创建、启动、停止等操作。
  2. 集成和扩展:将 Docker 功能集成到现有的应用程序或系统中,比如在云平台、监控工具或开发环境中。
  3. 自定义应用:构建自定义的用户界面或控制面板,提供更符合业务需求的容器管理功能。

2. containerd:负责容器的生命周期

containerd 是 Docker 的一个核心组件,主要用于容器的运行时管理。它负责以下几个方面:

  1. 容器生命周期管理:启动、停止、删除容器。
  2. 容器镜像管理:拉取、存储和管理容器镜像。
  3. 资源管理:管理容器的资源分配和限制。
  4. 日志管理:处理容器的日志输出。

3. runc:用于创建和启动容器

runc是OCI容器运行时规范的参考实现,它使用与OCI兼容的bundle(2?)来启动容器。runc生来只有一个作用------创建容器!

Docker使用runc作为其默认的容器运行时

  • containerd调用runc,并确保Docker镜像以OCI bundle的格式交给runc。
  • runc可以作为独立的CLI工具来创建容器。它基于Libcontainer(3?),也可被其他项目或第三方工具使用。

二. 启动容器的过程

下面的docker container run命令会基于alpine:latest镜像启动一个新容器。

python 复制代码
$ docker container run --name ctr1 -it alpine:latest sh

1. 启动过程

当使用Docker命令行工具执行如上命令时,

  1. Docker客户端会将其转换为合适的API格式,并发送到正确的API端点(3?)。
  2. 一旦daemon接收到创建新容器的命令,它就会向containerd发出调用。daemon已经不再包含任何创建容器的代码了。
  3. containerd指导runc启动容器:containerd不负责创建容器,而是指挥runc去做。containerd将Docker镜像转换为OCI bundle,并让runc基于此创建一个新的容器。
  4. runc与操作系统内核接口进行通信,基于所有必要的工具(Namespace、CGroup等)来创建容器。容器进程作为runc的子进程启动,启动完毕后,runc将会退出。

现在,容器启动完毕了。如下图容器启动过程:

2. docker daemon的维护不会影响到运行中的容器

为什么对于docker daemon的维护和升级不会影响到运行中的容器

因为Docker将所有的用于启动、管理容器的逻辑和代码从daemon中移除,意味着容器运行时与Docker daemon是解耦的,有时称之为"无守护进程的容器(daemonless container)​"​,所以,对Docker daemon的维护和升级工作不会影响到运行中的容器。

在旧模型中,所有容器运行时的逻辑都在daemon中实现,启动和停止daemon会导致宿主机上所有运行中的容器被杀掉。这在生产环境中是一个大问题------想一想新版Docker的发布频次吧!每次daemon的升级都会杀掉宿主机上所有的容器。

3. shim:让容器独立于docker daemon

上图展示了shim组件。shim是将运行中的容器与daemon解耦(,以便daemon进行升级等操作)不可或缺的工具。

containerd指挥runc来创建新容器。事实上,每次创建容器时它都会fork一个新的runc实例。不过,一旦容器创建完毕,对应的runc进程就会退出。因此,即使运行上百个容器,也无须保持上百个运行中的runc实例。

一旦runc退出,相关联的containerd-shim进程就会成为容器的父进程。作为容器的父进程,shim用于管理容器与容器运行时之间的通信。它主要承担以下功能:

  1. 保持所有STDIN和STDOUT是开启状态,从而当daemon重启的时候,容器不会因为管道(pipe)的关闭而终止;
  2. 容器进程管理:shim 负责启动和管理容器内的主进程,并确保容器进程在后台正确运行。
  3. 日志转发:将容器的标准输出和错误日志转发到 Docker 引擎或日志系统。
  4. 容器终止处理:处理容器的正常或异常退出,并将退出状态报告给 daemon。
  5. 生命周期管理:支持容器的启动、停止、重启等操作,确保容器生命周期的正常管理。

在 Docker 中,shim 的作用是让容器进程独立于 Docker 守护进程,使得容器可以更稳定地运行,同时也提供了更好的隔离和资源管理。

相关推荐
小的~~7 分钟前
k8s使用本地docker私服启动自制的flink集群
docker·flink·kubernetes
诚诚k35 分钟前
docker存储
运维·docker·容器
sorel_ferris37 分钟前
Ubuntu-24.04中Docker-Desktop无法启动
linux·ubuntu·docker
MinIO官方账号38 分钟前
从 HDFS 迁移到 MinIO 企业对象存储
人工智能·分布式·postgresql·架构·开源
数据智能老司机1 小时前
Kubernetes从入门到精通系列——外部 DNS 和全局负载均衡
云原生·容器·kubernetes
多多*1 小时前
OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发
linux·服务器·前端·ubuntu·docker·前端框架
hai405871 小时前
Spring Boot中的响应与分层解耦架构
spring boot·后端·架构
NiNg_1_2342 小时前
使用Docker Compose一键部署
运维·docker·容器
萠哥啥都行2 小时前
Linux安装Docker以及Docker入门操作
运维·docker·容器
王哲晓2 小时前
Linux通过yum安装Docker
java·linux·docker