我们接下来说说Operator。为什么讲Operator呢?Operator其实并不是一个工具,而是为了解决一个问题而存在的一个思路。什么问题?就是我们在管理应用时,会遇到无状态和有状态的应用。管理无状态的应用是相对来说比较简单的,但是有状态的应用则比较复杂。在Helm chart的stable仓库里面,很多数据库的chart其实是单节点的,因为分布式的数据库做起来会较为麻烦。
  
Operator的理念是希望注入领域知识,用软件管理复杂的应用。例如对于有状态应用来说,每一个东西都不一样,都可能需要你有专业的知识去处理。对于不同的数据库服务,扩容缩容以及备份等方式各有区别。能不能利用K8S便捷的特性去把这些复杂的东西简单化呢?这就是Operator想做的事情。
  
以无状态应用来说,把它做成一个Scale UP的话是比较简单的:扩充一下它的数量就行了。
 
技术分享图片
技术分享图片

   

接着在deployment或者是说ReplicaSet的controller中,会去判断它当前的状态,并向目标状态进行迁移。对有状态的应用来说,我们常常需要考虑很多复杂的事情,包括升级、配置更新、备份、灾难恢复、Scale调整数量等等,有时相当于将整个配置刷一遍,甚至可能要重启一些服务。
   
比如像Zookeeper315以前不能实时更新集群状态,想要扩容非常麻烦,可能需要把整个节点重启一轮。有些数据库可能方便一点,到master那里注册一下就好。因此每个服务都会有它自己的特点。
  
拿etcd来说,它是K8S里面主要的存储。如果对它做一个Scale up的话,需要往集群中添加一些新节点的连接信息,从而获取到集群的不同Member的配置连接。然后用它的集群信息去启动一个新的etcd节点。
  
如果有了etcd Operator,会怎么样?Operator其实是CoreOS布道的东西。CoreOS给社区出了几个开源的Operator,包括etcd,那么如何在这种情况下去扩容一个etcd集群?
  
首先可以以deployment的形式把etcd Operator部署到K8S中。部署完这个Operator之后,想要部署一个etcd的集群,其实很方便。因为不需要再去管理这个集群的配置信息了,你只要告诉我,你需要多少的节点,你需要什么版本的etcd,然后创建这样一个自定义的资源,Operator会监听你的需求,帮你创建出配置信息来。
  
$ kubectl create –f etcd-cluster.yaml
技术分享图片
 
 
要扩容的话也很简单,只要更新数量(比如从3改到5),再apply一下,它同样会监听这个自定义资源的变动,去做对应的更新。
  
$ kubectl apply -f upgrade-example.yaml

技术分享图片

这样就相当于把以前需要运维人员去处理集群的一些工作全部都交付给Operator去完成了。如何做到的呢?即应用了K8S的一个扩展性的API——CRD(在以前称为第三方资源)。
  
在部署了一个etcd Operator之后,通过kubernetes API去管理和维护目标的应用状态。本质上走的就是K8S里面的Controller的模式。K8S Controller会对它的resource做这样的一个管理:去监听或者是说检查它预期的状态,然后跟当前的状态作对比。如果其中它会有一些差异的话,它会去做对应的更新。
  
Kubernetes Controller 模式:

技术分享图片

  
etcd的做法是在拉起一个etcd Operator的时候,创建一个叫etcd cluster的自定义资源,监听应用的变化。比如你的声明你的更新,它都会去产生对应的一个事件,去做对应的更新,将你的etcd集群维护在这样的状态。
  
除了etcd以外,社区比如还有普罗米修斯Operator都可以以这种方便的形式,去帮你管理一些有状态的应用。
  
值得一提的是,Rancher2.0广泛采用了Kubernetes-native的Controller模式,去管理应用负载乃至K8S集群,调侃地说,是个Kubernetes operator。
 

五、Helm和Operator的对比

这两个东西讲完了,我们来对比一下二者吧。
   
Operator本质上是针对特定的场景去做有状态服务,或者说针对拥有复杂应用的应用场景去简化其运维管理的工具。Helm的话,它其实是一个比较普适的工具,想法也很简单,就是把你的K8S资源模板化,方便共享,然后在不同的配置中重用。
  
其实Operator做的东西Helm大部分也可以做。用Operator去监控更新etcd的集群状态,也可以用定制的Chart做同样的事情。只不过你可能需要一些更复杂的处理而已,例如在etcd没有建立起来时候,你可能需要一些init Container去做配置的更新,去检查状态,然后把这个节点用对应的信息给拉起来。删除的时候,则加一些PostHook去做一些处理。所以说Helm是一个更加普适的工具。两者甚至可以结合使用,比如stable仓库里就有etcd-operator chart。
  
就个人理解来说,在K8S这个庞然大物之上,他们两者都诞生于简单但自然的想法,helm是为了配置分离,operator则是针对复杂应用的自动化管理。