在 Operator SDK 中混合实现语言 - Helm、Go、Ansible

问题描述

我需要将多个容器部署到 Kubernetes 集群。目标是自动化 Kafka、Kafka Connect、Postgresql 等的部署。其中一些已经提供了我们可以使用的 Helm 操作符。所以我的问题是,我们能否以某种方式在我们的运营商中使用这些掌舵运营商?如果是这样,最好的方法是什么?

到目前为止我能想到的唯一方法是从部署应用程序中调用 helm 设置控制台命令。 另一种不使用这些 helm 文件方法是在我自己的 operator 中实现每个 operator 的功能,这似乎没有多大意义,因为我需要的东西已经开发出来并且是公开的。

我对操作符开发很陌生,所以如果这是一个愚蠢的问题,请原谅我。

编辑: 运营商的主要目的是部署X数据库。与此同时,我们希望有一个单一的运营商/捆绑包来立即部署整个系统。即使我们对某些容器有额外的任务,使用运算符进行捆绑是否有意义?有了这个,用户将在 yaml 文件中指定:

databases
  - type: "postgres"
    name: "users"
  - type: "postgres"
    name: "purchases"

和 2 个 Postgresql 数据库将被创建。然后可以在其他 yaml 文件中提及这些数据库,或者在同一个 yaml 文件中进一步提及这些数据库。手上的案例:来自数据库的信息将由 Debezium(另一个容器)拉取,因此 Debezium 需要知道它们的地址。所以运营商应该创建一个服务并将服务地址与数据库名称相关联。

这是 ETL 系统的一部分。这个想法是操作员可以通过处理大部分配置来轻松部署整个系统。 考虑到这一点,我们在考虑是否不可能选择现有的 Helm 操作符(或其他类型的操作符)并通过对配置(例如不同数据库的不同端口)进行小的修改来部署它们。

但是在阅读 F1ko 的回复后,我获得了新的视角。也许这对运营商来说是不可能的?

Edit2:edit1 的说明。

解决方法

仅供说明:

  • Helm 是一个包管理器,您可以使用它以捆绑方式将应用程序安装到集群上:它基本上为您提供了所有必要的 YAML,例如配置映射、服务、部署以及其他任何需要以适当的方式启动并运行所需的应用程序。

  • 操作员本质上是一个控制器。在 Kubernetes 中,有许多不同的控制器在您做某事时定义“逻辑”(例如,如果您决定增加 replicas 字段,则复制控制器会添加更多的 Pod 副本)。控制器太多了,无法将它们全部列出并单独运行,这就是为什么它们被编译成一个称为 kube-controller-manager 的二进制文件。 为了更容易区分,定制的控制器被称为操作符。这些操作员只是监视某些“事物”的状态,并在需要时执行操作。大多数情况下,这些“事物”将是 CustomResources (CR),它们本质上是通过应用 CustomResourceDefinitions (CRD) 引入集群的新 Kubernetes 对象。

话虽如此,使用 helm 来部署 Operator 并不少见,但是,请尽量避免使用“helm operator”一词,因为它实际上是指一个非常具体的操作符,可能会在将来导致混淆:{ {3}}

所以我的问题是,我们可以以某种方式在我们的操作符中使用这些 helm 操作符吗?

尽管您可以使用 https://github.com/fluxcd/helm-operator 构建自己的操作员,然后您可以部署或触发其他操作员的某些事件(例如,通过编辑他们的 CRD),但没有理由这样做。

到目前为止,我能想到的唯一方法是从部署应用程序中调用 helm 设置控制台命令。

很可能您正在寻找的是合适的 CI/CD 工作流程。 只需在 operator-sdk 存储库中提交您在 helm install 期间使用的舵图和 values.yaml 文件,并让 CI/CD 工具(例如 Git)将它们部署到您的每次进行新提交时进行集群。

更新:当另一个人编辑了他的问题并发表评论时,我决定更新这篇文章:

operator 的主要目的是部署 X 数据库。与此同时,我们希望有一个单一的运营商/捆绑包,可以立即部署整个系统。

您认为将运算符捆绑到另一个运算符中是否有意义,就像在 Helm 中所做的那样?

不,这根本没有意义。这正是 helm 的用途。使用 helm,您可以捆绑东西,您甚至可以将多个 helm chart 捆绑在一起,这可能是您实际需要的。您可以使用一个舵图将所需的值传递给实际的操作员舵图,从而在多个位置使用类似服务名称的内容。

如果是operator里面的operator,配置operator时还需要单独配置每个子operator吗?

如上所述,这样做没有任何意义,这只是一种过度设计的方法。但是,如果您真的想采用运算符方法,基本上可以采用两种方法:

  • 编写一个操作符,通过更改其他操作符的 CR、ConfigMap 等来配置其他操作符;通过这种方法,您将拥有一个有点轻量级运算符,但是您必须确保它始终与您希望它干扰的所有不同运算符兼容(当它们更改为新的 { {1}} 如果发生重大更改、引入新的 CR 或任何此类内容,您将不得不再次适应)。
  • 将现有运算符的整个逻辑提取到您的运算符中(即重建已经存在的东西);使用这种方法,您将拥有一个庞大的单体应用程序,维护起来将非常痛苦,因为只要上游操作符有更新,您就必须不断更新代码

希望现在很清楚,为“操作”其他操作符构建自己的操作符会带来很多痛苦的依赖,不应该是要走的路。

是否可以部署不同配置的镜像?比如数据库配置了不同的端口?

好的操作符和掌舵图让您可以通过相应的 CR / ConfigMap 或 apiVersion 文件开箱即用,但是,这取决于您将要使用的解决方案。所以总的来说,答案是:是的,如果支持,这是可能的。