×

为了确保您的 Operator 在 OpenShift Container Platform 集群的高可用性 (HA) 模式和非 HA 模式下都能正常运行,您可以使用 Operator SDK 检测集群的基础设施拓扑,并设置适合集群拓扑的资源需求。

OpenShift Container Platform 集群可以配置为高可用性 (HA) 模式(使用多个节点)或非 HA 模式(使用单个节点)。单节点集群(也称为单节点 OpenShift)可能具有更保守的资源约束。因此,重要的是,安装在单节点集群上的 Operator 能够相应地进行调整,并仍然能够正常运行。

通过访问 OpenShift Dedicated 中提供的集群高可用性模式 API,Operator 作者可以使用 Operator SDK 使其 Operator 能够检测集群的基础设施拓扑(HA 或非 HA 模式)。可以开发使用检测到的集群拓扑来自动切换资源需求的自定义 Operator 逻辑,包括 Operator 本身以及其管理的任何 Operand 或工作负载,以选择最适合拓扑的配置文件。

Red Hat 支持的 Operator SDK CLI 工具版本(包括 Operator 项目的相关脚手架和测试工具)已弃用,并计划在未来版本的 OpenShift Dedicated 中删除。Red Hat 将在此版本的生命周期内为此功能提供错误修复和支持,但此功能将不再接收增强功能,并将从未来的 OpenShift Dedicated 版本中删除。

不建议使用 Red Hat 支持的 Operator SDK 版本创建新的 Operator 项目。拥有现有 Operator 项目的 Operator 作者可以使用随 OpenShift Dedicated 发布的 Operator SDK CLI 工具版本来维护其项目并创建针对较新版本的 OpenShift Dedicated 的 Operator 版本。

以下与 Operator 项目相关的基础镜像被弃用。这些基础镜像的运行时功能和配置 API 仍然支持错误修复和解决 CVE。

  • 基于 Ansible 的 Operator 项目的基础镜像

  • 基于 Helm 的 Operator 项目的基础镜像

有关不受支持的社区维护的 Operator SDK 版本的信息,请参阅 Operator SDK (Operator Framework)

关于集群高可用性模式 API

OpenShift Dedicated 提供了一个集群高可用性模式 API,Operator 可以使用它来帮助检测基础设施拓扑。基础设施 API 保存有关基础设施的集群范围信息。如果 Operator Lifecycle Manager (OLM) 管理的 Operator 需要根据高可用性模式以不同的方式配置 Operand 或管理的工作负载,则可以使用基础设施 API。

在基础设施 API 中,infrastructureTopology 状态表示对不在控制平面节点上运行的基础设施服务的期望,通常由节点选择器为非masterrole 值指示。controlPlaneTopology 状态表示对通常在控制平面节点上运行的 Operand 的期望。

两种状态的默认设置均为HighlyAvailable,表示 Operator 在多个节点集群中的行为。SingleReplica 设置用于单节点集群(也称为单节点 OpenShift),并指示 Operator 不应将其 Operand 配置为高可用性操作。

OpenShift Dedicated 安装程序根据集群创建时的副本数量,按照以下规则设置controlPlaneTopologyinfrastructureTopology状态字段。

  • 当控制平面副本数量小于3时,controlPlaneTopology状态设置为SingleReplica。否则,设置为HighlyAvailable

  • 当工作节点副本数量为0时,控制平面节点也配置为工作节点。因此,infrastructureTopology状态将与controlPlaneTopology状态相同。

  • 当工作节点副本数量为1时,infrastructureTopology设置为SingleReplica。否则,设置为HighlyAvailable

Operator 项目中的 API 使用示例

作为 Operator 作者,您可以使用正常的 Kubernetes 结构和controller-runtime库更新您的 Operator 项目以访问 Infrastructure API,如下例所示。

controller-runtime 库示例
// Simple query
 nn := types.NamespacedName{
 Name: "cluster",
 }
 infraConfig := &configv1.Infrastructure{}
 err = crClient.Get(context.Background(), nn, infraConfig)
 if err != nil {
 return err
 }
 fmt.Printf("using crclient: %v\n", infraConfig.Status.ControlPlaneTopology)
 fmt.Printf("using crclient: %v\n", infraConfig.Status.InfrastructureTopology)
Kubernetes 结构示例
operatorConfigInformer := configinformer.NewSharedInformerFactoryWithOptions(configClient, 2*time.Second)
 infrastructureLister = operatorConfigInformer.Config().V1().Infrastructures().Lister()
 infraConfig, err := configClient.ConfigV1().Infrastructures().Get(context.Background(), "cluster", metav1.GetOptions{})
 if err != nil {
 return err
 }
// fmt.Printf("%v\n", infraConfig)
 fmt.Printf("%v\n", infraConfig.Status.ControlPlaneTopology)
 fmt.Printf("%v\n", infraConfig.Status.InfrastructureTopology)