2.4. Operator Lifecycle Manager (OLM)

2.4.1. Operator Lifecycle Manager 概念和资源

本指南概述了 OpenShift Container Platform 中 Operator Lifecycle Manager (OLM) 背后的概念。

2.4.1.1. Operator Lifecycle Manager 是什么?

Operator Lifecycle Manager(OLM)可帮助用户安装、更新和管理所有 Kubernetes 原生应用程序(Operator)以及在 OpenShift Container Platform 集群中运行的关联服务的生命周期。它是 Operator Framework 的一部分,后者是一个开源工具包,用于以有效、自动化且可扩展的方式管理 Operator。

图 2.2. Operator Lifecycle Manager 工作流

OLM 工作流

OLM 默认在 OpenShift Container Platform 4.12 中运行,辅助集群管理员对集群上运行的 Operator 进行安装、升级和授予访问权。OpenShift Container Platform Web 控制台提供一些管理界面,供集群管理员安装 Operator,以及为特定项目授权以便使用集群上的可用 Operator 目录。

开发人员通过自助服务体验,无需成为相关问题的专家也可自由置备和配置数据库、监控和大数据服务的实例,因为 Operator 已将相关知识融入其中。

2.4.1.2. OLM 资源

以下自定义资源定义 (CRD) 由 Operator Lifecycle Manager (OLM) 定义和管理:

表 2.1. 由 OLM 和 Catalog Operator 管理的 CRD

资源短名称描述

ClusterServiceVersion (CSV)

csv

应用程序元数据。例如:名称、版本、图标、所需资源。

CatalogSource

catsrc

定义应用程序的 CSV、CRD 和软件包存储库。

Subscription

sub

通过跟踪软件包中的频道来保持 CSV 最新。

InstallPlan

ip

为自动安装或升级 CSV 而需创建的资源的计算列表。

OperatorGroup

og

将部署在同一命名空间中的所有 Operator 配置为 OperatorGroup 对象,以便在一系列命名空间或集群范围内监视其自定义资源 ( CR)。

OperatorConditions

-

在 OLM 和它管理的 Operator 之间创建通信频道。操作员可以写入 Status.Conditions 数组,以向 OLM 通报复杂状态。

2.4.1.2.1. 集群服务版本

集群服务版本 (CSV) 代表 OpenShift Container Platform 集群中运行的 Operator 的特定版本。它是一个利用 Operator 元数据创建的 YAML 清单,可辅助 Operator Lifecycle Manager (OLM) 在集群中运行 Operator。

OLM 需要与 Operator 相关的元数据,以确保它可以在集群中安全运行,并在发布新版 Operator 时提供有关如何应用更新的信息。这和传统的操作系统的打包软件相似;可将 OLM 的打包步骤认为是制作 rpmdebapk 捆绑包的阶段。

CSV 中包含 Operator 容器镜像附带的元数据,用于在用户界面填充名称、版本、描述、标签、存储库链接和徽标等信息。

此外,CSV 还是运行 Operator 所需的技术信息来源,例如其管理或依赖的自定义资源 (CR)、RBAC 规则、集群要求和安装策略。此信息告诉 OLM 如何创建所需资源并将 Operator 设置为部署。

2.4.1.2.2. 目录源

catalog source 代表元数据存储,通常通过引用存储在容器 registry 中的 index image。Operator Lifecycle Manager (OLM) 查询目录源来发现和安装 Operator 及其依赖项。OpenShift Container Platform Web 控制台中的 OperatorHub 也会显示由目录源提供的 Operator。

提示

集群管理员可以使用 web 控制台中的 AdministrationCluster SettingsConfigurationOperatorHub 页面查看集群中已启用的目录源提供的 Operator 的完整列表。

CatalogSourcespec 指明了如何构造 pod,以及如何与服务于 Operator Registry gRPC API 的服务进行通信。

例 2.8. CatalogSource 对象示例

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  generation: 1
  name: example-catalog 1
  namespace: openshift-marketplace 2
  annotations:
    olm.catalogImageTemplate: 3
      "quay.io/example-org/example-catalog:v{kube_major_version}.{kube_minor_version}.{kube_patch_version}"
spec:
  displayName: Example Catalog 4
  image: quay.io/example-org/example-catalog:v1 5
  priority: -400 6
  publisher: Example Org
  sourceType: grpc 7
  grpcPodConfig:
    securityContextConfig: <security_mode> 8
    nodeSelector: 9
      custom_label: <label>
    priorityClassName: system-cluster-critical 10
    tolerations: 11
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoSchedule"
  updateStrategy:
    registryPoll: 12
      interval: 30m0s
status:
  connectionState:
    address: example-catalog.openshift-marketplace.svc:50051
    lastConnect: 2021-08-26T18:14:31Z
    lastObservedState: READY 13
  latestImageRegistryPoll: 2021-08-26T18:46:25Z 14
  registryService: 15
    createdAt: 2021-08-26T16:16:37Z
    port: 50051
    protocol: grpc
    serviceName: example-catalog
    serviceNamespace: openshift-marketplace
1
CatalogSource 对象的名称。此值也用作在请求的命名空间中创建相关 pod 的名称的一部分。
2
要创建目录的命名空间。要使目录在所有命名空间中都可用,请将此值设置为 openshift-marketplace。默认红帽提供的目录源也使用 openshift-marketplace 命名空间。否则,将值设置为特定命名空间,使 Operator 仅在该命名空间中可用。
3
可选:为避免集群升级可能会使 Operator 安装处于不受支持的状态或没有持续更新路径,您可以启用自动更改 Operator 目录的索引镜像版本作为集群升级的一部分。

olm.catalogImageTemplate 注解设置为索引镜像名称,并使用一个或多个 Kubernetes 集群版本变量,如为镜像标签构建模板时所示。该注解会在运行时覆盖 spec.image 字段。如需了解更多详细信息,请参阅"用于自定义目录源的镜像模板"。

4
在 Web 控制台和 CLI 中显示目录的名称。
5
目录的索引镜像。在使用 olm.catalogImageTemplate 注解时,也可以省略,该注解会在运行时设置 pull spec。
6
目录源的权重。OLM 在依赖项解析过程中使用权重进行优先级排序。权重越高,表示目录优先于轻量级目录。
7
源类型包括以下内容:
  • 带有镜像引用的 grpc:OLM 拉取镜像并运行 pod,为兼容的 API 服务。
  • 带有地址字段的 grpc:OLM 会尝试联系给定地址的 gRPC API。在大多数情况下不应该使用这种类型。
  • configmap:OLM 解析配置映射数据,并运行一个可以为其提供 gRPC API 的 pod。
8
指定 legacyrestricted 的值。如果没有设置该字段,则默认值为 legacy。在以后的 OpenShift Container Platform 发行版本中,计划默认值为 restricted。如果您的目录无法使用 restricted 权限运行,建议您手动将此字段设置为 legacy
9
可选: 对于 grpc 类型目录源,请覆盖在 spec.image 中提供内容的 pod 的默认节点选择器(如果定义)。
10
可选: 对于 grpc 类型目录源,请覆盖在 spec.image 中提供内容的 pod 的默认优先级类名称(如果定义)。Kubernetes 默认提供 system-cluster-criticalsystem-node-critical 优先级类。将字段设置为空 ("") 可为 pod 分配默认优先级。可以手动定义其他优先级类。
11
可选: 对于 grpc 类型目录源,请覆盖 spec.image 中提供内容的 pod 的默认容限(如果定义)。
12
在指定的时间段内自动检查新版本以保持最新。
13
目录连接的最后观察到状态。例如:
  • READY :成功建立连接。
  • CONNECTING :连接正在尝试建立。
  • TRANSIENT_FAILURE :尝试建立连接(如超时)时发生了临时问题。该状态最终将切回到 CONNECTING,然后重试。

如需了解更多详细信息,请参阅 gRPC 文档中的连接状态

14
存储目录镜像的容器注册表最近轮询的时间,以确保镜像为最新版本。
15
目录的 Operator Registry 服务的状态信息。

在订阅中引用 CatalogSource 对象的名称会指示 OLM 搜索查找请求的 Operator 的位置:

例 2.9. 引用目录源的 Subscription 对象示例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: example-operator
  namespace: example-namespace
spec:
  channel: stable
  name: example-operator
  source: example-catalog
  sourceNamespace: openshift-marketplace
2.4.1.2.2.1. 自定义目录源的镜像模板

与底层集群的 Operator 兼容性可以通过目录源以各种方式表示。其中一种用于红帽默认提供的目录源的方法是识别为特定平台发行版本(如 OpenShift Container Platform 4.12)特别创建的索引镜像的镜像标签。

在集群升级过程中,默认红帽提供的目录源的索引镜像标签由 Cluster Version Operator (CVO) 自动更新,以便 Operator Lifecycle Manager (OLM) 拉取目录的更新版本。例如,在从 OpenShift Container Platform 4.11 升级到 4.12 过程中,redhat-operators 目录的 CatalogSource 对象中的 spec.image 字段被更新:

registry.redhat.io/redhat/redhat-operator-index:v4.11

改为:

registry.redhat.io/redhat/redhat-operator-index:v4.12

但是,CVO 不会自动更新自定义目录的镜像标签。为确保用户在集群升级后仍然安装兼容并受支持的 Operator,还应更新自定义目录以引用更新的索引镜像。

从 OpenShift Container Platform 4.9 开始,集群管理员可以在自定义目录的 CatalogSource 对象中添加 olm.catalogImageTemplate 注解到包含模板的镜像引用。模板中支持使用以下 Kubernetes 版本变量:

  • kube_major_version
  • kube_minor_version
  • kube_patch_version
注意

您必须指定 Kubernetes 集群版本,而不是 OpenShift Container Platform 集群版本,因为后者目前不适用于模板。

如果您已创建并推送了带有指定更新 Kubernetes 版本标签的索引镜像,设置此注解可使自定义目录中的索引镜像版本在集群升级后自动更改。注解值用于设置或更新 CatalogSource 对象的 spec.image 字段中的镜像引用。这有助于避免集群升级,从而避免在不受支持的状态或没有持续更新路径的情况下安装 Operator。

重要

您必须确保集群可在集群升级时访问带有更新标签的索引镜像(无论存储在哪一 registry 中)。

例 2.10. 带有镜像模板的目录源示例

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  generation: 1
  name: example-catalog
  namespace: openshift-marketplace
  annotations:
    olm.catalogImageTemplate:
      "quay.io/example-org/example-catalog:v{kube_major_version}.{kube_minor_version}"
spec:
  displayName: Example Catalog
  image: quay.io/example-org/example-catalog:v1.25
  priority: -400
  publisher: Example Org
注意

如果设置了 spec.image 字段和 olm.catalogImageTemplate 注解,则 spec.image 字段会被注解中的解析值覆盖。如果注解没有解析为可用的 pull spec,目录源会回退到设置的 spec.image 值。

如果没有设置 spec.image 字段,且注解没有解析为可用的 pull spec,OLM 会停止目录源的协调,并将其设置为人类可读的错误条件。

对于使用 Kubernetes 1.25 的 OpenShift Container Platform 4.12 集群,上例中的 olm.catalogImageTemplate 注解会解析为以下镜像引用:

quay.io/example-org/example-catalog:v1.25

对于将来的 OpenShift Container Platform 版本,您可以为自定义目录创建更新的索引镜像,该镜像以更新的 Kubernetes 版本为目标,供以后的 OpenShift Container Platform 版本使用。升级前设置了 olm.catalogImageTemplate 注解,将集群升级到更新的 OpenShift Container Platform 版本也会自动更新目录的索引镜像。

2.4.1.2.2.2. 目录健康要求

集群上的 Operator 目录可从安装解析视角进行交换; Subscription 对象可能会引用特定目录,但依赖项会根据集群中的所有目录解决。

例如,如果 Catalog A 不健康,则引用 Catalog A 的订阅可能会解析 Catalog B 中的依赖项,集群管理员可能还没有预期,因为 B 通常具有比 A 更低的目录优先级。

因此,OLM 要求所有具有给定全局命名空间的目录(例如,默认的 openshift-marketplace 命名空间或自定义全局命名空间)都健康。当目录不健康时,其共享全局命名空间中的所有 Operator 或更新操作都将因为 CatalogSourcesUnhealthy 条件而失败。如果这些操作处于不健康状态,OLM 可能会做出对集群管理员意外的解析和安装决策。

作为集群管理员,如果您观察一个不健康的目录,并希望将目录视为无效并恢复 Operator 安装,请参阅"删除自定义目录"或"Disabling the default OperatorHub 目录源"部分,以了解有关删除不健康目录的信息。

2.4.1.2.3. 订阅

订阅 (由一个 Subscription 对象定义)代表安装 Operator 的意图。它是将 Operator 与目录源关联的自定义资源。

Subscription 描述了要订阅 Operator 软件包的哪个频道,以及是自动还是手动执行更新。如果设置为自动,订阅可确保 Operator Lifecycle Manager(OLM)自动管理并升级 Operator,以确保集群中始终运行最新版本。

Subscription 对象示例

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: example-operator
  namespace: example-namespace
spec:
  channel: stable
  name: example-operator
  source: example-catalog
  sourceNamespace: openshift-marketplace

Subscription 对象定义了 Operator 的名称和命名空间,以及从中查找 Operator 数据的目录。频道(如 alphabetastable )可帮助确定应从目录源安装哪些 Operator 流。

订阅中的频道名称可能会因 Operator 而异,但应遵守给定 Operator 中的常规约定。例如,频道名称可能会遵循 Operator 提供的应用程序的次发行版本更新流(1.21.3)或发行的频率(stablefast)。

除了可从 OpenShift Container Platform Web 控制台轻松查看外,还可以通过检查相关订阅的状态来识别是否有较新版本的 Operator 可用。与 currentCSV 字段关联的值是 OLM 已知的最新版本,而 installedCSV 是集群中安装的版本。

2.4.1.2.4. 安装计划

安装计划(由一个 InstallPlan 对象定义) 描述了 Operator Lifecycle Manager (OLM) 为安装或升级到 Operator 的特定版本而创建的一组资源。该版本由集群服务版本 (CSV) 定义。

要安装 Operator、集群管理员或被授予 Operator 安装权限的用户,必须首先创建一个 Subscription 对象。订阅代表了从目录源订阅 Operator 可用版本流的意图。然后,订阅会创建一个 InstallPlan 对象来方便为 Operator 安装资源。

然后,根据以下批准策略之一批准安装计划:

  • 如果订阅的 spec.installPlanApproval 字段被设置为 Automatic,则会自动批准安装计划。
  • 如果订阅的 spec.installPlanApproval 字段被设置为 Manual,则安装计划必须由集群管理员或具有适当权限的用户手动批准。

批准安装计划后,OLM 会创建指定的资源,并在订阅指定的命名空间中安装 Operator。

例 2.11. InstallPlan 对象示例

apiVersion: operators.coreos.com/v1alpha1
kind: InstallPlan
metadata:
  name: install-abcde
  namespace: operators
spec:
  approval: Automatic
  approved: true
  clusterServiceVersionNames:
    - my-operator.v1.0.1
  generation: 1
status:
  ...
  catalogSources: []
  conditions:
    - lastTransitionTime: '2021-01-01T20:17:27Z'
      lastUpdateTime: '2021-01-01T20:17:27Z'
      status: 'True'
      type: Installed
  phase: Complete
  plan:
    - resolving: my-operator.v1.0.1
      resource:
        group: operators.coreos.com
        kind: ClusterServiceVersion
        manifest: >-
        ...
        name: my-operator.v1.0.1
        sourceName: redhat-operators
        sourceNamespace: openshift-marketplace
        version: v1alpha1
      status: Created
    - resolving: my-operator.v1.0.1
      resource:
        group: apiextensions.k8s.io
        kind: CustomResourceDefinition
        manifest: >-
        ...
        name: webservers.web.servers.org
        sourceName: redhat-operators
        sourceNamespace: openshift-marketplace
        version: v1beta1
      status: Created
    - resolving: my-operator.v1.0.1
      resource:
        group: ''
        kind: ServiceAccount
        manifest: >-
        ...
        name: my-operator
        sourceName: redhat-operators
        sourceNamespace: openshift-marketplace
        version: v1
      status: Created
    - resolving: my-operator.v1.0.1
      resource:
        group: rbac.authorization.k8s.io
        kind: Role
        manifest: >-
        ...
        name: my-operator.v1.0.1-my-operator-6d7cbc6f57
        sourceName: redhat-operators
        sourceNamespace: openshift-marketplace
        version: v1
      status: Created
    - resolving: my-operator.v1.0.1
      resource:
        group: rbac.authorization.k8s.io
        kind: RoleBinding
        manifest: >-
        ...
        name: my-operator.v1.0.1-my-operator-6d7cbc6f57
        sourceName: redhat-operators
        sourceNamespace: openshift-marketplace
        version: v1
      status: Created
      ...
2.4.1.2.5. operator 组

OperatorGroup 资源定义的 Operator 组,为 OLM 安装的 Operator 提供多租户配置。Operator 组选择目标命名空间,在其中为其成员 Operator 生成所需的 RBAC 访问权限。

这一组目标命名空间通过存储在 CSV 的 olm.targetNamespaces 注解中的以逗号分隔的字符串来提供。该注解应用于成员 Operator 的 CSV 实例,并注入它们的部署中。

其他资源

2.4.1.2.6. Operator 条件

作为管理 Operator 生命周期的角色的一部分,Operator Lifecycle Manager(OLM)从定义 Operator 的 Kubernetes 资源状态中推断 Operator 状态。虽然此方法提供了一定程度的保证来确定 Operator 处于给定状态,但在有些情况下,Operator 可能需要直接向 OLM 提供信息,而这些信息不能被推断出来。这些信息可以被 OLM 使用来更好地管理 Operator 的生命周期。

OLM 提供了一个名为 OperatorCondition 的自定义资源定义(CRD),它允许 Operator 与 OLM 相互通信条件信息。当在一个 OperatorCondition 资源的 Spec.Conditions 数组中存在时,则代表存在一组会影响 OLM 管理 Operator 的支持条件。

注意

默认情况下,OperatorCondition 对象中没有 Spec.Conditions 数组,直到由用户添加或使用自定义 Operator 逻辑的结果为止。

其他资源

2.4.2. Operator Lifecycle Manager 架构

本指南概述了 OpenShift Container Platform 中 Operator Lifecycle Manager (OLM) 的组件架构。

2.4.2.1. 组件职责

Operator Lifecycle Manager (OLM) 由两个 Operator 组成,分别为:OLM Operator 和 Catalog Operator。

每个 Operator 均负责管理 CRD,而 CRD 是 OLM 的框架基础:

表 2.2. 由 OLM 和 Catalog Operator 管理的 CRD

资源短名称所有者描述

ClusterServiceVersion (CSV)

csv

OLM

应用程序元数据:名称、版本、图标、所需资源、安装等。

InstallPlan

ip

Catalog

为自动安装或升级 CSV 而需创建的资源的计算列表。

CatalogSource

catsrc

Catalog

定义应用程序的 CSV、CRD 和软件包存储库。

Subscription

sub

Catalog

用于通过跟踪软件包中的频道来保持 CSV 最新。

OperatorGroup

og

OLM

将部署在同一命名空间中的所有 Operator 配置为 OperatorGroup 对象,以便在一系列命名空间或集群范围内监视其自定义资源 ( CR)。

每个 Operator 还负责创建以下资源:

表 2.3. 由 OLM 和 Catalog Operator 创建的资源

资源所有者

部署

OLM

ServiceAccounts

(Cluster)Roles

(Cluster)RoleBindings

CustomResourceDefinitions (CRD)

Catalog

ClusterServiceVersions

2.4.2.2. OLM Operator

集群中存在 CSV 中指定需要的资源后,OLM Operator 将负责部署由 CSV 资源定义的应用程序。

OLM Operator 不负责创建所需资源;用户可选择使用 CLI 手动创建这些资源,也可选择使用 Catalog Operator 来创建这些资源。这种关注点分离的机制可以使得用户逐渐增加他们选择用于其应用程序的 OLM 框架量。

OLM Operator 使用以下工作流:

  1. 观察命名空间中的集群服务版本(CSV),并检查是否满足要求。
  2. 如果满足要求,请运行 CSV 的安装策略。

    注意

    CSV 必须是 Operator 组的活跃成员,才可运行该安装策略。

2.4.2.3. Catalog Operator

Catalog Operator 负责解析和安装集群服务版本(CSV)以及它们指定的所需资源。另外还负责监视频道中的目录源中是否有软件包更新,并将其升级(可选择自动)至最新可用版本。

要跟踪频道中的软件包,您可以创建一个 Subscription 对象来配置所需的软件包、频道和 CatalogSource 对象,以便拉取更新。在找到更新后,便会代表用户将一个适当的 InstallPlan 对象写入命名空间。

Catalog Operator 使用以下工作流:

  1. 连接到集群中的每个目录源。
  2. 监视是否有用户创建的未解析安装计划,如果有:

    1. 查找与请求名称相匹配的 CSV,并将此 CSC 添加为已解析的资源。
    2. 对于每个受管或所需 CRD,将其添加为已解析的资源。
    3. 对于每个所需 CRD,找到管理相应 CRD 的 CSV。
  3. 监视是否有已解析的安装计划并为其创建已发现的所有资源(用户批准或自动)。
  4. 观察目录源和订阅并根据它们创建安装计划。

2.4.2.4. Catalog Registry

Catalog Registry 存储 CSV 和 CRD 以便在集群中创建,并存储有关软件包和频道的元数据。

package manifest 是 Catalog Registry 中的一个条目,用于将软件包标识与 CSV 集相关联。在软件包中,频道指向特定 CSV。因为 CSV 明确引用了所替换的 CSV,软件包清单向 Catalog Operator 提供了将 CSV 更新至频道中最新版本所需的信息,逐步安装和替换每个中间版本。

2.4.3. Operator Lifecycle Manager 工作流

本指南概述了 OpenShift Container Platform 中 Operator Lifecycle Manager (OLM) 的工作流。

2.4.3.1. OLM 中的 Operator 安装和升级工作流

在 Operator Lifecycle Manager (OLM) 生态系统中,以下资源用于解决 Operator 的安装和升级问题:

  • ClusterServiceVersion (CSV)
  • CatalogSource
  • Subscription

CSV 中定义的 Operator 元数据可保存在一个称为目录源的集合中。目录源使用 Operator Registry API,OLM 又使用目录源来查询是否有可用的 Operator 及已安装 Operator 是否有升级版本。

图 2.3. 目录源概述

olm catalogsource

在目录源中,Operator 被整合为更新软件包和更新流,我们称为频道,这应是 OpenShift Container Platform 或其他软件(如 Web 浏览器)在持续发行周期中的常见更新模式。

图 2.4. 目录源中的软件包和频道

olm channels

用户在订阅中的特定目录源中指示特定软件包和频道,如 etcd 包及其 alpha 频道。如果订阅了命名空间中尚未安装的软件包,则会安装该软件包的最新 Operator。

注意

OLM 会刻意避免版本比较,因此给定 catalogchannelpackage 路径提供的“latest”或“newest”Operator 不一定是最高版本号。更应将其视为频道的 head 引用,类似 Git 存储库。

每个 CSV 均有一个 replaces 参数,指明所替换的是哪个 Operator。这样便构建了一个可通过 OLM 查询的 CSV 图,且不同频道之间可共享更新。可将频道视为更新图表的入口点:

图 2.5. OLM 的可用频道更新图表

olm replaces

软件包中的频道示例

packageName: example
channels:
- name: alpha
  currentCSV: example.v0.1.2
- name: beta
  currentCSV: example.v0.1.3
defaultChannel: alpha

为了让 OLM 成功查询更新、给定一个目录源、软件包、频道和 CSV,目录必须能够明确无误地返回替换输入 CSV 的单个 CSV。

2.4.3.1.1. 升级路径示例

对于示例升级场景,假设安装的 Operator 对应于 0.1.1 版 CSV。OLM 查询目录源,并在订阅的频道中检测升级,新的 0.1.3 版 CSV 替换了旧的但未安装的 0.1.2 版 CSV,后者又取代了较早且已安装的 0.1.1 版 CSV。

OLM 通过 CSV 中指定的 replaces 字段从频道头倒退至之前的版本,以确定升级路径为 0.1.30.1.20.1.1,其中箭头代表前者取代后者。OLM 一次仅升级一个 Operator 版本,直至到达频道头。

对于该给定场景,OLM 会安装 0.1.2 版 Operator 来取代现有的 0.1.1 版 Operator。然后再安装 0.1.3 版 Operator 来取代之前安装的 0.1.2 版 Operator。至此,所安装的 0.1.3 版 Operator 与频道头相匹配,意味着升级已完成。

2.4.3.1.2. 跳过升级

OLM 中升级的基本路径是:

  • 通过对 Operator 的一个或多个更新来更新目录源。
  • OLM 会遍历 Operator 的所有版本,直到到达目录源包含的最新版本。

但有时这不是一种安全操作。某些情况下,已发布但尚未就绪的 Operator 版本不可安装至集群中,如版本中存在严重漏洞。

这种情况下,OLM 必须考虑两个集群状态,并提供支持这两个状态的更新图:

  • 集群发现并安装了“不良”中间 Operator。
  • “不良”中间 Operator 尚未安装至集群中。

通过发送新目录并添加跳过的发行版本,可保证无论集群状态如何以及是否发现了不良更新,OLM 总能获得单个唯一更新。

带有跳过发行版本的 CSV 示例

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  name: etcdoperator.v0.9.2
  namespace: placeholder
  annotations:
spec:
    displayName: etcd
    description: Etcd Operator
    replaces: etcdoperator.v0.9.0
    skips:
    - etcdoperator.v0.9.1

考虑以下 Old CatalogSourceNew CatalogSource 示例。

图 2.6. 跳过更新

olm skipping updates

该图表明:

  • Old CatalogSource 中的任何 Operator 在 New CatalogSource 中均有单一替换项。
  • New CatalogSource 中的任何 Operator 在 New CatalogSource 中均有单一替换项。
  • 如果未曾安装不良更新,将来也绝不会安装。
2.4.3.1.3. 替换多个 Operator

按照描述创建 New CatalogSource 需要发布 CSV 来替换单个 Operator,但可跳过多个。该操作可通过 skipRange 注解来完成:

olm.skipRange: <semver_range>

其中 <semver_range> 具有 semver library 所支持的版本范围格式。

当在目录中搜索更新时,如果某个频道头提供一个 skipRange 注解,且当前安装的 Operator 的版本字段在该范围内,则 OLM 会更新至该频道中的最新条目。

先后顺序:

  1. Subscription 上由 sourceName 指定的源中的频道头(满足其他跳过条件的情况下)。
  2. sourceName 指定的源中替换当前 Operator 的下一 Operator。
  3. 对 Subscription 可见的另一个源中的频道头(满足其他跳过条件的情况下)。
  4. 在对 Subscription 可见的任何源中替换当前 Operator 的下一 Operator。

带有 skipRange 的 CSV 示例

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
    name: elasticsearch-operator.v4.1.2
    namespace: <namespace>
    annotations:
        olm.skipRange: '>=4.1.0 <4.1.2'

2.4.3.1.4. Z-stream 支持

对于相同从版本,z-stream 或补丁版本必须取代所有先前 z-stream 版本。OLM 不考虑主版本、次版本或补丁版本,只需要在目录中构建正确的图表。

换句话说,OLM 必须能够像在 Old CatalogSource 中一样获取一个图表,像在 New CatalogSource 中一样生成一个图表:

图 2.7. 替换多个 Operator

olm z stream

该图表明:

  • Old CatalogSource 中的任何 Operator 在 New CatalogSource 中均有单一替换项。
  • New CatalogSource 中的任何 Operator 在 New CatalogSource 中均有单一替换项。
  • Old CatalogSource 中的所有 z-stream 版本均会更新至 New CatalogSource 中最新 z-stream 版本。
  • 不可用版本可被视为“虚拟”图表节点;它们的内容无需存在,注册表只需像图表看上去这样响应即可。

2.4.4. Operator Lifecycle Manager 依赖项解析

本指南概述了 OpenShift Container Platform 中 Operator Lifecycle Manager (OLM) 内的依赖项解析和自定义资源定义 (CRD) 升级生命周期。

2.4.4.1. 关于依赖项解析

Operator Lifecycle Manager(OLM)管理运行 Operator 的依赖项解析和升级生命周期。在很多方面,OLM 的问题与其他系统或语言软件包管理器类似,如 yumrpm

但其中有一个限制是相似系统一般不存在而 OLM 存在的,那就是:因为 Operator 始终在运行,所以 OLM 会努力确保您所接触的 Operator 组始终相互兼容。

因此,OLM 不得创建以下情况:

  • 安装一组需要无法提供的 API 的 Operator
  • 更新某个 Operator 之时导致依赖该 Operator 的另一 Operator 中断

这可以通过两种类型的数据:

Properties

在依赖项解析器中输入构成了公共接口的 Operator 元数据。示例包括 Operator 提供的 API 的 group/version/kind(GVK),以及 Operator 的语义版本(semver)。

约束或依赖项

应该对可能或还没有在目标集群中安装的其他 Operator 满足 Operator 的要求。它们充当所有可用 Operator 的查询或过滤,并在依赖项解析和安装过程中限制选择。例如,需要特定的 API 在集群中可用,或希望安装带有特定版本的特定 Operator。

OLM 将这些属性和约束转换为布尔值公式系统,并将其传递给 SAT solver,SAT solver 是一个处理布尔值的程序,用于确定应该安装哪些 Operator。

2.4.4.2. Operator 属性

目录中的所有 Operator 均具有以下属性:

olm.package
包括软件包和 Operator 版本的名称
olm.gvk
集群服务版本(CSV)中每个提供的 API 的单个属性

Operator 作者也可以在 Operator 捆绑包的 metadata/ 目录中包括 properties.yaml 文件来直接声明其他属性。

任意(arbitrary)属性示例

properties:
- type: olm.kubeversion
  value:
    version: "1.16.0"

2.4.4.2.1. 任意属性

Operator 作者可在 Operator 捆绑包的 metadata/ 目录中的 properties.yaml 文件中声明任意属性。这些属性转换为映射数据结构,该结构用作运行时 Operator Lifecycle Manager(OLM)解析器的输入。

这些属性对解析器不理解属性而不理解这些属性,但可以针对这些属性评估通用限制,以确定约束是否可以满足给定的属性列表。

任意属性示例

properties:
  - property:
      type: color
      value: red
  - property:
      type: shape
      value: square
  - property:
      type: olm.gvk
      value:
        group: olm.coreos.io
        version: v1alpha1
        kind: myresource

此结构可用于为通用限制构建通用表达式语言(CEL)表达式。

2.4.4.3. Operator 依赖项

Operator 的依赖项列在捆绑包的 metadata/ 目录中的 dependencies.yaml 文件中。此文件是可选的,目前仅用于指明 Operator-version 依赖项。

依赖项列表中,每个项目包含一个 type 字段,用于指定这一依赖项的类型。支持以下 Operator 依赖项:

olm.package
这个类型表示特定 Operator 版本的依赖项。依赖项信息必须包含软件包名称以及软件包的版本,格式为 semver。例如,您可以指定具体版本,如 0.5.2,也可指定一系列版本,如 >0.5.1
olm.gvk
使用这个类型,作者可以使用 group/version/kind(GVK)信息指定依赖项,类似于 CSV 中现有 CRD 和基于 API 的使用量。该路径使 Operator 作者可以合并所有依赖项、API 或显式版本,使它们处于同一位置。
olm.constraint
这个类型在任意 Operator 属性上声明通用限制。

在以下示例中,为 Prometheus Operator 和 etcd CRD 指定依赖项:

dependencies.yaml 文件示例

dependencies:
  - type: olm.package
    value:
      packageName: prometheus
      version: ">0.27.0"
  - type: olm.gvk
    value:
      group: etcd.database.coreos.com
      kind: EtcdCluster
      version: v1beta2

2.4.4.4. 通用限制

olm.constraint 属性声明特定类型的依赖项约束,区分非约束和约束属性。其 value 字段是一个包含 failureMessage 字段的对象,其中包含约束消息的字符串表。如果约束在运行时不满意,则这一消息被作为信息性提供给用户使用。

以下键表示可用的约束类型:

gvk
其值及对其的解释与 olm.gvk 类型相同的类型
package
其值及对其的解释与 olm.package 类型相同的类型
cel
Operator Lifecycle Manager(OLM)解析程序通过任意捆绑包属性和集群信息在运行时评估的通用表达式语言(CEL)表达式
all, any, not
分别为 Conjunction, disjunction, 和 negation 约束,包括一个或多个 concrete 约束,如 gvk 或一个嵌套的 compound 约束
2.4.4.4.1. 常见表达式语言(CEL)约束

cel 约束类型支持将通用表达式语言(CEL) 用作表达式语言。cel struct 有一个 rule 字段,其中包含在运行时针对 Operator 属性评估的 CEL 表达式字符串,以确定 Operator 是否满足约束。

cel 约束示例

type: olm.constraint
value:
  failureMessage: 'require to have "certified"'
  cel:
    rule: 'properties.exists(p, p.type == "certified")'

CEL 语法支持广泛的逻辑运算符,如 ANDOR。因此,单个 CEL 表达式可以具有多个规则,这些条件由这些逻辑运算符链接在一起。这些规则针对来自捆绑包或任何给定源的多个不同属性的数据评估,输出可以解决单一约束内满足所有这些规则的捆绑包或 Operator。

使用多个规则的 cel 约束示例

type: olm.constraint
value:
  failureMessage: 'require to have "certified" and "stable" properties'
  cel:
    rule: 'properties.exists(p, p.type == "certified") && properties.exists(p, p.type == "stable")'

2.4.4.4.2. Compound 约束 (all, any, not)

复合约束类型按照其逻辑定义进行评估。

以下是两个软件包的 conjunctive 约束(all)的示例,以及一个 GVK。这代表,安装捆绑包都必须满足它们:

all 约束示例

schema: olm.bundle
name: red.v1.0.0
properties:
- type: olm.constraint
  value:
    failureMessage: All are required for Red because...
    all:
      constraints:
      - failureMessage: Package blue is needed for...
        package:
          name: blue
          versionRange: '>=1.0.0'
      - failureMessage: GVK Green/v1 is needed for...
        gvk:
          group: greens.example.com
          version: v1
          kind: Green

以下是同一个 GVK 的三个版本的 disjunctive 约束 (any) 示例。这代表,安装捆绑包必须至少满足其中一项:

any 约束示例

schema: olm.bundle
name: red.v1.0.0
properties:
- type: olm.constraint
  value:
    failureMessage: Any are required for Red because...
    any:
      constraints:
      - gvk:
          group: blues.example.com
          version: v1beta1
          kind: Blue
      - gvk:
          group: blues.example.com
          version: v1beta2
          kind: Blue
      - gvk:
          group: blues.example.com
          version: v1
          kind: Blue

以下是 GVK 的一个版本的 negation 约束(not)的示例。这代表,此 GVK 无法由结果集中的任何捆绑包提供:

not 约束示例

schema: olm.bundle
name: red.v1.0.0
properties:
- type: olm.constraint
  value:
  all:
    constraints:
    - failureMessage: Package blue is needed for...
      package:
        name: blue
        versionRange: '>=1.0.0'
    - failureMessage: Cannot be required for Red because...
      not:
        constraints:
        - gvk:
            group: greens.example.com
            version: v1alpha1
            kind: greens

对于 not 约束,其中的负语义可能并不明确。这里的负语义代表指示解析器删除所有可能的解决方案,这些解决方案包括特定 GVK、特点版本的软版本,或满足结果集中的一些子复合约束。

not compound 约束不应该和 allany 一起使用,因为这里的负语言在没有先选择一组可能的依赖项时是并没有意义。

2.4.4.4.3. 嵌套复合限制

一个嵌套复合约束(包括最少一个子复合约束以及零个或更多简单约束)会从底向上的顺序被评估,并根据每个前面描述的约束类型的过程进行。

以下是一个 disjunction 的 conjunctions 示例,其中一个、另一个、或两者都能满足约束:

嵌套复合约束示例

schema: olm.bundle
name: red.v1.0.0
properties:
- type: olm.constraint
  value:
    failureMessage: Required for Red because...
    any:
      constraints:
      - all:
          constraints:
          - package:
              name: blue
              versionRange: '>=1.0.0'
          - gvk:
              group: blues.example.com
              version: v1
              kind: Blue
      - all:
          constraints:
          - package:
              name: blue
              versionRange: '<1.0.0'
          - gvk:
              group: blues.example.com
              version: v1beta1
              kind: Blue

注意

olm.constraint 类型的最大原始大小为 64KB,用于限制资源耗尽的情况。

2.4.4.5. 依赖项首选项

有很多选项同样可以满足 Operator 的依赖性。Operator Lifecycle Manager(OLM)中的依赖项解析器决定哪个选项最适合所请求 Operator 的要求。作为 Operator 作者或用户,了解这些选择非常重要,以便明确依赖项解析。

2.4.4.5.1. 目录优先级

在 OpenShift Container Platform 集群中,OLM 会读取目录源以了解哪些 Operator 可用于安装。

CatalogSource 对象示例

apiVersion: "operators.coreos.com/v1alpha1"
kind: "CatalogSource"
metadata:
  name: "my-operators"
  namespace: "operators"
spec:
  sourceType: grpc
  grpcPodConfig:
    securityContextConfig: <security_mode> 1
  image: example.com/my/operator-index:v1
  displayName: "My Operators"
  priority: 100

1
指定 legacyrestricted 的值。如果没有设置该字段,则默认值为 legacy。在以后的 OpenShift Container Platform 发行版本中,计划默认值为 restricted。如果您的目录无法使用 restricted 权限运行,建议您手动将此字段设置为 legacy

CatalogSource 有一个 priority 字段,解析器使用它来知道如何为依赖关系设置首选选项。

目录首选项有两个规则:

  • 优先级较高目录中的选项优先于较低优先级目录的选项。
  • 与依赖项相同的目录里的选项优先于其它目录。
2.4.4.5.2. 频道排序

目录中的 Operator 软件包是用户可在 OpenShift Container Platform 集群中订阅的更新频道集合。可使用频道为次发行版本(1.2, 1.3)或者发行的频率(stable, fast)提供特定的更新流。

同一软件包中的 Operator 可能会满足依赖项,但可能会在不同的频道。例如,Operator 版本 1.2 可能存在于 stablefast 频道中。

每个软件包都有一个默认频道,该频道总是首选非默认频道。如果默认频道中没有选项可以满足依赖关系,则会在剩余的频道中按频道名称的字母顺序考虑这些选项。

2.4.4.5.3. 频道中的顺序

一般情况下,总会有多个选项来满足单一频道中的依赖关系。例如,一个软件包和频道中的 Operator 提供了相同的 API 集。

当用户创建订阅时,它们会指示要从哪个频道接收更新。这会立即把搜索范围限制在那个频道。但是在频道中,可以会有许多 Operator 可以满足依赖项。

在频道中,应该首选考虑使用更新图中位置较高的较新的 Operator。如果某个频道的头满足依赖关系,它将会被首先尝试。

2.4.4.5.4. 其他限制

除了软件包依赖关系的限制外,OLM 还添加了其他限制来代表所需用户状态和强制实施解析变量。

2.4.4.5.4.1. 订阅约束

一个订阅(Subscription)约束会过滤可满足订阅的 Operator 集合。订阅是对依赖项解析程序用户提供的限制。它们会声明安装一个新的 Operator(如果还没有在集群中安装),或对现有 Operator 进行更新。

2.4.4.5.4.2. 软件包约束

在命名空间中,不同的两个 Operator 不能来自于同一软件包。

2.4.4.5.5. 其他资源

2.4.4.6. CRD 升级

如果自定义资源定义(CRD)属于单一集群服务版本(CSV),OLM 会立即对其升级。如果某个 CRD 被多个 CSV 拥有,则当该 CRD 满足以下所有向后兼容条件时才会升级:

  • 所有已存在于当前 CRD 中的服务版本都包括在新 CRD 中。
  • 在根据新 CRD 的验证模式(schema)进行验证后,与 CRD 的服务版本关联的所有现有实例或自定义资源均有效。

2.4.4.7. 依赖项最佳实践

在指定依赖项时应该考虑的最佳实践。

依赖于 API 或 Operator 的特定版本范围
操作员可以随时添加或删除 API ; 始终针对 Operator 所需的任何 API 指定 olm.gvk 依赖项。例外情况是,指定 olm.package 约束来替代。
设置最小版本

Kubernetes 文档中与 API 的改变相关的部分描述了 Kubernetes 风格的 Operator 允许进行哪些更改。只要 API 向后兼容,Operator 就允许 Operator 对 API 进行更新,而不需要更改 API 的版本。

对于 Operator 依赖项,这意味着了解依赖的 API 版本可能不足以确保依赖的 Operator 正常工作。

例如:

  • TestOperator v1.0.0 提供 MyObject 资源的 v1alpha1 API 版本。
  • TestOperator v1.0.1 为 MyObject 添加了一个新的 spec.newfield 字段,但仍是 v1alpha1。

您的 Operator 可能需要将 spec.newfield 写入 MyObject 资源。仅使用 olm.gvk 约束还不足以让 OLM 决定您需要 TestOperator v1.0.1 而不是 TestOperator v1.0.0。

如果事先知道提供 API 的特定 Operator,则指定额外的 olm.package 约束来设置最小值。

省略一个最大版本,或允许一个广泛的范围

因为 Operator 提供了集群范围的资源,如 API 服务和 CRD,所以如果一个 Operator 为依赖项指定了一个小的窗口,则可能会对依赖项的其他用户的更新产生不必要的约束。

在可能的情况下,尽量不要设置最大版本。或者,设置一个非常宽松的语义范围,以防止与其他 Operator 冲突。例如:>1.0.0 <2.0.0

与传统的软件包管理器不同,Operator 作者显性地对更新通过 OLM 中的频道进行编码。如果现有订阅有可用更新,则假定 Operator 作者表示它可以从上一版本更新。为依赖项设置最大版本会绕过作者的更新流,即不必要的将它截断到特定的上限。

注意

集群管理员无法覆盖 Operator 作者设置的依赖项。

但是,如果已知有需要避免的不兼容问题,就应该设置最大版本。通过使用版本范围语法,可以省略特定的版本,如 > 1.0.0 !1.2.1

其他资源

2.4.4.8. 依赖项注意事项

当指定依赖项时,需要考虑一些注意事项。

没有捆绑包约束(AND)

目前还没有方法指定约束间的 AND 关系。换句话说,无法指定一个 Operator,它依赖于另外一个 Operator,它提供一个给定的 API 且版本是 >1.1.0

这意味着,在指定依赖项时,如:

dependencies:
- type: olm.package
  value:
    packageName: etcd
    version: ">3.1.0"
- type: olm.gvk
  value:
    group: etcd.database.coreos.com
    kind: EtcdCluster
    version: v1beta2

OLM 可以通过两个 Operator 来满足这个要求:一个提供 EtcdCluster,另一个有版本 >3.1.0。是否发生了这种情况,或者选择某个 Operator 是否满足这两个限制,这取决于是否准备了潜在的选项。依赖项偏好和排序选项被明确定义并可以指定原因,但为了谨慎起见,Operator 应该遵循一种机制或其他机制。

跨命名空间兼容性
OLM 在命名空间范围内执行依赖项解析。如果更新某个命名空间中的 Operator 会对另一个命名空间中的 Operator 造成问题,则可能会造成更新死锁。

2.4.4.9. 依赖项解析方案示例

在以下示例中,provider(供应商) 是指"拥有" CRD 或 API 服务的 Operator。

示例:弃用从属 API

A 和 B 是 API(CRD):

  • A 的供应商依赖 B。
  • B 的供应商有一个订阅。
  • B 更新供应商提供 C,但弃用 B。

结果:

  • B 不再有供应商。
  • A 不再工作。

这是 OLM 通过升级策略阻止的一个案例。

示例:版本死锁

A 和 B 均为 API:

  • A 的供应商需要 B。
  • B 的供应商需要 A。
  • A 更新的供应商到(提供 A2,需要 B2)并弃用 A。
  • B 更新的供应商到(提供 B2,需要 A2)并弃用 B。

如果 OLM 试图在更新 A 的同时不更新 B,或更新 B 的同时不更新 A,则无法升级到新版 Operator,即使可找到新的兼容集也无法更新。

这是 OLM 通过升级策略阻止的另一案例。

2.4.5. operator 组

本指南概述了 OpenShift Container Platform 中 Operator Lifecycle Manager(OLM)的 Operator 组使用情况。

2.4.5.1. 关于 Operator 组

OperatorGroup 资源定义的 Operator 组,为 OLM 安装的 Operator 提供多租户配置。Operator 组选择目标命名空间,在其中为其成员 Operator 生成所需的 RBAC 访问权限。

这一组目标命名空间通过存储在 CSV 的 olm.targetNamespaces 注解中的以逗号分隔的字符串来提供。该注解应用于成员 Operator 的 CSV 实例,并注入它们的部署中。

2.4.5.2. Operator 组成员

满足以下任一条件,Operator 即可被视为 Operator 组的 member

  • Operator 的 CSV 与 Operator 组位于同一命名空间中。
  • Operator CSV 中的安装模式支持 Operator 组的目标命名空间集。

CSV 中的安装模式由 InstallModeType 字段和 Supported 的布尔值字段组成。CSV 的 spec 可以包含一组由四个不同 InstallModeTypes 组成的安装模式:

表 2.4. 安装模式和支持的 Operator 组

InstallModeType描述

OwnNamespace

Operator 可以是选择其自有命名空间的 Operator 组的成员。

SingleNamespace

Operator 可以是选择一个命名空间的 Operator 组的成员。

MultiNamespace

Operator 可以是选择多个命名空间的 Operator 组的成员。

AllNamespaces

Operator 可以是选择所有命名空间的 Operator 组的成员(目标命名空间集为空字符串 "")。

注意

如果 CSV 的 spec 省略 InstallModeType 条目,则该类型将被视为不受支持,除非可通过隐式支持的现有条目推断出支持。

2.4.5.3. 目标命名空间选择

您可以使用 spec.targetNamespaces 参数为 Operator 组显式命名目标命名空间:

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: my-group
  namespace: my-namespace
spec:
  targetNamespaces:
  - my-namespace
警告

Operator Lifecycle Manager (OLM) 为每个 Operator 组创建以下集群角色:

  • <operatorgroup_name>-admin
  • <operatorgroup_name>-edit
  • <operatorgroup_name>-view

当手动创建 Operator 组时,您必须指定一个没有与现有集群角色或其他 Operator 组冲突的唯一名称。

您还可以使用带有 spec.selector 参数的标签选择器指定命名空间:

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: my-group
  namespace: my-namespace
spec:
  selector:
    cool.io/prod: "true"
重要

不建议通过 spec.targetNamespaces 列出多个命名空间,或通过 spec.selector 使用标签选择器,因为在以后的版本中可能会删除对 Operator 组中多个目标命名空间的支持。

如果 spec.targetNamespacesspec.selector 均已定义,则会忽略 spec.selector。另外,您可以省略 spec.selectorspec.targetNamespaces 来指定一个 全局 Operator 组,该组选择所有命名空间:

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: my-group
  namespace: my-namespace

Opeator 组的 status.namespaces 参数中会显示所选命名空间的解析集合。全局 OperatorGroup 的 status.namespace 包含空字符串 (""),而该字符串会向正在使用的 Operator 发出信号,要求其监视所有命名空间。

2.4.5.4. operator 组 CSV 注解

Operator 组的成员 CSV 具有以下注解:

注解描述

olm.operatorGroup=<group_name>

包含 Operator 组的名称。

olm.operatorNamespace=<group_namespace>

包含 Operator 组的命名空间。

olm.targetNamespaces=<target_namespaces>

包含以逗号分隔的字符串,列出 Operator 组的目标命名空间选择。

注意

olm.targetNamespaces 以外的所有注解均包含在复制的 CSV 中。在复制的 CSV 上省略 olm.targetNamespaces 注解可防止租户之间目标命名空间出现重复。

2.4.5.5. 所提供的 API 注解

group/version/kind (GVK) 是 Kubernetes API 的唯一标识符。olm.providedAPIs 注解中会显示有关 Operator 组提供哪些 GVK 的信息。该注解值为一个字符串,由用逗号分隔的 <kind>.<version>.<group> 组成。其中包括由 Operator 组的所有活跃成员 CSV 提供的 CRD 和 APIService 的 GVK。

查看以下 OperatorGroup 示例,该 OperatorGroup 带有提供 PackageManifest 资源的单个活跃成员 CSV:

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  annotations:
    olm.providedAPIs: PackageManifest.v1alpha1.packages.apps.redhat.com
  name: olm-operators
  namespace: local
  ...
spec:
  selector: {}
  serviceAccount:
    metadata:
      creationTimestamp: null
  targetNamespaces:
  - local
status:
  lastUpdated: 2019-02-19T16:18:28Z
  namespaces:
  - local

2.4.5.6. 基于角色的访问控制

创建 Operator 组时,会生成三个集群角色。每个 ClusterRole 均包含一个聚会规则,后者带有一个选择器以匹配标签,如下所示:

集群角色要匹配的标签

<operatorgroup_name>-admin

olm.opgroup.permissions/aggregate-to-admin: <operatorgroup_name>

<operatorgroup_name>-edit

olm.opgroup.permissions/aggregate-to-edit: <operatorgroup_name>

<operatorgroup_name>-view

olm.opgroup.permissions/aggregate-to-view: <operatorgroup_name>

警告

Operator Lifecycle Manager (OLM) 为每个 Operator 组创建以下集群角色:

  • <operatorgroup_name>-admin
  • <operatorgroup_name>-edit
  • <operatorgroup_name>-view

当手动创建 Operator 组时,您必须指定一个没有与现有集群角色或其他 Operator 组冲突的唯一名称。

当 CSV 成为 Operator 组的活跃成员时,只要该 CSV 正在使用 AllNamespaces 安装模式来监视所有命名空间,且没有因 InterOperatorGroupOwnerConflict 原因处于故障状态,便会生成以下 RBAC 资源:

  • 来自 CRD 的每个 API 资源的集群角色
  • 来自 API 服务的每个 API 资源的集群角色
  • 其他角色和角色绑定

表 2.5. 来自 CRD 的为每个 API 资源生成的集群角色

集群角色设置

<kind>.<group>-<version>-admin

<kind> 上的操作动词:

  • *

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-admin: true
  • olm.opgroup.permissions/aggregate-to-admin: <operatorgroup_name>

<kind>.<group>-<version>-edit

<kind> 上的操作动词:

  • create
  • update
  • patch
  • delete

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-edit: true
  • olm.opgroup.permissions/aggregate-to-edit: <operatorgroup_name>

<kind>.<group>-<version>-view

<kind> 上的操作动词:

  • get
  • list
  • watch

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-view: true
  • olm.opgroup.permissions/aggregate-to-view: <operatorgroup_name>

<kind>.<group>-<version>-view-crdview

apiextensions.k8s.io customresourcedefinitions <crd-name> 上的操作动词:

  • get

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-view: true
  • olm.opgroup.permissions/aggregate-to-view: <operatorgroup_name>

表 2.6. 来自 API 服务的为每个 API 资源生成的集群角色

集群角色设置

<kind>.<group>-<version>-admin

<kind> 上的操作动词:

  • *

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-admin: true
  • olm.opgroup.permissions/aggregate-to-admin: <operatorgroup_name>

<kind>.<group>-<version>-edit

<kind> 上的操作动词:

  • create
  • update
  • patch
  • delete

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-edit: true
  • olm.opgroup.permissions/aggregate-to-edit: <operatorgroup_name>

<kind>.<group>-<version>-view

<kind> 上的操作动词:

  • get
  • list
  • watch

聚合标签:

  • rbac.authorization.k8s.io/aggregate-to-view: true
  • olm.opgroup.permissions/aggregate-to-view: <operatorgroup_name>

其他角色和角色绑定

  • 如果 CSV 定义了一个目标命名空间,其中包括 *,则会针对 CSV 权限字段中定义的每个 permissions 生成集群角色和对应集群角色绑定。所有生成的资源均会标上 olm.owner: <csv_name>olm.owner.namespace: <csv_namespace> 标签。
  • 如果 CSV 没有定义一个包含 * 的目标命名空间,则 Operator 命名空间中的所有角色和角色绑定都使用 olm.owner: <csv_name>olm.owner.namespace: <csv_namespace> 标签复制到目标命名空间中。

2.4.5.7. 复制的 CSV

OLM 会在 Operator 组的每个目标命名空间中创建 Operator 组的所有活跃成员 CSV 的副本。复制 CSV 的目的在于告诉目标命名空间的用户,特定 Operator 已配置为监视在此创建的资源。

复制的 CSV 会复制状态原因,并会更新以匹配其源 CSV 的状态。在集群上创建复制的 CSV 之前,会从这些 CSV 中分离 olm.targetNamespaces 注解。省略目标命名空间选择可避免租户之间存在目标命名空间重复的现象。

当所复制的 CSV 的源 CSV 不存在或其源 CSV 所属的 Operator 组不再指向复制 CSV 的命名空间时,会删除复制的 CSV。

注意

默认情况下禁用 disableCopiedCSVs 字段。启用 disableCopiedCSVs 字段后,OLM 会删除集群中的现有复制的 CSV。当 disableCopiedCSVs 字段被禁用时,OLM 会再次添加复制的 CSV。

  • 禁用 disableCopiedCSVs 字段:

    $ cat << EOF | oc apply -f -
    apiVersion: operators.coreos.com/v1
    kind: OLMConfig
    metadata:
      name: cluster
    spec:
      features:
        disableCopiedCSVs: false
    EOF
  • 启用 disableCopiedCSVs 字段:

    $ cat << EOF | oc apply -f -
    apiVersion: operators.coreos.com/v1
    kind: OLMConfig
    metadata:
      name: cluster
    spec:
      features:
        disableCopiedCSVs: true
    EOF

2.4.5.8. 静态 Operator 组

如果 Operator 组的 spec.staticProvidedAPIs 字段被设置为 true,则 Operator 组为静态。因此,OLM 不会修改 Operator 组的 olm.providedAPIs 注解,这意味着可以提前设置它。如果一组命名空间没有活跃的成员 CSV 来为资源提供 API,而用户想使用 Operator 组来防止命名空间集中发生资源争用,则这一操作十分有用。

以下是一个 Operator 组示例,它使用 something.cool.io/cluster-monitoring: "true" 注解来保护所有命名空间中的 Prometheus 资源:

apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: cluster-monitoring
  namespace: cluster-monitoring
  annotations:
    olm.providedAPIs: Alertmanager.v1.monitoring.coreos.com,Prometheus.v1.monitoring.coreos.com,PrometheusRule.v1.monitoring.coreos.com,ServiceMonitor.v1.monitoring.coreos.com
spec:
  staticProvidedAPIs: true
  selector:
    matchLabels:
      something.cool.io/cluster-monitoring: "true"
警告

Operator Lifecycle Manager (OLM) 为每个 Operator 组创建以下集群角色:

  • <operatorgroup_name>-admin
  • <operatorgroup_name>-edit
  • <operatorgroup_name>-view

当手动创建 Operator 组时,您必须指定一个没有与现有集群角色或其他 Operator 组冲突的唯一名称。

2.4.5.9. operator 组交集

如果两个 Operator 组的目标命名空间集的交集不是空集,且根据 olm.providedAPIs 注解的定义,所提供的 API 集的交集也不是空集,则称这两个 OperatorGroup 的提供的 API 有交集

一个潜在问题是,提供的 API 有交集的 Operator 组可能在命名空间交集中竞争相同资源。

注意

在检查交集规则时,Operator 组的命名空间始终包含在其所选目标命名空间中。

交集规则

每次活跃成员 CSV 同步时,OLM 均会查询集群,以获取 CSV 组和其他所有 CSV 组之间提供的 API 交集。然后 OLM 会检查该交集是否为空集:

  • 如果结果为 true,且 CSV 提供的 API 是 Operator 组提供的 API 的子集:

    • 继续转变。
  • 如果结果为 true,且 CSV 提供的 API 不是 Operator 组提供的 API 的子集:

    • 如果 Operator 组是静态的:

      • 则清理属于 CSV 的所有部署。
      • 将 CSV 转变为故障状态,状态原因为:CannotModifyStaticOperatorGroupProvidedAPIs
    • 如果 Operator 组不是静态的:

      • 将 Operator 组的 olm.providedAPIs 注解替换为其本身与 CSV 提供的 API 的并集。
  • 如果结果为 false,且 CSV 提供的 API 不是 Operator 组提供的 API 的子集:

    • 则清理属于 CSV 的所有部署。
    • 将 CSV 转变为故障状态,状态原因为:InterOperatorGroupOwnerConflict
  • 如果结果为 false,且 CSV 提供的 API 是 Operator 组提供的 API 的子集:

    • 如果 Operator 组是静态的:

      • 则清理属于 CSV 的所有部署。
      • 将 CSV 转变为故障状态,状态原因为:CannotModifyStaticOperatorGroupProvidedAPIs
    • 如果 Operator 组不是静态的:

      • 将 Operator 组的 olm.providedAPIs 注解替换为其本身与 CSV 提供的 API 的差集。
注意

Operator 组所造成的故障状态不是终端状态。

每次 Operator 组同步时都会执行以下操作:

  • 来自活跃成员 CSV 的提供的 API 集是通过集群计算出来的。注意,复制的 CSV 会被忽略。
  • 将集群集与 olm.providedAPIs 进行比较,如果 olm.providedAPIs 包含任何额外 API,则将删除这些 API。
  • 在所有命名空间中提供相同 API 的所有 CSV 均会重新排序。这样可向交集组中的冲突 CSV 发送通知,表明可能已通过调整大小或删除冲突的 CSV 解决了冲突。

2.4.5.10. 多租户 Operator 管理的限制

OpenShift Container Platform 支持在同一集群中安装不同版本的 Operator。Operator Lifecycle Manager (OLM) 会在不同的命名空间中多次安装 Operator。其中一个限制是 Operator 的 API 版本必须相同。

Operator 是控制平面的扩展,因为它们使用了 CustomResourceDefinition 对象 (CRD),它们是 Kubernetes 中的全局资源。一个 Operator 的不同主版本通常具有不兼容的 CRD。这使得它们不兼容,可以在集群中的不同命名空间中安装。

所有租户或命名空间共享同一集群的 control plane。因此,多租户集群中的租户也共享全局 CRD,这限制同一集群中可以并行使用同一 Operator 实例的不同 Operator 实例。

支持的场景包括:

  • 提供相同 CRD 定义的不同版本的 Operator (如果版本化 CRD,则完全相同的版本)
  • 没有提供 CRD 的不同版本的 Operator,并在 OperatorHub 上的单独捆绑包中提供它们的 CRD

不支持所有其他场景,因为如果不同 Operator 版本中的多个竞争或重叠 CRD 在同一集群中协调,则无法保证集群数据的完整性。

2.4.5.11. 对 Operator 组进行故障排除

成员资格
  • 安装计划的命名空间必须只包含一个 Operator 组。当尝试在命名空间中生成集群服务版本(CSV)时,安装计划会认为一个 Operator 组在以下情况下无效:

    • 安装计划的命名空间中没有 Operator 组。
    • 安装计划的命名空间中存在多个 Operator 组。
    • 在 Operator 组中指定不正确或不存在的服务帐户名称。

    如果安装计划遇到无效的 Operator 组,则不会生成 CSV,InstallPlan 资源将继续使用相关消息进行安装。例如,如果同一命名空间中存在多个 Operator 组,则会提供以下信息:

    attenuated service account query failed - more than one operator group(s) are managing this namespace count=2

    其中 count= 指定命名空间中的 Operator 组数量。

  • 如果 CSV 的安装模式不支持其命名空间中 Operator 组的目标命名空间选择,CSV 会转变为故障状态,原因为 UnsupportedOperatorGroup。处于故障状态的 CSV 会在 Operator 组的目标命名空间选择变为受支持的配置后转变为待处理,或者 CSV 的安装模式被修改来支持目标命名空间选择。

2.4.6. 多租户和 Operator 共处

本指南概述了 Operator Lifecycle Manager (OLM) 中的多租户和 Operator 共处。

2.4.6.1. 命名空间中的 Operator 共处

Operator Lifecycle Manager (OLM) 处理在同一命名空间中安装的 OLM 管理的 Operator,这意味着其 Subscription 资源与相关 Operator 位于同一个命名空间中。即使它们实际不相关,OLM 会在更新其中任何一个时考虑其状态,如它们的版本和更新策略。

这个默认行为清单可以通过两种方式:

  • 待处理的更新的 InstallPlan 资源包括同一命名空间中的所有其他 Operator 的 ClusterServiceVersion (CSV) 资源。
  • 同一命名空间中的所有 Operator 都共享相同的更新策略。例如,如果一个 Operator 设置为手动更新,则所有其他 Operator 更新策略也会设置为 manual。

这些场景可能会导致以下问题:

  • 很难了解有关 Operator 更新安装计划的原因,因为它们中定义了除更新 Operator 以外的更多资源。
  • 在命名空间更新中,无法自动更新一些 Operator,而其他 Operator 也无法手动更新,这对集群管理员来说很常见。

这些问题通常是在使用 OpenShift Container Platform Web 控制台安装 Operator 时,默认行为会将支持 All namespaces 安装模式的 Operator 安装到默认的 openshift-operators 全局命名空间中。

作为集群管理员,您可以使用以下工作流手动绕过此默认行为:

  1. 为 Operator 的安装创建一个命名空间。
  2. 创建自定义 全局 Operator 组,这是监视所有命名空间的 Operator 组。通过将此 Operator 组与您刚才创建的命名空间关联,从而使安装命名空间成为全局命名空间,从而使 Operator 在所有命名空间中都可用。
  3. 在安装命名空间中安装所需的 Operator。

如果 Operator 具有依赖项,依赖项会在预先创建的命名空间中自动安装。因此,它对依赖项 Operator 有效,使其具有相同的更新策略和共享安装计划。具体步骤,请参阅“在自定义命名空间中安装全局 Operator"。

2.4.7. Operator 条件

本指南概述了 Operator Lifecycle Manager(OLM)如何使用 Operator 条件。

2.4.7.1. 关于 Operator 条件

作为管理 Operator 生命周期的角色的一部分,Operator Lifecycle Manager(OLM)从定义 Operator 的 Kubernetes 资源状态中推断 Operator 状态。虽然此方法提供了一定程度的保证来确定 Operator 处于给定状态,但在有些情况下,Operator 可能需要直接向 OLM 提供信息,而这些信息不能被推断出来。这些信息可以被 OLM 使用来更好地管理 Operator 的生命周期。

OLM 提供了一个名为 OperatorCondition 的自定义资源定义(CRD),它允许 Operator 与 OLM 相互通信条件信息。当在一个 OperatorCondition 资源的 Spec.Conditions 数组中存在时,则代表存在一组会影响 OLM 管理 Operator 的支持条件。

注意

默认情况下,OperatorCondition 对象中没有 Spec.Conditions 数组,直到由用户添加或使用自定义 Operator 逻辑的结果为止。

2.4.7.2. 支持的条件

Operator Lifecycle Manager(OLM)支持以下 Operator 条件。

2.4.7.2.1. Upgradeable(可升级)条件

Upgradeable Operator 条件可防止现有集群服务版本(CSV)被 CSV 的新版本替换。这一条件在以下情况下很有用:

  • Operator 即将启动关键进程,不应在进程完成前升级。
  • Operator 正在执行一个自定义资源(CR)迁移,这个迁移必须在 Operator 准备进行升级前完成。
重要

Upgradeable Operator 条件设置为 False 值不会避免 pod 中断。如果需要确保 pod 没有中断,请参阅"使用 pod 中断预算来指定必须在线的 pod 数量,以及 "Additional resources" 部分的 "Graceful termination"。

Upgradeable Operator 条件

apiVersion: operators.coreos.com/v1
kind: OperatorCondition
metadata:
  name: my-operator
  namespace: operators
spec:
  conditions:
  - type: Upgradeable 1
    status: "False" 2
    reason: "migration"
    message: "The Operator is performing a migration."
    lastTransitionTime: "2020-08-24T23:15:55Z"

1
条件的名称。
2
False 值表示 Operator 未准备好升级。OLM 可防止替换 Operator 现有 CSV 的 CSV 离开Pending 状态。False 值不会阻止集群升级。

2.4.7.3. 其他资源

2.4.8. Operator Lifecycle Manager 指标数据

2.4.8.1. 公开的指标

Operator Lifecycle Manager(OLM)会公开某些 OLM 特定资源,供基于 Prometheus 的 OpenShift Container Platform 集群监控堆栈使用。

表 2.7. OLM 公开的指标

名称描述

catalog_source_count

目录源数量。

catalogsource_ready

目录源的状态。值 1 表示目录源处于 READY 状态。0 表示目录源没有处于 READY 状态。

csv_abnormal

在协调集群服务版本(CSV)时,每当 CSV 版本处于 Succeeded 以外的任何状态时(如没有安装它时)就会存在。包括 namenamespacephasereasonversion 标签。当存在此指标数据时会创建一个 Prometheus 警报。

csv_count

成功注册的 CSV 数量。

csv_succeeded

在协调 CSV 时,代表 CSV 版本处于 Succeeded 状态(值为 1)或没有处于这个状态(值为 0)。包含 namenamespaceversion 标签。

csv_upgrade_count

CSV 升级的 Monotonic 计数。

install_plan_count

安装计划的数量。

installplan_warnings_total

由资源生成的警告数量(如已弃用资源)包含在安装计划中。

olm_resolution_duration_seconds

依赖项解析尝试的持续时间。

subscription_count

订阅数。

subscription_sync_total

订阅同步的单调计数。包括 channelinstalled CSV 和订阅 name 标签。

2.4.9. Operator Lifecycle Manager 中的 Webhook 管理

Webhook 允许 Operator 作者在资源被保存到对象存储并由 Operator 控制器处理之前,拦截、修改、接受或拒绝资源。当 webhook 与 Operator 一同提供时,Operator Lifecycle Manager(OLM)可以管理这些 webhook 的生命周期。

如需有关 Operator 开发人员如何为其 Operator 定义 webhook,以及 OLM 上运行时的注意事项的详细信息,请参阅定义集群服务版本(CSV)

2.4.9.1. 其他资源