当协作成员变得很多时往往很难同步交流,比如一个微信群同时在线的用户不可能太多。因此,在参与人员庞大的开源社区自然优先选择邮件列表或论坛等异步沟通等手段,在Node.js中也是通过异步编程来消除不同协作对象速度的差异。所以很多实践的地方在无法提供很好的同步API体验时,会采用事件异步触发或者定期等异步触发执行提前缓存好的操作。
在传统编程领域异步API主要是带来了性能优势,在运维场景异步API缓解了各种操作顺序差异带来的同步困难。但是异步API也有其缺点,举例来说Node.js程序会面临复杂的异步导致的嵌套问题,因为多层嵌套又引发了程序真实执行顺序难以理解的问题。简单来说,异步API如果配合需要严格依赖执行顺序的过程式编程模式将会带来Node.js面临的相似的问题。面对这个问题,Go语言尝试通过带缓存的管道来缓解异步的困难是另一种选择。而K8S则通过顺序无关的YAML数据表示的操作以配合异步API。两种手段都是在牺牲少量性能的前提下获得灵活性和便于理解的平衡,前者更适合于计算的场景、而后者更适合于资源管理场景。K8S 通过将基础设施抽象为对应的资源,实现了通过声明式描述资源期望的状态和异步状态控制达成了平衡。大家常举的例子就是空调恒温反馈系统:用户指定一个期望的稳定,空调慢慢调整到该温度,而空调本身始终处于一个动态调整的状态。
另一个额外的好处,是K8S的生命式API需要明确抽象资源的特征属性,而基于这些相对独立的属性(或者叫维度)可以让不同角色的运维和开发同学可以在同一个平台协同工作。类似开发同学在调整空调的温度之时,运维同学可以放心地调整空调的吹风方向。即可以协调又不会引起冲突正是DevOps理念同学期望的状态,因此也可以说 K8S 这种顺序无关的声明式异步API是天生DevOps亲和的(这也正是诞生的目的)。
当然K8S本身设计已经远远超出了异步API:它不仅仅通过etcd存储期望的状态,同时也时刻反映了平台本身状态,基于etcd和控制器它像粘合剂一样将所有部件连接在一起。正是这种机制,让其可以保持可扩展性、可观测性的同时与组织生态系统共存,而自身还可以不断渐进式发展保持更持久的生命力。K8S 采用的是上帝编程范式:帝哥说要有光于是就有了光,App开发者说要有超大内存就有了超大内存,SRE说要有网络于是就有了网络。这对于日常打工人来说是最大的挑战,需要将思维方式努力调整为上帝或老板模式,从干活角色变成向 K8S 发命令的角色。