--- title: 控制器 content_template: templates/concept weight: 30 --- {{% capture overview %}} 在机器人技术和自动化中,控制环是一个控制系统状态的不终止的循环。 这是一个控制环的例子:房间里的温度自动调节器。 当你设置了温度,告诉了温度自动调节器你的*期望状态*。房间的实际温度是*当前状态*。通过对设备的开关控制,温度自动调节器让其当前状态接近期望状态。 {{< glossary_definition term_id="controller" length="short">}} {{% /capture %}} {{% capture body %}} ## 控制器模式 {#controller-pattern} 一个控制器至少追踪一种类型的 Kubernetes 资源。这些[对象](/docs/concepts/overview/working-with-objects/kubernetes-objects/)有一个代表期望状态的指定字段。正对这种资源的控制器就是要使他的当前状态接近与期望状态。 控制器可能会自行执行操作;在 Kubernetes 中更常见的是一个控制器会发送信息给 {{< glossary_tooltip text="API 服务器" term_id="kube-apiserver" >}},这会有副作用。看下面这个例子。 {{< comment >}} 一些内置的控制器,比如命名空间控制器,针对没有指定命名空间的对象。为了简单起见,这篇文章没有详细介绍这些细节。 {{< /comment >}} ### 通过 API 服务器来控制 {#control-via-API-server} {{< glossary_tooltip term_id="job" >}} 控制器是一个 Kubernetes 内置控制器的例子。内置控制器通过和集群 API 服务器交互来管理状态。 Job 是一种 Kubernetes 资源,它运行一个 {{< glossary_tooltip term_id="pod" >}},或者可能是多个 Pod,来执行一个任务然后停止。 (一旦[被调度了](/docs/concepts/scheduling/)),对 kubelet 来说 Pod 对象就会变成了期望状态的一部分。 在集群中,当 Job 控制器拿到新任务时,它会保证一组 Node 节点上的 kubelet 可以运行正确数量的 Pod 来完成工作。 Job 控制器不会自己运行任何的 Pod 或者容器。Job 控制器是通知 API 服务器来创建或者移除 Pod。 {{< glossary_tooltip text="控制平面" term_id="control-plane" >}}中的其它组件根据新的消息而反应(调度新的 Pod 并且运行它)并且最终完成工作。 创建新 Job 后,所期望的状态就是完成这个 Job。Job 控制器会让 Job 的当前状态不断接近期望状态:创建为 Job 要完成工作所需要的 Pod,使 Job 的状态接近完成。 控制器也会更新配置对象。例如:一旦 Job 的工作完成了,Job 控制器会更新 Job 对象的状态为 `Finished`。 (这有点像温度自动调节器关闭了一个灯,以此来告诉你房间的温度现在到你设定的值了)。 ### 直接控制 {#direct-control} 相比 Job 控制器,有些控制器需要对集群外的一些东西进行修改。 例如,如果你使用一个控制环来保证集群中有足够的{{< glossary_tooltip text="节点" term_id="node" >}},那么控制就需要当前集群外的一些服务在需要时创建新节点。 和外部状态交互的控制器从 API 服务器获取到它想要的状态,然后直接和外部系统进行通信并使当前状态更接近期望状态。 (实际上有一个控制器可以水平地扩展集群中的节点。请看[集群自动扩缩容](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaling))。 ## 期望状态与当前状态 {#desired-vs-current} Kubernetes 采用了系统的云原生视图,并且可以处理持续的变化。 在任务执行时,集群随时都可能被修改,并且控制环会自动的修复故障。这意味着很可能集群永远不会达到稳定状态。 只要集群中控制器的在运行并且进行有效的修改,整体状态的稳定与否是无关紧要的。 ## 设计 {#design} 作为设计的一个原则,Kubernetes 使用了很多控制器,每个控制器管理集群状态的一个特定方面。最常见的一个特定的控制器使用一种类型的资源作为它的期望状态,控制器管理控制另外一种类型的资源向它的期望状态发展。 使用简单的控制器而不是一组相互连接的单体控制环是很有用的。控制器会失败,所以 Kubernetes 的设计是考虑到了这一点。 例如:为 Job 追踪 Job 对象(发现新工作)和 Pod 对象(运行 Job,并且等工作完成)的控制器。在本例中,其它东西创建作业,而作业控制器创建 Pod。 {{< note >}} 可以有多个控制器来创建或者更新相同类型的对象。在这之后,Kubernetes 控制器确保他们只关心和它们控制资源相关联的资源。 例如,你可以有 Deployments 和 Jobs;它们都可以创建 Pod。Job 控制器不删除 Deployment 创建的 Pod,因为有信息({{< glossary_tooltip term_id="label" text="标签" >}})让控制器可以区分这些 Pod。 {{< /note >}} ## 运行控制器的方式 {#running-controllers} Kubernetes 自带有一组内置的控制器,运行在 {{< glossary_tooltip term_id="kube-controller-manager" >}} 内。这些内置的控制器提供了重要的核心功能。 Deployment 控制器和 Job 控制器是 Kubernetes 内置控制器的典型例子。Kubernetes 运行一个弹性的控制平面,所以如果任意内置控制器失败了,控制平面的另外一部分会接替它的工作。 你会发现控制平面外面运行的控制器,扩展了 Kubernetes 的能力。或者,如果你愿意,你也可以写一个新控制器。你可以以一组 Pod 来运行你的控制器,或者运行在 Kubernetes 外面。什么是最合适的控制器,这将取决于特定控制器的功能。 {{% /capture %}} {{% capture whatsnext %}} * 请阅读 [Kubernetes 控制平面](/docs/concepts/#kubernetes-control-plane) * 了解一些基本的 [Kubernetes 对象](/docs/concepts/#kubernetes-objects) * 学习更多的 [Kubernetes API](/docs/concepts/overview/kubernetes-api/) * 如果你想写自己的控制器,请看 Kubernetes 的[扩展模式](/docs/concepts/extend-kubernetes/extend-cluster/#extension-patterns)。 {{% /capture %}}