控制器

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

控制回路的一个例子是房间里的恒温器。

当你设定温度时,这相当于告诉恒温器你的期望状态。实际的房间温度是当前状态。恒温器通过开启或关闭设备,使当前状态更接近期望状态。

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

控制器模式

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

控制器可能会自行执行操作;更常见的是,在 Kubernetes 中,控制器会向 API server 发送具有有用副作用的消息。下面你会看到相关的例子。

通过 API server 控制

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

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

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

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

创建新 Job 后,期望状态是该 Job 已完成。Job 控制器使该 Job 的当前状态更接近你的期望状态:创建执行该 Job所需工作的 Pod,以便 Job 更接近完成。

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

(这有点像某些恒温器通过关掉灯来指示房间温度已达到设定值)。

直接控制

与 Job 不同,有些控制器需要修改集群外部的事物。

例如,如果你使用控制回路来确保集群中有足够的 Nodes,那么该控制器就需要集群外部的东西来在需要时设置新的 Node。

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

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

这里的重点是,控制器会做一些改动以实现你的期望状态,然后将当前状态报告回集群的 API server。其他控制回路可以观察报告的数据并采取自己的行动。

在恒温器例子中,如果房间非常冷,则另一个控制器也可能打开防霜加热器。对于 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 外部运行。最适合的方式取决于该特定控制器的功能。

下一步