本文超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否仍然正确。
rktnetes 将 rkt 容器引擎引入 Kubernetes
编者注:这篇文章是关于 Kubernetes 1.3 新功能的系列深度文章的一部分。
作为 Kubernetes 1.3 的一部分,我们很高兴地宣布,我们为 Kubernetes 引入可互换容器引擎的工作已初见成效。我们亲切地称之为“rktnetes”的功能已包含在 Kubernetes 1.3 版本中,并已准备好用于开发。rktnetes 将对 CoreOS rkt 的支持集成到 Kubernetes 中,作为集群节点上的容器运行时,现在是 Kubernetes 主线源代码的一部分。如今,对于注重容器可移植性的开发人员和运维专家来说,尝试使用不同的容器引擎运行 Kubernetes 比以往任何时候都更容易。
“我们发现 CoreOS 的 rkt 是 Kubernetes 中一个引人注目的容器引擎,因为它与底层 systemd 的组合方式,”PayPal 服务 Xoom 的高级 MTS 和架构师 Mark Petrovic 说。“rkt 运行时只承担它需要的责任,然后在适当时委托给其他系统服务。这种关注点分离对我们很重要。”
什么是 rktnetes?
rktnetes 是使 Kubernetes 节点能够使用 rkt 容器引擎(而不是 Docker)执行应用程序容器的代码的昵称。这一变化为 Kubernetes 添加了新的功能,例如在灵活的隔离级别下运行容器。rkt 探索了一种替代容器运行时架构的方法,旨在体现 Unix 哲学中清晰分离的模块化工具。支持 rktnetes 所做的工作也为 Kubernetes 开辟了未来的可能性,例如多容器镜像格式支持,以及集成针对特定用例或平台定制的其他容器运行时。
为什么 Kubernetes 需要 rktnetes?
rktnetes 不仅仅是关于 rkt。它还涉及改进和运用 Kubernetes 接口,并为未来其他模块化运行时铺平道路。虽然 Docker 容器引擎广为人知,并且目前是默认的 Kubernetes 容器运行时,但可插拔容器环境带来了许多好处。例如,某些集群可能需要非常特定的容器引擎实现,并且确保 Kubernetes 设计足够灵活以支持替代运行时(从 rkt 开始)有助于保持组件之间的接口简洁明了。
关注点分离:分解单体容器守护进程
Kubernetes 当前使用的容器运行时强加了许多设计决策。在这个快速发展的领域中,尝试其他容器执行架构是值得的。如今,当 Kubernetes 向节点发送运行 pod 的请求时,它会通过每个节点上的 kubelet 与默认容器运行时的中央守护进程进行通信,该守护进程负责管理节点的所有容器。
rkt 没有实现单体容器管理守护进程。(值得注意的是,默认容器运行时正在重构其原始的单体架构。)rkt 设计从一开始就尝试将模块化原则应用到极致,包括重用经过良好测试的系统组件,而不是重新实现它们。
构建容器镜像的任务在 rkt 中从容器运行时核心抽象出来,并由一个独立的实用程序实现。正在进行的容器生命周期管理也采用了相同的方法。单个二进制文件 rkt 配置环境并准备要执行的容器镜像,然后设置容器应用程序及其隔离环境运行。此时,rkt 程序已经完成了它的“一项工作”,容器隔离器接管了。
Kubernetes 用于跟踪每个节点上的集群工作的容器引擎和 pod 状态查询 API 在一个单独的服务中实现,将协调和编排功能与核心容器运行时隔离开来。虽然 API 服务没有完全实现当前默认容器引擎的所有 API 功能,但它已经帮助将容器与核心运行时中的故障和升级隔离开来,并提供用于查询容器元数据的预期 API 的只读部分。
模块化容器隔离级别
通过 rkt 管理容器执行,Kubernetes 可以利用 CoreOS 容器引擎的模块化 *stage1* 隔离机制。典型的容器在 rkt 下运行,该环境由 Linux 内核命名空间、cgroup 和其他工具构建的软件隔离环境中运行。然而,以这种常见方式隔离的容器与系统上的所有其他容器共享一个内核,从而实现了运行应用程序的轻量级隔离。
但是,rkt 具有可插拔的隔离环境(称为 stage1),可以更改容器的执行和隔离方式。例如,rkt fly stage1 在主机命名空间(PID、挂载、网络等)中运行容器,从而授予容器更大的主机系统权限。Fly 用于容器化较低级别的系统和网络软件,例如 kubelet 本身。在隔离范围的另一端,KVM stage1 将标准应用程序容器作为单独的虚拟机运行,每个虚拟机都在其自己的 Linux 内核之上,由 KVM 管理程序管理。此隔离级别可用于高安全性和多租户集群工作负载。
目前,rktnetes 可以通过设置 kubelet 的 --rkt-stage1-image 选项来使用 KVM stage1 以 VM 隔离方式执行节点上的所有容器。目前正在进行实验性工作,可以通过 Kubernetes 注释声明 pod 的适当 stage1 来选择每个 pod 的 stage1 隔离机制。KVM 容器和标准 Linux 容器可以在同一个集群中混合使用。
rkt 如何与 Kubernetes 配合使用
Kubernetes 如今通过 Docker 守护进程提供的 API 与默认容器引擎进行通信。rktnetes 与 rkt 的通信方式略有不同。首先,Kubernetes 如何更改节点容器的状态(如何启动和停止 pod 或重新安排它们以进行故障转移或扩展)与协调器如何查询 pod 元数据以进行常规只读簿记之间存在区别。两种不同的设施实现了这两种不同的情况。
管理微服务生命周期
每个集群节点上的 kubelet 与 rkt 通信以准备容器及其环境到 pod 中,并与 systemd(linux 服务管理框架)通信以调用和管理 pod 进程。然后将 Pod 作为 systemd 服务进行管理,kubelet 通过 dbus 发送 systemd 命令来操作它们。生命周期管理,例如重新启动失败的 pod 和终止已完成的进程,由 systemd 在 kubelet 的指示下处理。
用于读取 pod 数据的 API 服务
一个离散的 rkt api-service 实现了 Kubernetes 预期的 pod 自省机制。虽然每个节点的 kubelet 使用 systemd 来启动、停止和重新启动 pod 作为服务,但它会联系 API 服务来读取容器运行时元数据。这包括基本的编排信息,例如节点上运行的 pod 数量、这些 pod 的名称和网络,以及 pod 配置、资源限制和存储卷的详细信息(想想 kubectl describe 子命令显示的信息)。
pod 日志已被写入日志文件,API 服务也使 kubectl logs 和其他取证子命令可以使用这些日志,API 服务从日志文件读取内容,为 kubelet 提供 pod 日志数据以响应控制平面请求。
这种与容器环境的双接口是一个非常活跃的开发领域,计划是扩展 API 服务以提供 pod 操作命令的方法。底层机制将继续牢记关注点分离,但会对 kubelet 隐藏更多这方面的内容。随着时间的推移,kubelet 用于控制 rktnetes 容器引擎的方法与默认容器运行时接口的差异将越来越小。
试用 rktnetes
那么你今天可以用 rktnetes 做什么呢?目前,rktnetes 通过了所有适用的 Kubernetes“端到端”(又名“e2e”)测试,向 cAdvisor 提供标准指标,使用 CNI 管理网络,处理每个容器/pod 的日志,并自动对旧容器和镜像进行垃圾回收。在 rkt 上运行的 Kubernetes 已经为 Kubernetes 集群提供了一个模块化、灵活的容器运行时的基础,它已经是 CoreOS 开发环境中的一个功能部分。
开发人员和早期采用者可以关注rktnetes 说明中的已知问题,以了解测试驱动程序可能会遇到的问题。此列表将 rktnetes 与现有容器运行时和 API 达到功能对等所需的高级组件分组。我们希望您也能在 Kubernetes 集群中试用 rktnetes。
立即将 rkt 与 Kubernetes 结合使用
入门指南 *在 rkt 上运行 Kubernetes* 逐步介绍了启动 rktnetes 集群的步骤,从 kubelet --container-runtime=rkt 到联网和启动 pod。本介绍还概述了您使用 Kubernetes kube-up.sh 脚本在 GCE 上启动集群所需的配置。
最近的工作也旨在使 rktnetes 集群创建更容易。虽然尚未合并,但正在进行的拉取请求创建了一个 rktnetes 配置切换,以便在使用 coreos-kubernetes 配置工具部署 Kubernetes 集群时选择 rkt 作为容器引擎。您还可以查看 rktnetes 研讨会项目,该项目只需一个 vagrant up 命令即可在几乎任何开发人员工作站上启动单节点 rktnetes 集群。
我们很高兴看到更广泛的 Kubernetes 和 CoreOS 社区设计的实验,以测试 rktnetes,我们欢迎您的意见——以及拉取请求!