控制器

在机器人技术和自动化领域,控制循环 是一个不断循环的循环,用于调节系统的状态。

以下是一个控制循环的例子:房间里的恒温器。

当你设置温度时,就是告诉恒温器你的目标状态。房间的实际温度是当前状态。恒温器通过打开或关闭设备,将当前状态调整到更接近目标状态。

在 Kubernetes 中,控制器是控制循环,它们监控你集群的状态,然后在需要时进行更改或请求更改。每个控制器都试图将当前集群状态调整到更接近目标状态。

控制器模式

控制器至少跟踪一种 Kubernetes 资源类型。这些对象都有一个 `spec` 字段,代表目标状态。负责将当前状态调整到更接近目标状态的是该资源的控制器。

控制器可能会自己执行操作;更常见的是,在 Kubernetes 中,控制器会向API 服务器发送具有有用副作用的消息。你将在下面看到这方面的示例。

通过 API 服务器控制

作业控制器是 Kubernetes 内置控制器的示例。内置控制器通过与集群 API 服务器交互来管理状态。

作业是 Kubernetes 资源,它运行一个Pod,或者可能运行多个 Pod,以执行任务,然后停止。

(一旦调度,Pod 对象就成为 kubelet 目标状态的一部分)。

当作业控制器看到一项新任务时,它会确保在你的集群中的某个位置,一组节点上的 kubelet 正在运行正确数量的 Pod,以完成工作。作业控制器本身不运行任何 Pod 或容器。相反,作业控制器告诉 API 服务器创建或删除 Pod。控制平面中的其他组件会根据新信息采取行动(有新的 Pod 要调度和运行),最终工作完成。

在创建新作业后,目标状态是该作业完成。作业控制器使该作业的当前状态更接近你的目标状态:创建 Pod 来执行你为该作业想要执行的工作,以便该作业更接近完成。

控制器还会更新配置它们的那些对象。例如:一旦作业完成工作,作业控制器就会更新该作业对象以将其标记为 `Finished`。

(这有点像某些恒温器如何关闭灯光以表明你的房间现在已达到你设置的温度)。

直接控制

与作业相比,一些控制器需要对集群外部的事物进行更改。

例如,如果你使用控制循环来确保你的集群中有足够的节点,那么该控制器需要集群外部的东西在需要时设置新节点。

与外部状态交互的控制器从 API 服务器中找到其目标状态,然后直接与外部系统通信,以使当前状态更接近目标状态。

(实际上存在一个控制器,可以水平扩展你集群中的节点)。

这里重要的是,控制器会进行一些更改以实现你的目标状态,然后将当前状态报告回你集群的 API 服务器。其他控制循环可以观察这些报告的数据并采取自己的行动。

在恒温器示例中,如果房间非常冷,则另一个控制器也可能会打开防冻加热器。对于 Kubernetes 集群,控制平面通过扩展 Kubernetes,间接地与 IP 地址管理工具、存储服务、云提供商 API 和其他服务进行交互来实现这一点。

目标状态与当前状态

Kubernetes 采用云原生视角来查看系统,并且能够处理不断变化的情况。

你的集群可能在任何时候都在发生变化,因为工作正在进行,而控制循环会自动修复故障。这意味着,你的集群可能永远不会达到稳定状态。

只要你的集群的控制器正在运行并能够做出有用的更改,总体状态是否稳定并不重要。

设计

作为其设计原则之一,Kubernetes 使用大量控制器,每个控制器都管理集群状态的特定方面。最常见的是,一个特定的控制循环(控制器)使用一种资源作为其目标状态,并拥有另一种资源,它会管理这些资源以实现该目标状态。例如,作业的控制器跟踪作业对象(以发现新工作)和 Pod 对象(以运行作业,然后查看工作何时完成)。在这种情况下,其他内容会创建作业,而作业控制器会创建 Pod。

使用简单的控制器而不是一个单片式的控制循环集合是有用的,这些控制循环是相互关联的。控制器可能会出现故障,因此 Kubernetes 的设计允许这种情况发生。

运行控制器的几种方式

Kubernetes 带有一组内置的控制器,这些控制器在kube-controller-manager内部运行。这些内置控制器提供了重要的核心行为。

部署控制器和作业控制器是作为 Kubernetes 本身的一部分(“内置”控制器)提供的控制器的示例。Kubernetes 允许你运行一个弹性控制平面,以便如果任何内置控制器出现故障,控制平面的另一个部分将接管工作。

你可以找到在控制平面外部运行的控制器,以扩展 Kubernetes。或者,如果你愿意,你可以自己编写一个新的控制器。你可以将自己的控制器作为一组 Pod 运行,也可以在 Kubernetes 外部运行。最适合哪种方式将取决于该特定控制器执行的操作。

下一步

上次修改时间:2023 年 11 月 22 日下午 2:00 PST:在控制器页面上添加指向 sample-controller 存储库的链接 (1b2cb46752)