Kubernetes 的工作原理

已完成

要成功配置 Kubernetes 安装,需要充分了解 Kubernetes 系统体系结构。 本文介绍构成 Kubernetes 安装的所有组件。

什么是计算机群集?

群集是一组计算机,可配置为协同工作并视为单个系统。 群集中配置的计算机会处理相同类型的任务。 例如,它们会托管网站、API 或运行计算密集型工作。

群集使用负责计划和控制这些任务的集中式软件。 群集中运行任务的计算机称为“节点”,运行计划软件的计算机称为“控制平面”。

Diagram of a computer cluster that shows how a task is distributed via the control plane to three nodes and the interaction between the nodes.

Kubernetes 体系结构

回想一下之前的内容,业务流程协调程序是用于部署和管理应用的系统。 你还了解到群集是一组协同工作的计算机,并被视为单个系统。 使用 Kubernetes 作为业务流程和群集软件来部署应用,以及响应计算资源需求的变化。

Diagram of a Kubernetes cluster architecture that shows the components installed on the control plane and the worker nodes.

Kubernetes 群集至少包含一个主平面以及一个或多个节点。 控制平面和节点实例都可以是物理设备、虚拟机或云中的实例。 Kubernetes 中的默认主机 OS 是 Linux,默认情况下支持基于 Linux 的工作负载。

也可以通过在群集节点上使用 Windows Server 2019 或更高版本运行 Microsoft 工作负载。 例如,假设无人机跟踪应用中的数据处理服务编写为使用特定 Windows OS API 调用的 .NET 4.5 应用。 此服务只能在运行 Windows Server OS 的节点上运行。

现在,请更详细地了解一下控制平面和工作器节点以及在它们上面运行的软件。 了解每个组件的作用以及每个组件在群集中的运行位置,可以在安装 Kubernetes 时有所助益。

Kubernetes 控制平面

Kubernetes 群集中的 Kubernetes 控制平面运行一个服务集合,该集合管理 Kubernetes 中的业务流程功能。

从学习的角度来看,在浏览 Kubernetes 功能时,应该在测试环境中使用单个控制平面。 但是,在生产部署和云部署(如 Azure Kubernetes 服务 (AKS))中,你会发现首选配置是具有三到五个复制控制平面的高可用性部署。

注意

控制平面运行特定软件来维护群集状态,但它同时也会运行其他计算工作负载。 但是,你通常需要避免让控制平面运行非关键的用户应用工作负载。

Kubernetes 节点

Kubernetes 群集中的节点是计算工作负载运行的位置。 每个节点都通过 API 服务器与控制平面通信,以通知它节点上的状态改变。

在控制平面上运行的服务

Kubernetes 依赖于在控制平面上运行的若干管理服务。 这些服务管理群集组件通信、工作负载计划以及群集状态持久化等方面。

Diagram of a Kubernetes cluster architecture that shows the components installed on the control plane.

以下服务构成了 Kubernetes 群集的控制平面:

  • API 服务器
  • 后备存储
  • 计划程序
  • 控制器管理器
  • 云控制器管理器

什么是 API 服务器?

你可以将 API 服务器视为 Kubernetes 群集控制平面的前端。 Kubernetes 中的组件之间的所有通信都是通过此 API 完成的。

例如,用户可以使用名为 kubectl 的命令行应用针对 Kubernetes 群集的 API 服务器运行命令。 提供此 API 的组件称为 kube-apiserver,你可以部署此组件的多个实例,以支持在群集中进行缩放。

此 API 公开一个 RESTful API,通过该 API 可以发布命令或基于 YAML 的配置文件。 YAML 是编程语言的可读数据序列化标准。 使用 YAML 文件可定义 Kubernetes 群集中所有对象的预期状态。

例如,假设要增加群集中应用的实例数。 你将使用基于 YAML 的文件定义新状态,并将此文件提交到 API 服务器。 API 服务器会验证配置,将其保存到群集,最后在应用部署中增加配置。

什么是后备存储?

后备存储是一个持久性存储,Kubernetes 群集在其中保存它的完整配置。 Kubernetes 使用名为 etcd 的可靠的高可用性分布式键值存储。 此键值存储存储当前状态以及群集中所有对象的所需状态。

在生产 Kubernetes 群集中,Kubernetes 的官方指导意见是安排三到五个 etcd 数据库的复制实例,以实现高可用性。

注意

etcd 不负责数据备份。 你要负责确保有一个有效的备份计划来备份 etcd 数据。

什么是计划程序?

计划程序是负责在所有节点间分配工作负载的组件。 计划程序监视群集中是否有新创建的容器,并将其分配给节点。

什么是控制器管理器?

控制器管理器通过 API 服务器启动和监视为群集配置的控制器。

Kubernetes 会利用控制器来跟踪群集中对象的状态。 在监视和响应群集中的事件时,每个控制器都在非终止循环中运行。 例如,有一些控制器用于监视节点、容器和终结点。

控制器可与 API 服务器通信,以确定对象的状态。 如果对象的当前状态与所需状态不一致,则控制器会采取措施来确保所需状态。

假设群集中运行的三个容器中的一个停止响应,最终失败。 在这种情况下,控制器决定是否需要启动新容器来确保应用始终可用。 如果所需状态是在任何时间都运行三个容器,则会安排运行一个新的容器。

什么是云控制器管理器?

群集在云环境中运行时,云控制器管理器会与群集中的基础云技术集成。 例如,这些服务可以是负载均衡器、队列和存储。

在节点上运行的服务

有几个在 Kubernetes 节点上运行的服务,用于控制工作负载的运行方式。

Diagram of a Kubernetes cluster architecture that shows the components installed on a Kubernetes node.

以下服务在 Kubernetes 节点上运行:

  • kubelet
  • kube-proxy
  • 容器运行时

什么是 kubelet?

kubelet 是一个代理,在群集的每个节点上运行,并监视 API 服务器的工作请求。 它确保请求的工作单元正在运行并一切正常。

kubelet 监视节点,并确保每个节点上安排的容器按预期运行。 kubelet 仅管理 Kubernetes 创建的容器。 在当前节点无法运行工作时,它不负责将工作重新安排到其他节点上运行。

什么是 kube-proxy?

kube-proxy 组件负责本地群集网络,并在每个节点上运行。 它确保每个节点都具有唯一的 IP 地址。 它还实行使用 iptables 和 IPVS 处理流量的路由和负载平衡的规则。

此代理本身不提供 DNS 服务。 建议使用基于 CoreDNS 的 DNS 群集加载项(默认安装)。

什么是容器运行时?

容器运行时是在 Kubernetes 群集上运行容器的基础软件。 运行时负责提取、启动和停止容器映像。 Kubernetes 支持多种容器运行时,包括但不限于 Docker、containerd、rkt、CRI-O 和 frakti。 对多种容器运行时类型的支持都是基于容器运行时接口 (CRI) 实现的。 CRI 是一种插件设计,允许 kubelet 与可用容器运行时通信。

AKS 中的默认容器运行时是 containerd,这是一个行业标准容器运行时。

与 Kubernetes 群集交互

Kubernetes 提供了一个名为 kubectl 的命令行工具,可用于管理群集。 使用 kubectl 将命令发送到群集的控制平面,或通过 API 服务器获取有关所有 Kubernetes 对象的信息。

kubectl 使用包含以下配置信息的配置文件:

  • “群集”配置可指定群集名称、证书信息以及与群集关联的服务 API 终结点。 通过此定义,可以从单个工作站连接到多个群集。
  • “用户”配置可在用户访问配置的群集时指定用户及其权限级别。
  • “上下文”配置可使用易记名称对群集和用户进行分组。 例如,可以使用“dev-cluster”和“prod-cluster”来标识自己的开发群集和生产群集。

可以通过在命令行语法中提供正确的上下文,将 kubectl 配置为连接到多个群集。

Kubernetes pod

Pod 表示在 Kubernetes 中运行的应用的单个实例。 在 Kubernetes 上运行的工作负载是容器化应用。 与 Docker 环境不同,不能直接在 Kubernetes 上运行容器。 请将容器打包到称为 Pod 的 Kubernetes 对象中。 Pod 是 Kubernetes 中可创建的最小对象。

Diagram of a pod with a website as the primary container.

单个 Pod 可容纳一组容器(可以是一个或多个容器)。 但是,Pod 通常不包含同一个应用的多个实例。

Pod 包含有关共享存储和网络配置的信息,以及有关如何运行其打包容器的规范。 使用 Pod 模板定义在群集中运行的 Pod 的相关信息。 Pod 模板是 YAML 编码文件,可重复使用并包含在其他对象中以用于管理 Pod 部署。

Diagram of pod with a website as the primary container and a supporting container. The node has both an assigned IP address and a localhost host address.

例如,假设你要向 Kubernetes 群集部署网站。 你需要创建 Pod 定义文件,该文件指定应用的容器映像和配置。 接下来将 Pod 定义文件部署到 Kubernetes。

Web 应用不太可能将网站作为解决方案中的唯一组件。 Web 应用通常有某种类型的数据存储和其他支持元素。 Kubernetes Pod 还可以包含多个容器。

假设你的站点使用数据库。 网站会打包到主容器中,数据库会打包到支持容器中。 多个容器通过环境相互通信。 容器包括用于主机操作系统、网络堆栈、内核命名空间、共享内存和存储卷的服务。 Pod 是为应用提供所有这些服务的沙盒环境。 Pod 还允许容器共享其分配的 IP 地址。

由于你可能会创建在多个节点上运行的多个 Pod,因此很难识别它们。 你可以使用在定义 Pod 时指定的字符串标签来识别 Pod 并进行分组。

Kubernetes Pod 的生命周期

Kubernetes Pod 独特的生命周期会影响部署、运行和更新 Pod 的方式。 首先,将 Pod YAML 清单提交到群集。 提交清单文件并保存到群集后,它会定义所需的 Pod 状态。 计划程序将 Pod 安排到正常的节点,正常的节点具有足够的资源来运行 Pod。

Diagram that shows the lifecycle of a pod.

Pod 生命周期包含以下各个阶段:

阶段 说明
待定 Pod 接受群集,但并非群集中的所有容器都已设置完毕或已准备好运行。 “挂起”状态指示 Pod 等待计划的时间和下载容器映像所花费的时间。
运行 Pod 中的所有资源准备就绪后,Pod 会转变为运行状态。
成功 Pod 完成其预期任务并成功运行后,Pod 会转变为成功状态。
失败 Pod 可能因多种原因而失败。 Pod 中的容器可能发生故障,导致所有其他容器终止;可能会在准备 Pod 容器期间找不到映像。 在这些情况下,Pod 可能转换到“失败”状态。 Pod 可从“挂起”状态或“正在运行”状态转换到“失败”状态。 特定的失败还可以将一个 Pod 变回挂起状态。
未知 如果无法确定 Pod 的状态,则该 Pod 处于“未知”状态。

Pod 会一直保存在群集上,直到控制器、控制平面或用户显式地删除它们。 删除 Pod 后,会立即创建一个新 Pod。 新 Pod 是根据 Pod 清单生成的全新实例,并非完全相同的副本,因此不同于已删除的 Pod。

群集不会保存 Pod 的状态或动态分配到的配置。 例如,它不会保存 Pod 的 ID 或 IP 地址。 这一点会影响部署 Pod 的方式以及应用的设计方式。 例如,你不能依赖于 Pod 预先分配到的 IP 地址。

容器状态

请记住,这些阶段是 Pod 在其生命周期中所处位置的总结。 检查 Pod 时,群集会使用三种状态来跟踪 Pod 中的容器:

状态 说明
等待 这是容器的默认状态,以及容器在未运行或未终止时的状态。
运行 容器正在按预期运行,未出现任何问题。
终止 容器不再运行。 原因是所有任务都已完成或容器因某种原因失败。 原因和退出代码可用于调试这两种情况。