5.10. 高可用性或单节点集群检测和支持

OpenShift Container Platform 集群能够以高可用性 (HA) 模式配置,该模式使用多个节点,或者在非 HA 模式中使用单一节点。单节点集群(也称为单节点 OpenShift)可能会有更保守的资源约束。因此,在单一节点集群中安装 Operator 务必要进行相应调整,并且仍然运行良好。

通过访问 OpenShift Container Platform 中提供的集群高可用性模式 API,Operator 作者可使用 Operator SDK 来让 Operator 检测集群的基础架构拓扑,不论是 HA 模式还是非 HA 模式。可以开发使用检测到的集群拓扑的自定义 Operator 逻辑,以自动将 Operator 及其管理的任何 Operands 或工作负载的资源要求切换到最适合拓扑的配置集。

5.10.1. 关于集群高可用性模式 API

OpenShift Container Platform 提供了一个集群高可用性模式 API,可供 Operator 用于帮助检测基础架构拓扑。基础架构 API 包含有关基础架构的集群范围信息。由 Operator Lifecycle Manager (OLM) 管理的操作员如果需要根据高可用性模式以不同的方式配置 Operand 或受管理的工作负载,则可以使用 Infrastructure API。

在 Infrastructure API 中,infrastructureTopology 状态表达了对未在 control plane 节点上运行的基础架构服务的期望,通常由节点选择器针对 master 以外的 role 值表示。controlPlaneTopology 状态表达了通常在 control plane 节点上运行的 Operand 的预期。

两个状态的默认设置都是 HighlyAvailable,它代表 Operator 在多个节点集群中具有的行为。SingleReplica 设置在单节点集群中(也称为单节点 OpenShift)中使用,表示 Operator 不应该为高可用性操作配置 Operands。

OpenShift Container Platform 安装程序根据以下规则,根据集群创建的副本数设置 controlPlaneTopologyinfrastructureTopology 状态字段:

  • 当 control plane 副本数小于 3 时,controlPlaneTopology 状态被设置为 SingleReplica。否则,它被设置为 HighlyAvailable
  • 当 worker 副本数为 0 时,control plane 节点也会配置为 worker。因此,infrastructureTopology 状态将与 controlPlaneTopology 状态相同。
  • 当 worker 副本数为 1 时,infrastructureTopology 被设置为 SingleReplica。否则,它被设置为 HighlyAvailable

5.10.2. 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)