GSoC 2020-构建集群附加组件的运营商

作者 :Somtochi Onyekwere

介绍

Google Summer of Code 是一项全球计划,旨在向学生介绍开源。在夏季,学生会与开放源代码组织进行配对,与他们合作三个月。

我叫Somtochi Onyekwere,来自奥韦里联邦技术大学(尼日利亚),今年,我有幸与Kubernetes(在CNCF组织下)一起工作,这使我度过了一个非常棒的暑假,学习,与之互动并与之互动。社区。

具体来说,我从事 集群插件:打包所有东西! 项目。该项目侧重于构建用于更好地管理各种集群插件的运营商,扩展了用于构建这些运营商的工具,并使这些运营商的创建过程更加顺利。

背景

在过去的几年中,Kubernetes在蓬勃发展的社区和众多的贡献者中取得了长足的进步。代码库逐渐从所有代码都驻留在其中的整体结构中移开。 kubernetes / kubernetes 存储库被拆分为多个子项目。集群附件的部分重点是使这些子项目中的一些子项目以易于组装,自我监控,自我修复和Kubernetes原生的方式一起工作。它使他们能够无缝地工作,而无需人工干预。

社区正在探索使用运营商作为监视集群中各种资源并适当管理这些资源的机制。除此之外,它还提供了自我修复功能,它是一种Kubernetes原生模式,可以对这些插件的最佳工作方式进行编码并对其进行适当的管理。

什么是集群插件?集群插件是资源的集合(如服务和部署),这些资源用于为Kubernetes集群提供其他功能。它们的范围从简单到Kubernetes仪表板(用于可视化)到复杂的工具,如Calico(用于联网)。这些插件对于集群中运行的不同应用程序以及集群本身至关重要。插件操作员提供了一种更好的方式来管理这些插件并了解组成该插件的各种资源的运行状况和状态。您可以在此获得更深入的概述 文章 .

运算符是具有自定义资源定义的自定义控制器,该资源定义对特定于应用程序的知识进行编码,并用于管理复杂的有状态应用程序。这是一种被广泛接受的模式。通过操作员管理插件,这些操作员编码了有关如何最好地使用插件的知识,在设置易于遵循和扩展的标准的同时,引入了许多优势。这个 文章 很好地解释了运算符。

插件操作员可以解决很多问题,但是他们面临挑战。那些下 集群附件项目 遗失了部分,仍然是概念的证明。为操作员生成RBAC配置是很痛苦的,有时会给操作员太多的特权。操作员的扩展性不是很好,因为它仅从本地文件系统或HTTP服务器中提取清单,并且许多简单的插件都在生成相同的代码。 我整个暑假都在研究这些问题,以崭新的眼光看待它们,并提出了已知和未知问题的解决方案。

kubebuilder 声明式模式的各种添加

kubebuilder 声明式模式 (从此处称为KDP)存储库是附加组件专用工具的额外层,位于 kubebuilder SDK that is enabled by passing the experimental --pattern=addon flag to kubebuilder create command. Together, they create the base code for the addon operator. During the internship, I worked on a couple of features in KDP and 集群附件 .

操作员版本检查

Enabling version checks for operators helped in making upgrades/downgrades safer to different versions of the addon, even though the operator had complex logic. It is a way of matching the version of an addon to the version of the operator that knows how to manage it well. Most addons have different versions and these versions might need to be managed differently. This feature checks the custom resource for the addons.k8s.io/min-operator-version annotation which states the minimum operator version that is needed to manage the version against the version of the operator. If the operator version is below the minimum version required, the operator pauses with an error telling the user that the version of the operator is too low. This helps to ensure that the correct operator is being used for the addon.

Git存储库,用于存储清单

以前,仅支持用于存储清单的本地文件目录和HTTPS存储库。使插件操作员的创建者能够将清单存储在GitHub存储库中,可以加快开发和版本控制。启动控制器时,可以传递一个标志来指定您的channels目录的位置。 Channels目录包含不同版本的清单,控制器从该目录中提取清单并将其应用于集群。在实习期间,我将其扩展到包括Git存储库。

暂时禁用对帐的注释

的 reconciliation loop that ensures that the desired state matches the actual state prevents modification of objects in the cluster. This makes it hard to experiment or investigate what might be wrong in the cluster as any changes made are promptly reverted. I resolved this by allowing users to place an addons.k8s.io/ignore annotation on the resource that they don’t want the controller to reconcile. 的 controller checks for this annotation and doesn’t reconcile that object. To resume reconciliation, the annotation can be removed from the resource.

kubebuilder 声明式模式中的非结构化支持

我研究的操作员之一是通用控制器,该控制器可以管理多个集群插件,而无需额外配置。为此,操作员无法使用特定类型,因此需要kubebuilder-declarative-repo支持使用 非结构化 type. 的 re were various functions in the kubebuilder 声明式模式 that couldn’t handle this type and returned an error if the object passed in was not of type addonsv1alpha1.CommonObject. 的 functions were modified to handle both 非结构化 and addonsv1alpha.CommonObject.

工具和CLI程序

我还编写了一些命令行程序,这些程序可用来简化与插件操作符的工作。他们中的大多数人都在addon运算符之外使用它们,因为他们试图解决在使用Kubernetes时可能出现在任何地方的特定问题。我鼓励你 去看一下 当你有机会的时候!

RBAC发电机

运营商最担心的问题之一是RBAC。您必须手动浏览清单并为每个资源添加RBAC规则,因为在集群内运行时,它需要具有RBAC权限才能创建,获取,更新和删除清单中的资源。建立 RBAC发电机 automated the process of writing the RBAC roles and role bindings. 的 function of the RBAC发电机 is simple. It accepts the file name of the manifest as a flag. 的 n, it parses the manifest and gets the API group and resource name of the resources and adds it to a role. It outputs the role and role binding to stdout or a file if the --out flag is parsed.

Additionally, the tool enables you to split the RBAC by separating the cluster roles in the manifest. This lessened the security concern of an operator being over-privileged as it needed to have all the permissions that the clusterrole has. If you want to apply the clusterrole yourself and not give the operator these permissions, you can pass in a --supervisory boolean flag so that the generator does not add these permissions to the role. 的 CLI program resides 这里 .

Kubectl所有者参考

一目了然地发现哪些对象是由插件自定义资源创建的。这个kubectl插件通过显示资源中拥有ownerref的集群中的所有对象来减轻痛苦。您只需将资源的种类和名称作为参数传递给程序,它就会检查群集中的对象,并给出此类对象的种类,名称和名称空间。通过传入自定义资源的名称和种类,获得控制器正在协调的所有对象的一般概述可能会很有用。 CLI程序驻留 这里 .

附加运算符

要完全理解插件操作符并更改其创建方式,您必须尝试创建和使用它们。暑假的一部分时间是为一些受欢迎的插件(例如Kubernetes仪表板,法兰绒,NodeLocalDNS等)构建操作员。请检查 集群附件 不同插件操作员的存储库。在本节中,我将重点介绍一个与其他内容略有不同的内容。

通用控制器

通用控制器可以在不需要太多配置的插件之间共享。这可以最大程度地减少群集上的资源消耗,因为它减少了需要运行的控制器的数量。同样,除了构建自己的运算符之外,您还可以使用通用控制器,只要感觉到需求增长并且需要更复杂的运算符,就可以始终使用kubebuilder来编写代码,然后从通用运算符停止的地方继续执行。要使用通用控制器,您可以使用此工具生成CustomResourceDefinition(CRD)( 通用插件 )。您传递通道目录的种类,组和位置(它也可以是Git存储库!)。该工具为您生成-CRD,RBAC清单和两个自定义资源。

流程如下:

该工具创建:

  1. 您的插件的CRD
  2. CustomResourceDefinitions的RBAC规则
  3. RBAC适用清单的规则
  4. 插件的自定义资源
  5. 通用自定义资源

通用自定义资源如下所示:

apiVersion: addons.x-k8s.io/v1alpha1
kind: Generic
metadata:
 	name: generic-sample
spec:
  objectKind:
  kind: NodeLocalDNS
  version: "v1alpha1"
  group: addons.x-k8s.io
channel: "../nodelocaldns/channels"

应用这些清单,但确保在CR之前应用CRD。 然后,在您的计算机或群集中运行通用控制器。

如果您有兴趣建立操作员,请签出 本指南 .

相关连结

进一步的工作

在GSoC期间,肯定在集群附加组件上做了很多工作。但是我们需要更多的人来构建操作员并在集群中使用它们。我们需要在社区中得到更广泛的采用。为您喜欢的插件构建操作符,并告诉我们它的运行方式以及是否有任何问题。看看这个 自述文件 开始。

升值

我真的很想感谢我的导师 贾斯汀·圣芭芭拉(Justin Santa Barbara) (Google)和 雷·卡皮利 (编织)。我的实习很棒,因为他们很棒。他们为指导的方式设定了黄金标准。它们易于访问,并且随时可用以清除任何混乱。我认为我最喜欢的是他们不只是提出任务,而是就什么是错误的以及可以改进的地方进行了公开讨论。他们真的是最好的,我希望我能再次与他们合作! 另外,我想对 卢博米尔·伊万诺夫 用于审查此博客文章!

结论

到目前为止,我已经学到了很多有关Go,Kubernetes的内部知识以及操作员的知识。最后,我想鼓励人们不管您的经验水平如何,都为开源做出贡献(尤其是Kubernetes :)。对我来说,这是一次全面的体验,我开始爱上社区。这是一个伟大的倡议,也是学习和结识真棒人的好方法。特别鸣谢Google组织此计划。

如果您对集群插件感兴趣并在插件操作符上找到更多信息,欢迎加入我们在Kubernetes上的松弛频道 #cluster-addons.


Somtochi Onyekwere 是一位软件工程师,喜欢为开源做出贡献并探索云原生解决方案。