控制器

在机器人和自动化中,控制循环 是一个调节系统状态的非终止循环。

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

当您设置温度时,就是在告诉恒温器您的期望状态。实际的房间温度是当前状态。恒温器通过打开或关闭设备来使当前状态更接近期望状态。

在 Kubernetes 中,控制器是监视您的集群状态,然后在需要时进行更改或请求更改的控制循环。每个控制器都试图使当前的集群状态更接近期望的状态。

控制器模式

控制器跟踪至少一种 Kubernetes 资源类型。这些对象有一个 spec 字段,表示期望的状态。该资源的控制器负责使当前状态更接近期望的状态。

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

通过 API 服务器进行控制

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

Job 是一个 Kubernetes 资源,它运行一个Pod,或者可能是几个 Pod,来执行任务,然后停止。

(一旦调度,Pod 对象将成为 kubelet 的期望状态的一部分)。

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

创建新 Job 后,期望状态是完成该 Job。Job 控制器使该 Job 的当前状态更接近您的期望状态:创建为该 Job 执行您想要的工作的 Pod,从而使 Job 更接近完成。

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

(这有点像某些恒温器会关闭灯光以指示您的房间现在处于您设置的温度)。

直接控制

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

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

与外部状态交互的控制器从 API 服务器找到它们的期望状态,然后直接与外部系统通信,以使当前状态更接近一致。

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

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

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

期望状态与当前状态

Kubernetes 采用云原生系统视图,能够处理不断的变化。

当工作发生并且控制循环自动修复故障时,您的集群可能随时都在变化。这意味着,您的集群可能会永远不会达到稳定状态。

只要集群的控制器正在运行并且能够进行有用的更改,无论整体状态是否稳定都无关紧要。

设计

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

拥有简单的控制器,而不是一组相互关联的单体控制循环是有用的。控制器可能会失败,因此 Kubernetes 的设计允许这种情况发生。

运行控制器的方式

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

Deployment 控制器和 Job 控制器是 Kubernetes 本身提供的控制器(“内置”控制器)的示例。Kubernetes 允许您运行弹性控制平面,以便在任何内置控制器发生故障时,控制平面的另一部分将接管工作。

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

下一步