[Kubernetes] 容器运行时 Container Runtime

作者 : admin 本文共4257个字,预计阅读时间需要11分钟 发布时间: 2024-06-10 共2人阅读

文章目录

      • 1.容器运行时(Container Runtime)
      • 2.容器运行时接口
      • 3.容器运行时层级
      • 4.容器运行时比较
      • 5.强隔离容器
      • 6.K8S为何难以实现真正的多租户

1.容器运行时(Container Runtime)

Container Runtime 是运行于 k8s 集群每个节点中,负责容器的整个生命周期。Docker 就目前来说是应用最为广泛的。随着容器云的发展,涌现了很多容器运行时。Google 为了将 kubelet 和特定的容器运行时解耦(主要还是为了干掉 Docker),于是推出了 CRI(容器运行时接口) 。

2.容器运行时接口

CRI 是 k8s 定义的一组 gRPC 服务。kubelet 作为客户端,基于 gRPC 框架,通过 Socket 和容器运行时通信。CRI 包括两类服务:镜像服务(Image Service)和运行时服务(Runtime Service)。镜像服务提供下载、检查和删除镜像的远程程序调用。运行时服务用于管理容器的生命周期,以及和容器交互的调用(exec / attach / port-forward)。

[Kubernetes] 容器运行时 Container Runtime插图

3.容器运行时层级

Container Runtime 分为高低两个层级。

  1. 高层级运行时

    • Dockershim、containerd 和 CRI-O 都是遵循 CRI 的容器运行时,属于高层级运行时,主要是面向外部提供 gRPC 调用。
    • 注意这里是 Dockershim,并不是 Docker,Docker 至今也没有遵循 CRI。
    • OCI(OPen Container Initiative)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范和运行时规范。
    • 高层级运行时会下载一个 OCI 镜像,并把它解压成 OCI 运行时文件系统包(filesystem bundle)。
    • 高层运行时主要负责镜像的管理、转换等工作, 为容器的运行做准备,主流的高层运行时主要有containerd和CRI-O。
    • 高层运行时与底层运行时各司其职, 容器运行时一般先由高层运行时将镜像下载下来, 并解压为容器运行时需要的操作系统文件, 再由底层运行时启动和管理容器。
  2. 低层级运行时

    • 低层级运行时定义如何为新容器设置 Linux namespaces 和 cgroups,以及 rootfs 等操作, runC 就是具体的参考实现。除了 runC 外,还有很多其他的运行时遵循 OCI 标准,例如 kata 以及 gVisor。
    • 底层运行时主要负责与宿主机操作系统打交道, 根据指定的容器镜像在宿主上运行容器的进程, 并对容器的整个生命周期进行管理。而这个底层运行时, 正是负责执行前面讲解的设置容器Namespace, Cgroups 等基础操作的组件, 常见的底层运行时有:
      • runc: 传统的运行时, 基于Namespace和Cgroup技术实现, 代表实现为Docker
      • runv: 基于虚拟机管理程序的运行时, 通过虚拟化 guest kernel, 将容器和主机隔离开, 使得其边界更加清晰, 代表为kata container和Firecracker。
      • runsc: runc + safety, 通过拦截应用程序的所有系统调用, 提供安全隔离的轻量级容器运行时沙箱, 代表为gVisor
  3. docker和containerd区别

    • 主要区别在于Docker是一个完整的容器平台,而Containerd是一个轻量级的容器运行时。
      • Docker 是一个开源的容器平台,提供了一整套容器解决方案,包括构建、打包、分发和运行容器。它包括Docker Engine、Docker Swarm、Docker Compose等多个组件,提供了镜像构建、容器编排等高级功能,适合需要复杂容器管理功能的用户。Docker不仅是一个容器引擎,还包括了网络、存储等组件,其API和CLI(命令行接口)更加丰富,可以方便地进行容器创建、停止、启动、删除等操作,具有更高的安全和稳定性。
      • Containerd 是一个轻量级的容器运行时,专注于底层的容器生命周期管理,如容器的创建、启动、停止和销毁。它比Docker更轻量级,可以快速启动和运行容器,并且具有更好的性能和可扩展性。Containerd的设计更加简单和稳定,提供了API,可以与其他容器编排工具集成使用,使其更加灵活和可扩展。Containerd的API和CLI相对比较简单,更加注重容器的生命周期管理和基本的镜像操作。
    • 在Kubernetes(K8s)中,使用Docker和Containerd作为容器运行时在调用上存在一些区别。Containerd不需要经过dockershim,所以调用链更短,组件更少,更稳定,占用节点资源更少。而Docker需要经过更长的调用链。此外,Docker调用CNI(容器网络接口)是通过“docker-shim”,而Containerd调用CNI是通过“containerd-cri”。
    • 总的来说,Docker和Containerd的区别主要体现在功能丰富度、系统资源占用、以及与Kubernetes等工具的集成能力上。Docker提供了更全面的容器管理功能,适合需要复杂容器管理功能的用户;而Containerd则更适合追求轻量级、高性能和灵活性的用户。

高层级运行时(Dockershim、containerd 和 CRI-O ),主要是面向外部提供 gRPC 调用。
低层级运行时(runC、kata和gVisor ),定义如何为新容器设置 Linux namespaces 和 cgroups,以及 rootfs 等操作。

4.容器运行时比较

[Kubernetes] 容器运行时 Container Runtime插图(1)

  1. containerd + runc
  2. containerd + kata containers
  3. cri + runc

Docker 的多层封装和调用,导致其在可维护性上略逊一筹。containerd 和 CRI-O 的方案比 Docker 简洁很多。

[Kubernetes] 容器运行时 Container Runtime插图(2)

dockershim 遵循 CRI,并把请求转为 dockerd 可处理的请求,其代码集成在 kubelet 中,这也是 k8s 急于摆脱 Docker 的原因之一。

真正的启动容器是通过 containerd-shim 去调用 runC 来启动容器的,runC 启动完成后会直接退出,containerd-shim 会成为容器进程的父进程,负责收集容器进程的状态,上报给 containerd,并在容器中 pid 为 1 的进程退出后接管容器中的子进程,确保不会出现僵尸进程。同时也避免了宿主机上 containerd 进程挂掉的话,所有容器进程都退出。

  1. containerd 和 Docker 细节差异
    [Kubernetes] 容器运行时 Container Runtime插图(3)
    Docker 作为容器运行时,k8s 其实根本没有使用 docker 本身的存储、网络等功能,只是用了 Docker 的 Image 功能,来满足 CRI 中的镜像服务。

  2. containerd 和 CRI-O
    CRI-O是由红帽发起并开源的一款容器运行时,本身比较新,没有太多的生产实践。而且在社区的测试结果中,在操作容器方面的性能以及延时都没有 containerd 优秀。

5.强隔离容器

(1)常用强隔离容器

Kata, gVisor, firecracker

(2)安全容器与 Serverless

Serverless 要做到所有的用户容器或函数按需使用计算资源, 那必须满足两点:

  1. 多租户强隔离: 用户的容器或函数都是按需启动按秒计费, 我们可不能给每个用户预先分配一坨隔离的资源,因此我们要保证整个 Platform 是多租户强隔离的;
  2. 极度轻量: Serverless 的第一个特点是运行时沙箱会更频繁地创建和销毁, 第二个特点是切分的粒度会非常非常细, 细中细就是 FaaS, 一个函数就要一个沙箱。 因此就要求两点: 1. 沙箱启动删除必须飞快; 2. 沙箱占用的资源越少越好。

(3)Kata Containers

① 概念

Kata Containers作为OpenStack基金会的一个开放源代码项目,作为其最近扩展的包含OpenStack核心项目的章程的一部分。这个项目肯定会促进标准化和创新,从而推动容器技术的快速发展。已经有将近20家公司同意在Kata Containers上共同合作。

Kata容器也将在多个基础架构和容器编排和规范社区中集成和兼容:Kubernetes,Docker,Open Container Initiative(OCI),Container Runtime Interface(CRI),容器网络接口(CNI),QEMU,KVM,HyperV和OpenStack。

② 特点

容器的速度,虚拟机的安全。

Kata 的一张图很好地解释了基于虚拟机的容器与基于 namespaces 和 cgroups 的容器间的区别:

[Kubernetes] 容器运行时 Container Runtime插图(4)

Kata Containers是一种轻量级虚拟机的新颖实现无缝集成在容器生态系统中。Kata Containers同容器一样轻而快,并与容器结合管理层,同时也提供了虚拟机的安全优势。

Kata Containers是两个现有的开源项目合并:英特尔Clear Containers和Hyper runV。新项目汇集了最好的这两种技术都具有重构虚拟化,容器原生应用程序的共同愿景,为了提供容器的速度,和虚拟机的安全。

[Kubernetes] 容器运行时 Container Runtime插图(5)

Kata Containers从每个项目的优势中受益。Intel Clear Containers专注于性能(<100ms启动时间)和增强安全性,而hyper runV优先于技术无关支持许多不同的CPU架构和管理程序。通过合并这些项目,Clear Containers提供了卓越的最终用户体验性能和兼容性,统一开发者社区,并加速功能开发以解决未来的使用案例。

行业转向容器在安全方面提出了独特的挑战,用户工作负载在多租户不受信任的环境中。Kata Containers使用开源虚拟机管理程序作为每个容器的隔离边界(或一个容器中的容器的集合);这种方法解决了与现有的裸机容器解决方案共同的内核困境。

Kata Containers是非常适合按需,基于事件的部署,如无服务器功能,连续整合/持续交付,以及更长时间运行的Web服务器应用。开发者不再需要知道任何事情下面的基础或执行任何类型的容量规划之前启动他们的容器工作量。Kata Containers交付增强安全性,可扩展性和更高的资源利用率,同时导致整体简化的堆栈。

6.K8S为何难以实现真正的多租户

  1. kube-apiserver 是整个集群中的单例, 并且没有多租户概念;

  2. 默认的 oci-runtime 是 runC, 而 runC 启动的容器是共享内核的。

一个典型的解决方案就是提供一个新的 OCI 实现, 用 VM 来跑容器, 实现内核上的硬隔离。 runV 和 Clear Containers 都是这个思路. 因为这两个项目做得事情是很类似, 后来就合并成了一个项目 Kata Container。

本站无任何商业行为
个人在线分享 » [Kubernetes] 容器运行时 Container Runtime
E-->