
kubernete编排技术八:使用operator管理有状态应用
作者 | 朱晋君
来源 | 君哥聊技术(ID:gh_1f109b82d301)
operator是kubernetes的一个扩展,它使用自定义资源(Custom Resources)来管理应用和组件,并且遵循kubernetes的规范。它的核心就是自己编写控制器来实现自动化任务的效果,从而取代kubernetes自己的控制器和CRD资源。
使用operator是实现自动化的需求大概有以下几类:
- 按照需求部署一个应用
- 获取或者恢复一个应用的状态
- 应用代码升级,同时关联的数据库或者配置等一并升级
- 发布一个服务,让不支持kubernetes api的应用也能发现它
- 模拟集群的故障以测试集群稳定性
- 为分布式集群选取leader节点
上面的描述来自于kubernetes官网,这个描述可以看出,operator可以使用自定义资源来编排有状态应用。
本文我以使用etcd-operator部署etcd集群为例来介绍operator的编排功能,这个案例就是用operator在kubernetes上部署一套etcd的集群。
etcd集群搭建
下载源代码,地址如下:
安装operator之前,先执行一个脚本,如下:
从这个执行结果我们看到,这个脚本是在为operator创建RBAC访问权限,这里创建了ClusterRole(etcd-operator)和ClusterRoleBinding(etcd-operator),他们的namespace都是default。对RBAC不太熟悉的同学可以查看这篇文章《kubernete编排技术六:RBAC权限控制》。
这样etcd-operator就具备了访问apiserver的权限。具体有哪些权限,我们查看一下etcd-operator这个ClusterRole:
可以看到,它的权限是非常大的,除了对secrets只有get权限外,对其他api对象都有所有的权限。我们再看下这个ClusterRoleBinding:
可以看到,User类型是一个ServiceAccount。
RBAC创建好之后,我们再来看一下etcd-operator的yaml文件,如下(注意,源码中的yaml文件不匹配我的kubernetes版本v1.17.3,我做了修改并且标记出来了):
可以看出,其实它就是一个Deployment,replicas配置的是1。下面我们创建这个对象,也就是创建etcd-operator:
创建成功后,过一段时间,就能看到这个pod进入running状态了:
创建operator时,应用会创建一个crd(Custom Resource Definition),这正是operator的特性,我们查看一下这个crd:
接着,我们查看一下这个crd的详细信息:
这个crd里面定义的Group是etcd.database.coreos.com,kind是EtcdCluster。有了这个crd,operator就可以作为一个控制器来对这个crd进行控制了。
下面我们创建集群,我们先看一下yaml文件,内容如下:
这个yaml文件的定义非常简单,集群数量是2,etcd版本号是3.3.25,而kind就是我们自定义的资源类型EtcdCluster,所以它其实就是crd的具体实现,即CR(Custom Resources)。创建这个集群:
过一小段时间后查看pod创建情况,可以看到,集群中的2个节点已经创建出来了:
这时我们进入一个pod,进行etcd数据操作,结果如下,可以集群已经可以使用:
注意:
1.因为我本地环境的限制,kubernetes集群只有2个节点,一个master和一个worker节点,而master节点默认是不能部署pod的,如果想要去除这个污点(Taint),有2个方法,一个就是我之前讲到的使用DaemonSet,另一个就是比较简单,使用下面命令:
#下面的master是主节点名字
而想要让master节点恢复这个污点(Taint),使用如下命令:
2.一开始部署的时候,pod一直创建失败,查看docker日志,发现是nslookupup下面这个域名失败,提示的ip地址是10.96.0.10,这是因为etcd集群中的每个pod都有一个check-dns的容器在做这个事情:
这时我想到api-kubelete中配置的默认集群地址是:
我把上面地址修改成下面地址就可以了
集群原理
首先我们查看这2个pod的详情:
这个pod是etcd的主节点,因为上面有个参数--initial-cluster-state=new,而从节点这个属性的值是existing,如下:
这里介绍一下如果不采用etcd operator,etcd组建集群的过程,这样etcd组建集群就是一个静态的集群。
首先需要启动一个节点,这个节点的initial-cluster-state参数值是new,然后固定了ip地址,比如10.244.1.3,这样initial-cluster参数就是master=http://10.244.1.3:2380。
然后再启动一个etcd节点加入第一个节点就可以了,比如ip是10.244.0.4,这个节点的initial-cluster-state参数值是existing,加入成功后,集群中就有2个节点了,所以initial-cluster参数就是master=http://10.244.1.3:2380,worker1=http://10.244.0.4:2380
之后其他的节点都不断地加入第一个节点。这样这个静态集群就一步一步组建起来了。
而使用etcd operator的优势,就是可以把上面这个静态组建集群的过程自动化,上面两个pod的describe中,我们可以看到都有一个command命令,这个正是etcd operator自动组建集群的过程。下面再次贴一下这2个命令
etcd operator会根据size=2这个参数,动态组建一个etcd集群,首先启动一个节点,用上面的第一个命令,启动成功后,使用上面的第二个命令启动第二个节点,并且加入第一个节点的集群,重复这个过程只要pod数量达到了size的数量。从上面的initial-cluster字段我们能看出,operator组建的集群使用的是域名。
etcd operator创建集群的这个过程,其实就是operator对CRD的控制过程,operator控制的就是EtcdCluster类型的pod数量和EtcdCluster定义的size数量一致。
etcd operator不仅定义了集群的创建,同时也定义了集群的备份和故障恢复,yaml文件在下面2个目录,这个就不深入讲解了,
总结
operator的本质就是创建CRD,然后编写控制器来控制CRD的创建过程。跟StatefulSet的编排不一样的是,StatefulSet的编排pod是通过绑定编号的方式来固定拓扑结构的,而本文中operator的创建过程并没有这样,原因就是etcd operator的编排无非就是新增节点加入集群和删除多的节点,这个拓扑结果etcd内部就可以维护了,绑定编号没有意义。
