【ElasticSearch Operator解析】阅读Kubernetes Operator代码
ElasticSearch运算符是什么?
ElasticSearch Operator是一个针对ElasticSearch的Kubernetes Operator,在Openshift的ClusterLogging功能中作为一个Operator运行。
这个操作符实现了用于自动运维ElasticSearch的操作。
看起来由Openshift社区维护的Github仓库名为openshift/elasticsearch-operator。
OpenShift/Elasticsearch运算员
【補充】Elasticsearch操作员的代码量
有超过2500个Go文件,并且代码超过1000k行。
❯ cloc .
3297 text files.
3170 unique files.
367 files ignored.
github.com/AlDanial/cloc v 1.80 T=10.38 s (283.8 files/s, 117872.8 lines/s)
--------------------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------------------
Go 2539 81218 112652 974429
~
--------------------------------------------------------------------------------
SUM: 2945 89341 127274 1006349
--------------------------------------------------------------------------------
当在vendor目录中以类似的方式进行查看时,我们发现约有950行代码与vendor相关,所以可以说elasticsearch-operator的代码实际上只有大约20k行。
❯ cloc .
3070 text files.
2948 unique files.
343 files ignored.
github.com/AlDanial/cloc v 1.80 T=7.37 s (371.4 files/s, 161408.3 lines/s)
--------------------------------------------------------------------------------
Language files blank comment code
--------------------------------------------------------------------------------
Go 2411 77974 111744 956992
~
--------------------------------------------------------------------------------
SUM: 2738 85146 124716 980068
--------------------------------------------------------------------------------
ElasticSearch的Reconcile处理详解
调和处理摘要
-
- elasticsearchのNode(Elasticsearchクラスタのメンバ)ごとに、正常性確認を行う
-
- Elasticsearch nodeごとにdeploymentを持っていて、そのdeploymentごとにreconcileを行う
- deployment内のpodステータスを確認する際に、コンテナのステータスも確認しreconcileを行っている。
与Reconcile处理相关的代码调用流程。
主要的处理流程可以描述为
-
- controller/erlasticsearch packageのadd()関数
-
- controller packageのreconcileHandler経由でReconcile()関数が呼ばれ
-
- さらにk8shandler内のReconcile()が呼ばれ
- KubernetesのDeployment, Pod, ContainerレベルのReconcileが行われる
在图表1中被标记出的黑色箭头部分。
使用下面的工具绘制了上面的通话图表。因为处理过程很繁重,所以只绘制了上述一张图表,但可以进行交互式处理。
通过调用elasticsearch包内的add()函数,将Controller注册为处理的入口。
看一下add()代码(图2),这是一个函数,通过提供reconciler来添加新的controller。
在这里会生成用于调解ElasticSearch的控制器。
通过这个add()方法添加的controller的Reconcile函数,被称为所谓的调和循环,是Kubernetes和Kubernetes Operator的主要角色。
和解循环
Reconcile()的定义如下所示。
OpenShift的Elasticsearch运营商
正如图1所示,调用Reconcile()函数时,它会调用k8shandler包内的Reconcile()函数。(见图3)
在这个k8shandler.Reconcile()函数中,主要进行基于Kubernetes资源级别的Reconcile操作。
详细来说,
-
- ServiceAccount
-
- RBAC
-
- ConfigMaps
- Prometheus向けのServiceMonitor, PrometheusRule
有诸如此类的事物。
此外,再加上以上所述
-
- Elasticsearch Cluster
- IndexManagement
在代码中定义了关于Reconcile处理的部分。
关于这些,有一个名为CreateOrUpdateHoge()的函数可用,如果资源不存在,则创建它,如果状态不理想,则进行更新处理(Reconcilation Loop)的实现。
创建或更新Hoge郡的相关代码如下所示。
Openshift/ Elasticsearch 厂商
在这里,我们决定更深入地探索主要的Reconcile处理函数CreateOrUpdateElasticsearchCluster()。
核实ElasticSearch的调和处理CreateOrUpdateElasticsearchCluster()的实现
正如前面所述,CreateOrUpdateElasticsearchCluster()是一个用于保持ElasticSearch处于理想状态的函数。
如果你对具体的处理方法感兴趣,可以从以下的步骤进行追踪。
Openshift的elasticsearch-operator
这里需要关注的是当ElasticSearch出现故障时,我们如何对Pod进行调和(Reconcile)。
通过在k8shandler包的cluster.go文件中监视ScheduledForUpgrade,将需要更新的节点(指elasticsearch集群的成员,而不是k8s节点)作为upgradeNodes存储起来。(ScheduledForUpgrade如何更新将在后述中补充说明)
OpenShift/Elasticsearch运算符
在上述中,被识别为upgradeNode的节点将应用协调过程于k8shandler.UpgradeStatus()中。
在Reconcile处理的内部,确认具体的实现。
通过在UpdateClusterStatus()中调用status.go中的updateNodeConditions()来进入每个elasticsearch Node的reconcile过程。
OpenShift的Elasticsearch运算符
确认Pod的正常性
请确认Pod已经安排好了日程。
如果Pod已经被调度,同时Pod的状态为False的情况下,将Pod标记为不可调度。
如果unschedulable标志被设置,我们将在后续处理中检查Pod内的容器状态。
以下是相对应的代码
Openshift的elasticsearch-operator
查询Pod内的容器状态
首先,我们需要检查Pod中elasticsearch容器的状态,它可能是等待状态或已终止状态。
在这种情况下,通过调用updatePodNotReadyCondition()函数,我们为Pod添加了准确的原因和消息,表明它已经损坏了。
我也在检查另一个代理容器。
开放移植性/弹性搜索操作员
从磁盘使用率的角度进行正常性确认
完成容器正常性检查后,需要进行磁盘使用量的确认。
检查磁盘使用量是否超过阈值,以及是否被识别为磁盘水印高或低。
Openshift的elasticsearch-operator
总结
-
- Openshiftで用いられるElastichSearch Operatorの役割について、PodのReconcile部分に焦点を当てて実装を確認した。
-
- 実際のReconcile部分に限っていうとElasticsearch特有という部分は余り目立たず、他のOperatorのコードを読む上でも同様に読み進めるための材料として読むことは有用と感じる。
- Operatorhub.ioにおいてelasticsearch-operatorは公開されておらず、”Elastic Cloud on Kubernetes” Operatorが公開されているため、こちらとの関連やその差分などについても考察の余地があるが、OperatorHub.ioに登録されている方がよりデファクトであると現時点では考えられる。そのため、本記事で紹介したelasticsearch-operatorはOpenshiftに特化した内容になっていると考えるのが妥当である。
可供参考的资料
- Elasticsearch OperatorのGoDoc
elasticsearch-operator – 简化中文文档
- openshift/elasticsearch-operator Github
- openshiftのcluster-loggingのリポジトリ
【補充】ScheduledForUpgrade的更新方式
首先,在k8shandler包的deployment.go文件中监视deployment的状态。
开放移动/弹性搜索运营商
通过node.isChanged()方法,通过纯粹地比较部署的desired和current,判断是否需要进行更新。
如果node.isChanged()返回true,通过设置api.ElasticsearchNodeStatus.UpgradeStatus.ScheduledForUpgrade标志,在reconcilationLoop中创建了一个触发重新启动的机制。