Kubernetes 与 Cybernetics
3月24日 3:29 更新
开启更多功能,提升办公效能

摘要

本文首先介绍了控制论的基本概念,然后在此基础之上讨论了 kubernetes 通过负反馈控制实现容器化应用管理的可行性。最后通过控制论分析了 kubernetes 在容器编排领域的实践。

Kubernetes & Cybernetics

在云原生领域,Kubernetes 是一个用于自动部署、扩缩和管理容器化应用程序的系统。Kubernetes 之名来源于希腊语,意为“舵手”或“领航员”,旨在成为容器编排领域的“舵手”,为容器化应用提供统一的部署、管理和调度服务。


控制论(cybernetics)这个词来源于希腊文的“kubernetes”(舵手)一词,选择这个词是因为船舶的舵机是一种较早且发展较为完善的反馈机制。在古希腊,三列桨战船上的舵手要指挥一百多名划桨手随时变换他们的动作,使战船获得想要的方向和速度。“Kubernetes” 一词还有另一个译法:调节器。瓦特于 18 世纪发明的蒸汽机使用离心式调速器来度量引擎的速度,并调节进人气缸的蒸汽量。这些早期的机械控制体现了控制论中“反馈与控制”的思想。(引自《控制论革命者》)

图片来源:"Discoveries & Inventions of the Nineteenth Century" by Robert Routledge, published: 1901.


那么什么是控制论,Kubernetes 和控制论之间又有哪些关系。

Cybernetics

控制论是一门研究系统、控制和通信一般规律的学科,由诺伯特·维纳创立。控制论关注如何通过反馈机制来控制和调节系统,无论这些系统是机械的、生物的还是社会的。


说明:本章节很大程度引用或参考了金观涛老师《控制论与科学方法论》一书的内容和观点。

可能性空间

世界上很多事物的发展具有不确定性。事物并不是从一开始就注定要发展成现在这个样子的,在事物发展的初期往往有多种发展的可能性,由于某些条件或者纯粹偶然的关系,最终才沿着某一个特定的方向发展下去。


生物的进化过程可以通过生命之树来表达,这是物种在其发展过程中按可能性空间展开的形象体现。生物多样性是自然选择、环境变化、隔离、基因突变等多种复杂条件的影响经过数十亿年演化形成的。

图片来源:《控制论与科学方法论》


我们将事物发展变化中面临的各种可能性集合称为这个事物的可能性空间。

控制

事物发展的可能性空间或事物的不确定性,是由事物内部的矛盾决定的。我们根据自己的目的改变条件,使事物沿着可能性空间内的某种确定的方向发展,就形成了控制。控制,归根结底是一个在事物可能性空间中进行有方向选择的过程。


自然环境下,存在着各种各样特性的水稻品种的可能性,例如抗旱但不抗寒、抗虫但不高产、低产但抗虫等等。农业研究员通过杂交育种技术培育出来的新的水稻品种,结合了多个亲本的优良遗传特性,达到了提高水稻高产高质量的目的。

控制能力

实行控制前后的可能性空间之比称为控制能力。如果某一事物的可能性空间为,实行控制后可能性空间缩小为,那么控制能力就是


弓箭手射靶,是他用弓对箭飞出去的位置实行某种控制。箭越靠近靶心,表示弓箭手的控制能力越强,因为他将箭的可能性空间范围缩得越小。所以环数是控制能力的一种表示方法,环数代表了弓箭手水平的高低。


每实行一次控制后,事物发展的可能性空间缩小了。可能性空间缩得越小,表示控制能力越强。

对于同一事物,控制能力越强其控制过程一般也更复杂,同时这也取决于采用的控制方法和技术。对于大多数控制过程,把可能性空间缩小到一定范围就能达到控制的目的了,而某些特殊情况下需要把可能性空间精确地缩小到某几个或某个惟一的状态。

控制方法

在介绍了控制的一些基本概念后,我们进一步来了解控制的方法,也就是如何进行控制。


控制过程一般由三个基本环节构成:

  1. 了解事物发展的可能性空间
  1. 在可能性空间中选择某些状态为目标
  1. 控制条件使事物向既定的目标转化


常用的控制方法:随机控制、共轭控制、前馈控制、正反馈控制、负反馈控制等。本文主要涉及负反馈控制因此主要介绍负反馈控制。

负反馈控制

负反馈控制是自动控制理论中一种重要和常用的控制方法,用于提高系统的稳定性和性能。其基本原理是不断拿控制结果和目标比较,根据目标差产生相对应减少目标差的控制反应,从而使得目标差在一次一次控制中慢慢减少,最后达到控制的目的。负反馈控制是控制系统设计的基础,是实现系统稳定性和精确控制的关键技术之一。


基本组成:

  • 比较器:将控制结果和目标对比,产生目标差。
  • 控制器:根据比较器产生的目标差通过执行器进行调控。
  • 执行器:调控被控制对象以达到目标。
  • 传感器:持续监控控制结果和被控制对象,将信息反馈给控制器决策。
  • 反馈回路:系统输出(结果)返回到输入(目标)的过程,使得系统能够自我调节。确保系统稳定、减小误差和增强抗干扰能力方面起到了关键作用。被控对象具有不确定性,在不断地发展变化,所以需要通过反馈感知被控对象的变化从而进行对应的调控,让被控对象沿着我们预期的方向发展,从而达到控制的目的。


特点:

  • 提高稳定性:负反馈有助于减小系统响应的波动,使系统更稳定。它通过减少误差,抑制系统控制的过度波动和振荡,从而实现稳定的控制效果。
  • 误差校正:负反馈机制通过连续监测控制结果与目标值之间的差异,并不断调整系统来校正误差。这种自动纠错能力使得系统能够准确地达到设定的目标。
  • 抗干扰能力:负反馈控制有较强的适应能力,可以有效抵抗外部扰动和系统内部的不确定性。即使在面对环境变化或系统参数变化的情况下,负反馈也能帮助系统保持期望的性能。


导弹能够在复杂多变的战场环境中精确追踪并打击高机动性的战机。这种控制方法的核心在于实时误差计算和持续路径调整,确保导弹始终朝向目标,直到最终命中。负反馈控制系统提供了高精度、快速响应和强抗干扰能力,使得导弹具备了卓越的追踪和打击性能。

控制与信息

控制与信息和通信密切相关。控制的核心是缩小事物可能性空间的范围,而信息的本质是消除不确定性。目标、反馈数据和控制结果等关键信息对于理解系统的当前状态至关重要,这些信息是制定精确控制决策的基础。没有准确的信息,就无法做出精准的控制决策。例如,反馈信息不准确会导致控制器进行错误的控制,从而影响系统的稳定性。

小结

控制论的应用非常广泛,它影响了生物、社会、工程等多个领域。例如,在生物领域,控制论帮助我们理解生物体如何通过反馈机制调节其内部状态;在工程领域,控制论原理被用于设计和分析自动控制系统。

Kubernetes

容器编排

当要运行单个容器实例的服务,我们可以通过 Docker 在一台机器把容器运行起来。如果容器实例意外停止运行,我们需要确保容器在当前或其他机器重新运行起来,以维持服务的连续性和可用性。


容器有创建、运行、暂停、停止、退出、删除、未知等状态,这些状态也就是容器可能性空间的可能性集合。影响容器状态的条件有:硬件、操作系统、网络、容器环境、容器自身、人为操作等。这些条件自身可能会不断的变化,例如可用内存资源会不断改变。所以维持容器运行其实就是通过不断改变这些条件(内存足够、网络通畅等)从而把容器控制在运行状态。


人工控制容器运行的过程,是一个简单的负反馈控制模型:



在实际生产环境,应用的微服务数量少则几十多则数千甚至更多,每个服务又有数量不同的实例。因此机器数量也随之增多,并且还有可能遍布多个国家和地区的机房。


规模化场景下软硬件故障成为常态:

  • 故障概率累积效应:假设每台机器的故障概率为,当有台机器时,至少有一台机器发生故障的概率为。随着的增加,故障的总概率会接近于
  • 系统复杂性理论:系统复杂性理论指出,随着系统组件数量的增加和相互依赖关系的复杂化(复杂性增加),系统的不确定性和出错的可能性也随之增加。微服务架构由于其分布式的特性,使得系统更加复杂,因此故障出现的概率可能会增加。
  • 故障域理论:在分布式系统中,故障域是指一个故障可能影响的范围。微服务架构中,服务分布在多个机器或机房,增加了故障域的数量,从而增加了故障传播的可能性。


假设每个容器有种可能的状态,微服务容器的数量为,那么所有容器的可能性空间的可能性集合为。为了达到应用持续运行的目标我们需要尽可能控制每个容器都处于运行的状态,控制的复杂度远超单机单实例的复杂度。


在这种复杂的场景中,传统的人工管理方法已难以应对。因此,我们需要自动化工具来高效地管理容器化应用。在这样的背景下,以 Kubernetes 为代表的容器编排系统应运而生。

kubernetes

考虑容器编排面临的问题以及负反馈控制的特点,我们可以认为负反馈控制适合用来实现自动化容器编排系统。



Kubernetes 实现了一个典型的负反馈控制系统。Kubernetes 通过 API Server 接收用户的声明式配置(目标),然后控制器持续监控被控制对象的状态,并与目标状态进行比较。如果实际状态与目标状态存在差异,控制器会自动采取调整措施,以逐步减少这种差异,确保系统最终达到或保持在目标状态。这种机制构建了一个“监测-决策-执行”的反馈循环,保障系统在动态环境下的稳定性和一致性。

  • Kubernetes Objects:kubernetes 资源对象,例如 Deployment、Pod 等
  • Spec:目标
  • Status:控制结果
  • Control Objects:被控制对象,例如 Pod、容器等
  • Controller:控制器,这里的控制器实际上包括了传感器、比较器和执行器
  • Observe:监控器,例如 Informer,获取目标和被控制对象的当前状态
  • Analyze:分析器,分析当前被控制对象和目前之间的差异
  • Act: 执行器,根据分析器产生的差异对被控制对象采取调控


控制系统的主要任务之一是识别用户的目标以及将控制结果反馈给用户。Kubernetes 使用资源对象作为其声明式 API 的交互方式,这种方式天然适合表达用户目标。例如 Deployment 表示一个容器服务:

apiVersion: apps/v1
kind: Deployment # 容器服务
metadata:
name: nginx-service
namespace: default
spec: # 目标:需要三个实例版本为 1.26.0 的 Nginx 服务
replicas: 3
template:
spec:
containers:
- image: nginx:1.26.0
name: nginx
ports:
- containerPort: 80
status: # 控制结果
availableReplicas: 3
readyReplicas: 3 # 三个实例正常运行
replicas: 3 # 有三个实例
updatedReplicas: 3 # 有三个镜像版本为 1.26.0 的实例


容器编排实际由多个子控制系统协作完成,每个子系统则由一个或多个控制器组成。控制器之间通过订阅模式进行通信和协作,API Server 是信息的中心枢纽,资源对象是控制器之间信息传递的载体,同时也是控制器协作的契约。这样的协作方式不需要中心化的协调控制,每个控制器按照约定完成自己所负责的工作。订阅模式耦合度较低,可以提高系统的灵活性和可扩展性。通过添加新的控制器可以新增加的功能,或是使用新的控制器替换部分控制器从而改变已有的功能。订阅模式的性能和实时性也比较好,可以实时传递信息,提高控制的实时性。


我们进一步分析这些子系统如何协作完成容器编排。

Deployment

Deployment 控制系统负责控制整个容器服务,也就是服务的生命周期管理。


Deployment 控制器会持续监控自己管理的 Pod,如果 Pod 没有达到目标数量,Deployment 控制器会创建足够数量的 Pod。而如果 Pod 处于非正常状态,Deployment 系统会和 kubelet 系统协作处理,详细参考 kubelet 部分。


现代软件需要频繁的更新和发布,Deployment 控制器通过 ReplicaSet 控制器间接管理 Pod,每个 ReplicaSet 负责管理一组相同版本的 Pod。容器遵循不可变基础设施的原则,因此版本的变更通过新旧容器更替实现。这种替换会导致系统(包括 Kubernetes 系统和容器应用系统)从一个稳定状态过渡到另一个稳定状态,而这个过渡过程可能引起系统波动或震荡。

通过设置 RollingUpdate 参数,可以控制版本更新的速率,使系统的过渡过程更加平滑。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-service
  namespace: default
spec:
  replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate

Scheduler

调度系统负责为 Pod 选择合适的节点。


从 Pod 的角度,调度器的目标是为 Pod 选择主机。假设集群有个节点,那么 Pod 调度到节点的可能性空间的可能性集合为


从整个系统来说,调度器通过综合评估节点的状态、资源使用情况和调度约束,来做出最优的调度决策,从而优化集群的整体性能和资源利用,这种控制方式称为优化控制。优化控制在控制论中是通过系统化的、基于规则和目标的方式来调整控制变量,以优化某个性能指标的过程。

apiVersion: v1
kind: Pod
metadata:
name: nginx-service-8556777689-9s7d9
namespace: default
spec:
- nodeName: "" # 目标,给 Pod 选择一个合适的节点
+ nodeName: "cybernetics-node" # 控制结果,给 Pod 选择了节点 cybernetics-node

nodeName 既是目标也是控制结果,nodeName 同时也是控制器之间协作的契约。ReplicaSet 控制器创建了待调度的 Pod,调度器为 Pod 选择合适的节点,kubelet 控制器在节点上为 Pod 创建对应的容器。

Kubelet

Kubelet 负责控制节点上的容器,也就是容器的生命周期管理。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-service-8556777689-9s7d9
  namespace: default
spec: # 目标,一个版本为 1.26.0 的 Nginx 容器
  containers:
  - image: nginx:1.26.0
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP
  nodeName: "cybernetics-node"
status: # 控制结果,容器当前的状态
  containerStatuses:
  - containerID: containerd://0f54f0320ffea7e717a8ad367d461c277f4e08ae6b1d9e6e3ddc1361d409d675
    image: docker.io/library/nginx:1.26.0
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2024-06-08T15:46:00Z"

Kubelet 从 API Server 获取调度器分配到它所在节点的 Pod。如果 Pod 对应的容器还没有在当前机器创建,kubelet 会通过 CRI 创建新的容器。同时 Kubelet 会持续监控节点上的容器,如果容器处于非运行状态,kubelet 尝试通过重启恢复容器的运行状态。影响容器运行的条件很多,kubelet 如果要改变这些条件去满足容器运行的需求是比较复杂的,重启无疑是最简单的方式。但重启并不能都能保证容器可以恢复运行,例如容器自身问题、节点资源不足等。从容器服务的目标来说,关注的是有足够数量在运行的容器,所以最简单处理的策略就是,当重启容器无法恢复运行,Deployment 控制器会删除异常 Pod,然后创建新的 Pod,并由调度器选择合适的节点。控制关心的是目标的达成,所以控制的过程应该采用尽可能简单的方式,不一定需要复杂的控制和更强的控制力。

小结

kubernetes 是一个典型的负反馈控制系统,它基于负反馈等控制方法实现了高效稳定的容器编排管理。一个控制系统可以由多个子控制系统组成一个大的目标可以拆分成多个小目标,并由不同的子控制系统协作完成每个小目标,直至整个大的目标达成。

总结

控制论揭示了系统运行的普遍规律,广泛应用于工程系统等。通过分析我们了解了 Kubernetes 如何利用负反馈控制等控制方法实现容器应用的高效管理。进一步地,我们可以借鉴控制论的思想,设计出高效稳定的软件控制系统。

参考

[1] 金观涛,华国凡.控制论与科学方法论.新星出版社.2005

[2] 诺伯特·维纳.控制论.重庆出版社.2023

[3] 郭雷.系统控制之美.2024