现在都流行面向
Kubernetes
编程,也就是使用Kubernetes
申明式API,面向终态思想衍生出来的管控平台。 但流行的东西就真的适合么?
管控平台
管控平台就是公司后台资源和应用服务的系统,也被称作运维平台。
演进
一个公司的运维,通常先从单机脚本开始,随着规模逐渐扩大,需求增多,慢慢演变出平台型的云位系统。 为了解决任务执行过程中的异常,在系统中加入一些状态判断,慢慢演变出任务流系统,再在此基础上衍生出巡检系统,智能修复系统等。 更进一步,让运维平台支持更大的规模,以及多租户后,就变成了云平台。
分层
一般的运维系统通常会有两个部分,逻辑层和操作层。逻辑层组织业务处理的流程,操作层负责执行具体操作。 假设我们要创建一个数据库实例,需要以下几个步骤: 1. 申请主机资源。 2. 在主机上安装数据库。 3. 初始化数据库文件。 4. 启动数据库。 5. 初始化数据库账号等信息。 6. 建立数据访问通道。
每个步骤都对应一个函数,这些函数便是操作层。 逻辑层则是将这些步骤串联起来。就和高级语言一样,封装的多了,开发也就更方便。 逻辑规则可以是代码,也可以是配置,二者也是可以相互转换的。过于复杂的规则不如用代码,简单的流程不如写规则。
管控逻辑
操作层都差不多,主要的区别在于逻辑层。 同样的功能有不同的设计思想和实现方式,但本质上还是相同的,都是让事情按照一定的依赖执行下去。
任务流
任务流就好像是一个传送带,每个任务就是传送带上的物品,传送带把物品送到执行点,处理后运往下一个执行点。最简单的任务流就是这样顺序执行。
优点
- 任务流的特点在于逻辑简单,因为任务流的思维逻辑出发点在于任务本身,由任务(传送带)去驱动每个工作环节。这是一个顺序的思维,符合常人的思维模式。
- 通常使用配置文件编写任务流程,很好地分离了逻辑层和操作层。
缺点
- 从图中可以看出,流程较为简单,任务走向是固定的。
- 全局同步,受全局任务队列控制,通常只会单线程执行。
Operaotr式
Operator
就是Kubernetes
的工作单元,它依托Kubernetes
运行。
Operator
需要主动去获取任务,就好像是一个自治工作单元的组合。每个单元前会有一个自己的入口和出口队列,它们接收上游的任务,处理后放到下游的队列中。
优点
- 有非常好的并行度,类似
systemd
的思想,让所有自启动程序自己运行,然后它们会根据依赖关系自己推进。 - 更高的灵活性。
缺点
Operator
的逻辑是一种逆向思维。思维逻辑出发点在每个工作单元,没有很好地全局视角,所以对开发者的要求较高。- 由于
Operator
是通过任务的属性来判断状态的,这就导致逻辑代码会有非常多的if else
,对代码维护不利。 - 过于灵活,可能会产生死循环。
小结
任务流是从简单开始,去累加更多的功能。
Operator
则是站在了更高的起点上,把复杂留给自己,再慢慢优化。
设计思想
实现方式也和设计思想相关。
面向任务和面向终态对应任务流和Operator
式管控逻辑。
面向任务
传统的RPC
思想,即接口对应操作。
复杂的操作通过简单的操作组合实现。
面向终态
这是因Kubernetes
流行起来的一种设计。虽然在Kubernetes
之前也有类似实现,但没有现在这么热门。
面向终态指的是管控系统的API调用为声明式的描述,后台系统会根据期望的状态推进。代码实现在Reconcile
中,通过不断Reconcile
推进状态。
比如使用Kubernetes
的Operator
来设计管控平台,也就是所谓的面向Kubernetes
编程。
对比
- 在适用范围上,面向任务的接口模式是面向终态的超集。
- 在抽象层面上,面向终态是在面向任务之上更具体的抽象。
- 在单纯的操作类接口上,命令式操作更符合习惯。
- 在配置或资源修改类的操作上,面向终态的申明式接口更契合。
类比
方式 | 设计 | 编程 | 思维 | 特点 |
---|---|---|---|---|
面向任务 | 过程式设计/接口 (Procedural) | 面向过程(OP) | 过程导向 | 使用者友好 |
面向终态 | 声明式设计/接口 (Declarative) | 面向对象(OO) | 结果导向 | 开发者友好 |
总结
面向Kubernetes的设计适合较为简单的事务。但在有较为复杂的逻辑处理时,面向任务的设计更加适合。 但其实二者在实现上都可以优化,吸收对方的优点。只是方向不同罢了。 所以,具体需求具体分析,找到最合适的抽象方式,而不是手里有个锤子,看什么都是钉子那样生搬硬套的过度抽象。