1.7.2 循环嵌套

期望状态通常是人来制定的,比如通过YAML描述期望状态,然后交给控制器去执行。

这样是没有问题的,但是通常情况下,实际状态可能会更加复杂。站在工程师专业的角度,我们会通过抽象和组合来应对这种复杂的情况。如果不使用抽象和组合,如果必须为我们的期望状态定义每个细节,那么:(1)将通过网络发送很多关于期望状态的信息;(2)需要一个非常复杂的控制器控制所有的细节信息[14]

对于这种复杂的情况,业界一般通过分层控制来解决,即通过上一层控制器来修改一个控制器的期望状态。例如,工业窑炉中有很多控制器,这些控制器通过每个燃气进气开关控制可燃的燃气量。那么到底多少燃气量才是合适的呢?这个燃气量是由上一层控制器决定的。也就是说,有两层控制器为数百个燃烧器设置正确的气体流量,而不是整个系统通过一个控制器来控制整个燃气炉的温度是多少。燃气炉中的多层控制系统如图1.14所示。

根据单一职责原则,这属于分层架构。温度控制与气流控制有不同的关注点。软件系统也是如此:通过光纤传送信号的业务不同于构建数据帧,构建数据帧不同于发送数据包,更与GET请求区别甚远。开发业务代码(如使用JavaScript)的人不需要了解开发光学控制算法。有些人可能认为这很可惜,此处笔者保留自己的观点。

img

图1.14 燃气炉中的多层控制系统

最终,这种反馈控制回路的层次结构将由开发人员决定。开发人员描述了一个期望的系统(实现某个目的的软件),想要期望的系统发生变化,从而创建一系列其他不断变化的系统。不久,部署将为下层控制器设置新的目标。大多数情况下,我们只专注于正在采取的行动即可,但希望行为的目的明确。

Kubernetes基于反馈回路控制模式构建,并提供声明式的API架构,以便扩展开发各种不同的控制器。Kubernetes使用分层控制来控制各自的资源:Pod由ReplicaSets控制器控制,而ReplicaSets由Deployments控制器控制。运行一个Knative应用所涉及的Knative和Kubernetes多层控制器如图1.15所示。

Knative Serving建立在上述多层反馈控制模式之上,它提供了服务(Service)、配置(Configuration)、修订版本(Revision)和路由(Route)的API接口。这些由第一级控制器处理,这些控制器将它们分解为其他控制器的目标,以此类推,直到控制的目标是底层的为止(底层对外屏蔽)。使用者的目标是成为这个分层控制系统中的顶级控制者,其他的都交给Knative处理。

img

图1.15 运行一个Knative应用所涉及的Knative和Kubernetes多层控制器