基于本文回答

播面 播面

文解图解播客视频,多维讲透八股文
0
评论

什么是容器运行时(Container Runtime)?请列举几种常见的运行时(如 runc, containerd)。

在 Docker 和 Kubernetes 的世界中,容器运行时(Container Runtime) 是最核心 competent(组件)之一。

简单来说,容器运行时就是负责“运行容器”的软件。它负责从镜像仓库拉取镜像、管理容器的生命周期(创建、启动、停止、删除)、管理网络和存储,以及将容器与宿主机的操作系统内核进行隔离。

为了更好地理解,我们可以把容器镜像(Image)比作“设计图纸”,而容器运行时(Container Runtime)就是“施工队”,负责把图纸变成真正可以住人的“房子(运行中的容器)”


1. 容器运行时的分类:高低之分

容器运行时并不是单一的软件,为了实现解耦和标准化(遵循 OCI - 开放容器标准),容器运行时被分为了两层:

① 低级运行时(Low-level Runtime)—— 真正干活的

  • 职责:只负责最底层的工作。利用 Linux 内核特性(Namespace 和 Cgroups)来创建和运行容器。它不负责下载镜像,也不负责管理网络。
  • 特点:生命周期极短,容器启动后,它通常就退出了。
  • 代表runc

② 高级运行时(High-level Runtime / Container Engine)—— 负责管理的

  • 职责:负责更上层的管理工作。包括从仓库拉取镜像、解析镜像、管理容器网络、管理存储卷,然后调用低级运行时去真正启动容器。
  • 特点:作为一个守护进程(Daemon)持续在后台运行。
  • 代表containerdCRI-O

2. 常见的容器运行时

以下是目前业界最主流的几种容器运行时:

1) runc(最经典的低级运行时)

  • 介绍runc 是根据 OCI(Open Container Initiative)规范编写的参考实现。它最初由 Docker 公司开发,后来捐赠给了 Linux 基金会。
  • 角色:低级运行时。
  • 工作原理:它直接与 Linux 内核交互,通过 clone() 系统调用创建命名空间(Namespace)实现隔离,通过 Cgroups 限制资源。
  • 地位:它是目前绝大多数容器技术的基石,无论是 Docker 还是 Kubernetes,底层默认都是用 runc 来启动容器的。

2) containerd(工业级标准的高级运行时)

  • 介绍containerd 最初是 Docker 引擎的一部分,后来被剥离出来作为一个独立的开源项目,并捐赠给了 CNCF(云原生计算基金会),目前是毕业项目。
  • 角色:高级运行时。
  • 功能:它管理着容器的完整生命周期,包括镜像传输与存储、容器执行与监督、低层存储与网络附件等。它在后台运行,当需要启动容器时,它会调用 runc
  • 地位
    • 在 Docker 中:Docker 社区版(Docker CE)的核心就是 containerd
    • 在 Kubernetes 中:由于 K8s 在 v1.24 彻底移除了对 Docker 的直接支持(Dockershim),containerd 成为了目前 Kubernetes 最主流的默认容器运行时。

3) CRI-O(专为 Kubernetes 诞生的运行时)

  • 介绍:由 Red Hat、Intel、SUSE 等公司联合开发的轻量级容器运行时。
  • 角色:高级运行时。
  • 特点:它是专门为了满足 Kubernetes 的 CRI(容器运行时接口)而设计的。它不包含任何 Kubernetes 不需要的功能(而 containerd 还要兼顾 Docker 的需求),因此非常轻量、安全和专注。
  • 地位:在红帽的 OpenShift 和一些追求极简的 K8s 集群中应用广泛。

4) Kata Containers / gVisor(安全/沙箱运行时)

  • 介绍:传统的 runc 容器共享宿主机内核,如果发生“容器逃逸”,宿主机就会面临安全威胁。因此诞生了安全运行时。
  • 代表
    • Kata Containers:结合了虚拟机(VM)的安全性和容器的轻量性。每个容器运行在一个独立的轻量级微型虚拟机(MicroVM)中,拥有独立的内核。
    • gVisor(Google 开发):在用户空间实现了一个“虚拟内核”,拦截容器的系统调用,防止容器直接接触宿主机内核。
  • 应用场景:多租户云平台、运行不信任的代码。

3. 总结:在 Docker 中它们是如何协同工作的?

当你运行命令 docker run -d nginx 时,幕后发生的过程如下:

  1. Docker CLI(命令行工具)将你的请求发送给 Docker Daemon(Docker 守护进程)。
  2. Docker Daemon 无法直接启动容器,它将请求传递给高级运行时 containerd
  3. containerd 发现本地没有镜像,就去 Docker Hub 下载 Nginx 镜像并保存。
  4. containerd 创建一个名为 containerd-shim 的小进程,由它调用低级运行时 runc
  5. runc 拿着镜像,向 Linux 内核申请 Namespace 和 Cgroups,创建并启动 Nginx 容器。
  6. 容器启动成功后,runc 退出,而 containerd-shim 留在后台,负责收集容器日志和状态,并汇报给 containerd