控制器
在机器人技术和自动化领域,控制回路是一种不终止的循环,用于调节系统的状态。
控制回路的一个例子是房间里的恒温器。
当你设定温度时,这相当于告诉恒温器你的期望状态。实际的房间温度是当前状态。恒温器通过开启或关闭设备,使当前状态更接近期望状态。
在 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 控制器会确保它们只关注与其控制资源关联的资源。
例如,你可以有 Deployments 和 Jobs;它们都创建 Pod。Job 控制器不会删除你的 Deployment 创建的 Pod,因为控制器可以使用某些信息(标签)来区分这些 Pod。
运行控制器的方式
Kubernetes 内置了一组运行在 kube-controller-manager 内部的控制器。这些内置控制器提供了重要的核心行为。
Deployment 控制器和 Job 控制器是 Kubernetes 自身自带的控制器(“内置”控制器)的例子。Kubernetes 允许你运行一个具备弹性的控制平面,这样如果任何内置控制器发生故障,控制平面的另一部分将接管工作。
你可以找到运行在控制平面之外的控制器,用于扩展 Kubernetes。或者,如果你愿意,你可以自己编写一个新的控制器。你可以将自己的控制器作为一组 Pod 运行,也可以在 Kubernetes 外部运行。最适合的方式取决于该特定控制器的功能。
下一步
- 阅读有关 Kubernetes 控制平面 的信息
- 了解一些基本的 Kubernetes 对象
- 了解更多关于 Kubernetes API 的信息
- 如果你想编写自己的控制器,请参阅 Kubernetes 扩展模式 和 sample-controller 代码仓库。