11.4. 生成 ClusterServiceVersion (CSV)

ClusterServiceVersion (CSV) 是一个利用 Operator 元数据创建的 YAML 清单,可辅助 Operator Lifecycle Manager (OLM) 在集群中运行 Operator。它是 Operator 容器镜像附带的元数据,用于在用户界面填充徽标、描述和版本等信息。此外,CSV 还是运行 Operator 所需的技术信息来源,类似于其需要的 RBAC 规则及其管理或依赖的自定义资源 (CR)。

Operator SDK 中包含 olm-catalog gen-csv 子命令,用于通过手动定义的 YAML 清单和 Operator 源文件中包含的信息为自定义的当前 Operator 项目生成 ClusterServiceVersion (CSV)。

借助生成 CSV 的命令,Operator 作者便无需深入掌握为了让其 Operator 与 Operator Lifecycle Manager (OLM) 交互或向 Catalog Registry 发布元数据所需的 OLM 知识。此外,因为实现了新的 Kubernetes 和 OLM 功能,CSV spec 可能会随着时间的推移而有所变化,而 Operator SDK 可轻松扩展其更新系统,以应对 CSV 的未来新功能。

CSV 版本与 Operator 的版本相同,在升级 Operator 版本的同时会生成新 CSV。Operator 作者可使用 --csv-version 标记将其 Operator 状态与所提供的语义版本一起封装至 CSV 中:

$ operator-sdk olm-catalog gen-csv --csv-version <version>

此操作采用等幂方式,仅会在提供新版本或更改 YAML 清单或源文件时才会更新 CSV 文件。Operator 作者不必直接修改 CSV 清单中的大部分字段。本指南中已经明确了需要修改的字段。例如:metadata.name 中必须包含 CSV 版本信息。

11.4.1. CSV 生成的工作方式

Operator 项目的 deploy/ 目录是部署 Operator 需要的所有清单的标准位置。Operator SDK 可使用 deploy/ 中的清单数据来编写 CSV。以下命令:

$ operator-sdk olm-catalog gen-csv --csv-version <version>

默认将 CSV YAML 文件写入 deploy/olm-catalog/ 目录中。

生成 CSV 只需三类清单:

  • operator.yaml
  • *_{crd,cr}.yaml
  • RBAC 角色文件,如 role.yaml

Operator 作者对这些文件可能有不同的版本要求,并且可配置 deploy/olm-catalog/csv-config.yaml 中要包含哪些特定文件。

工作流

根据是否检测到了现有 CSV,并假设使用所有配置默认值,olm-catalog gen-csv 子命令将:

  • 使用 YAML 清单和源文件中的可用数据新建一个 CSV,其位置和命名约定与当前存在的信息相同。

    1. 该更新机制会检查 deploy/ 中是否存在现有 CSV。如果未找到,便会创建一个 ClusterServiceVersion 对象,这里称为 cache,并填充容易从 Operator 元数据派生的字段,如 Kubernetes API ObjectMeta
    2. 更新机制在 deploy/ 中搜索包含 CSV 所用数据(如 Deployment 资源)的清单,并使用该数据设置 cache 中的适当 CSV 字段。
    3. 搜索完成后,每个填充的 cache 字段都会写回到 CSV YAML 文件中。

或:

  • 使用 YAML 清单和源文件中的可用数据更新当前预定义位置的现有 CSV。

    1. 该更新机制会检查 deploy/ 中是否存在现有 CSV。找到后,CSV YAML 文件内容会被封送至 ClusterServiceVersion cache 中。
    2. 更新机制在 deploy/ 中搜索包含 CSV 所用数据(如 Deployment 资源)的清单,并使用该数据设置 cache 中的适当 CSV 字段。
    3. 搜索完成后,每个填充的 cache 字段都会写回到 CSV YAML 文件中。
注意

单个 YAML 字段(而非整个文件)会被覆盖,因为 CSV 的描述和其他未生成的部分将被保留。

11.4.2. CSV 组成配置

Operator 作者可通过填充 deploy/olm-catalog/csv-config.yaml 文件中的几个字段来配置 CSV 组成:

字段描述

operator-path (string)

Operator 资源清单文件路径。默认为 deploy/operator.yaml

crd-cr-path-list (string(, string)*)

CRD 和 CR 清单文件路径列表。默认为 [deploy/crds/*_{crd,cr}.yaml]

rbac-path-list (string(, string)*)

RBAC 角色清单文件路径列表。默认为 [deploy/role.yaml]

11.4.3. 手动定义的 CSV 字段

很多 CSV 字段无法使用生成的非 SDK 特定清单进行填充。这些字段大多由人工编写,是一些有关 Operator 和各种自定义资源定义 (CRD) 的英文元数据。

Operator 作者必须直接修改其 CSV YAML 文件,将个性化数据添加至以下必填字段。当检测到任何必填字段中缺少数据时,Operator SDK 就会发出一个 CSV 生成警告。

表 11.5. 必填

字段描述

metadata.name

该 CSV 的唯一名称。Operator 版本应包含在名称中,以保证唯一性,如 app-operator.v0.1.1

spec.displayName

用于标识 Operator 的公共名称。

spec.description

简单描述 Operator 的功能。

spec.keywords

描述 Operator 的关键词。

spec.maintainers

维护 Operator 的个人或组织实体,含名称电子邮件地址

spec.provider

Operator 供应商(通常为一个组织),含名称

spec.labels

供 Operator 内部使用的键值对。

spec.version

Operator 的语义版本,如 0.1.1

spec.customresourcedefinitions

Operator 使用的任何 CRD。如果 deploy/ 中存在任何 CRD YAML 文件,Operator SDK 将自动填充该字段。但 CRD 清单 spec 中没有的几个字段需要用户输入:

  • description:CRD 描述。
  • resources:CRD 利用的任何 Kubernetes 资源,如 Pod 和 StatefulSets。
  • specDescriptors:用于 Operator 输入和输出的 UI 提示。

表 11.6. 选填

字段描述

spec.replaces

被该 CSV 替换的 CSV 名称。

spec.links

与被管理的 Operator 或应用程序相关的 URL(如网站和文档),各自含名称url

spec.selector

Operator 可用于配对群集中资源的选择器。

spec.icon

Operator 独有的 base64 编码图标,通过 mediatypebase64data 字段中设置。

spec.maturity

根据 Operator 成熟度模型划分的 Operator 能力水平,如无缝升级

有关以上每个字段应包含哪些数据的更多详情,请参见 CSV spec

注意

当前需要用户干预的多个 YAML 字段可能会从 Operator 代码中解析出来;这种 Operator SDK 功能将在未来的设计文件中阐述。

11.4.4. 生成 CSV

先决条件

  • 使用 Operator SDK 生成一个 Operator 项目

流程

  1. 在 Operator 项目中,通过修改 deploy/olm-catalog/csv-config.yaml 文件来配置您的 CSV 组成(如果需要)。
  2. 生成 CSV:

    $ operator-sdk olm-catalog gen-csv --csv-version <version>
  3. deploy/olm-catalog/ 目录中生成的新 CSV 中,确保正确设置所有必填的手动定义字段。

11.4.5. 了解您的自定义资源定义 (CRD)

您的 Operator 可能会使用两类自定义资源定义 (CRD):一类归 Operator 拥有,另一类为 Operator 依赖的必要 CRD。

11.4.5.1. 拥有的 CRD

Operator 拥有的 CRD 是 CSV 最重要的组成部分。这类 CRD 会在您的 Operator 与所需 RBAC 规则、依赖项管理和其他 Kubernetes 概念之间建立联系。

Operator 通常会使用多个 CRD 将各个概念链接在一起,例如一个对象中的顶级数据库配置和另一对象中的 ReplicaSets 表示形式。这在 CSV 文件中应逐一列出。

表 11.7. 拥有的 CRD 字段

字段描述必填/选填

名称

CRD 的全名。

必填

Version

该对象 API 的版本。

必填

Kind

CRD 的机器可读名称。

必填

DisplayName

CRD 名称的人类可读版本,如 MongoDB Standalone

必填

描述

有关 Operator 如何使用该 CRD 的简短描述,或有关 CRD 所提供功能的描述。

必填

Group

该 CRD 所属的 API 组,如 database.example.com

选填

Resources

您的 CRD 可能拥有一类或多类 Kubernetes 对象。它们将在资源部分列出,用于告知用户他们可能需要排除故障的对象或如何连接至应用程序,如公开数据库的 Service 或 Ingress 规则。

建议仅列出对人重要的对象,而不必列出您编排的所有对象。例如,存储不应由用户修改的内部状态的 ConfigMaps 不应出现在此处。

选填

SpecDescriptorsStatusDescriptorsActionDescriptors

这些描述符是通过对终端用户来说最重要的 Operator 的某些输入或输出提示 UI 的一种方式。如果您的 CRD 包含用户必须提供的 Secret 或 ConfigMap 的名称,您可在此处指定。这些项目在兼容的 UI 中链接并突出显示。

共有以下三类描述符:

  • SpecDescriptors:引用对象 spec 块中的字段。
  • StatusDescriptors:引用对象 status 块中的字段。
  • ActionDescriptors:引用对象上可执行的操作。

所有描述符均接受以下字段:

  • DisplayName:Spec、Status 或 Action 的人类可读名称。
  • Description:有关 Spec、Status 或 Action 以及 Operator 如何使用它的简短描述。
  • Path:描述符描述的对象上字段的点分隔路径。
  • X-Descriptors:用于决定该描述符拥有哪些“功能”以及要使用哪个 UI 组件。有关 OpenShift Container Platform 的标准 React UI X-Descriptors 列表的信息,请参见 openshift/console 项目。

有关描述符的更多一般信息,请参见 openshift/console 项目。

选填

以下示例描述了一个 MongoDB Standalone CRD,要求某些用户以 Secret 和 ConfigMap 的形式输入,并编排 Service、StatefulSet、Pod 和 ConfigMap:

拥有的 CRD 示例

      - displayName: MongoDB Standalone
        group: mongodb.com
        kind: MongoDbStandalone
        name: mongodbstandalones.mongodb.com
        resources:
          - kind: Service
            name: ''
            version: v1
          - kind: StatefulSet
            name: ''
            version: v1beta2
          - kind: Pod
            name: ''
            version: v1
          - kind: ConfigMap
            name: ''
            version: v1
        specDescriptors:
          - description: Credentials for Ops Manager or Cloud Manager.
            displayName: Credentials
            path: credentials
            x-descriptors:
              - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Secret'
          - description: Project this deployment belongs to.
            displayName: Project
            path: project
            x-descriptors:
              - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap'
          - description: MongoDB version to be installed.
            displayName: Version
            path: version
            x-descriptors:
              - 'urn:alm:descriptor:com.tectonic.ui:label'
        statusDescriptors:
          - description: The status of each of the Pods for the MongoDB cluster.
            displayName: Pod Status
            path: pods
            x-descriptors:
              - 'urn:alm:descriptor:com.tectonic.ui:podStatuses'
        version: v1
        description: >-
          MongoDB Deployment consisting of only one host. No replication of
          data.

11.4.5.2. 必需的 CRD

是否依赖其他必需 CRD 完全可以自由选择,它们存在的目的只是为了缩小单个 Operator 的范围,并提供一种将多个 Operator 组合到一起来解决端到端用例的办法。

例如,一个 Operator 可设置一个应用程序并(从 etcd Operator)安装一个 etcd 集群以用于分布式锁定,以及一个 Postgres 数据库(来自 Postgres Operator)以用于数据存储。

Operator Lifecycle Manager (OLM) 对照集群中可用的 CRD 和 Operator 进行检查,以满足这些要求。如果找到合适的版本,Operator 将在所需命名空间中启动,并为每个 Operator 创建一个服务账户,以创建、监视和修改所需的 Kubernetes 资源。

表 11.8. 必需的 CRD 字段

字段描述必填/选填

名称

所需 CRD 的全称。

必填

Version

该对象 API 的版本。

必填

Kind

Kubernetes 对象类型。

必填

DisplayName

CRD 的人类可读版本。

必填

描述

概述该组件如何适合您的更大架构。

必填

必需的 CRD 示例

    required:
    - name: etcdclusters.etcd.database.coreos.com
      version: v1beta2
      kind: EtcdCluster
      displayName: etcd Cluster
      description: Represents a cluster of etcd nodes.

11.4.5.3. CRD 模板

Operator 用户需要了解哪个选项必填,哪个选项选填。您可为您的每个 CRD 提供模板,并以最小配置集作为名为 alm-examples 的注解。兼容 UI 会预先填充该模板,供用户进一步自定义。

该注解由一个 kind 列表组成,如 CRD 名称和对应的 Kubernetes 对象的 metadataspec

以下完整示例提供了 EtcdClusterEtcdBackupEtcdRestore 模板:

metadata:
  annotations:
    alm-examples: >-
      [{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]

11.4.6. 了解您的 API 服务

与 CRD 一样,您的 Operator 可使用两类 APIService:拥有的必需的

11.4.6.1. 拥有的 APIService

如果 CSV 拥有 APIService,它将负责描述为其提供支持的扩展 api-server 的部署及其提供的 group-version-kinds

APIService 由其提供的 group-version 唯一标识,且可多次列出,以表示其期望提供的不同类型。

表 11.9. 拥有的 APIService 字段

字段描述必填/选填

Group

由 APIService 提供的组,如 database.example.com

必填

Version

APIService 的版本,如 v1alpha1

必填

Kind

预期由 APIService 提供的类型。

必填

名称

所提供的 APIService 的复数名称

必填

DeploymentName

由您的 CSV 定义的部署名称,对应您的 APIService(对于拥有的 APIService 来说必填)。在 CSV 待定阶段,OLM Operator 会在您的 CSV InstallStrategy 中搜索具有匹配名称的部署 spec,如果未找到,则不会将 CSV 转换至安装就绪阶段。

必填

DisplayName

APIService 名称的人类可读版本,如 MongoDB Standalone

必填

描述

有关 Operator 如何使用该 APIService 的简短描述,或有关 APIService 所提供功能的描述。

必填

Resources

您的 APIService 可能拥有一类或多类 Kubernetes 对象。它们将在资源部分列出,用于告知用户他们可能需要排除故障的对象或如何连接至应用程序,如公开数据库的 Service 或 Ingress 规则。

建议仅列出对人重要的对象,而不必列出您编排的所有对象。例如,存储不应由用户修改的内部状态的 ConfigMaps 不应出现在此处。

选填

SpecDescriptorsStatusDescriptorsActionDescriptors

与拥有的 CRD 基本相同。

选填

11.4.6.1.1. APIService 资源创建

Operator Lifecycle Manager (OLM) 负责为每个唯一拥有的 APIService 创建或替换 Service 及 APIService 资源:

  • Service Pod 选择器从与 APIServiceDescription 的 DeploymentName 相匹配的 CSV 部署中复制。
  • 每次安装都会生成一个新的 CA 密钥/证书对,且 base64 编码的 CA 捆绑包会嵌入到相应 APIService 资源中。
11.4.6.1.2. APIService 服务证书

每当安装拥有的 APIService 时,OLM 均会处理服务密钥/证书对的生成。服务证书有一个包含所生成 Service 资源的主机名的 CN,并由嵌入至对应 APIService 资源中的 CA 捆绑包的私钥签名。

该证书作为类型 kubernetes.io/tls Secret 存储在部署命名空间中,一个名为 apiservice-cert 的卷会自动附加至 CSV 中与 APIServiceDescription 的 DeploymentName 字段相匹配的部署的 Volumes 部分中。

如果尚不存在,则具有匹配名称的 VolumeMount 也会附加至该部署的所有容器中。这样用户便可使用预期名称来定义 VolumeMount,以适应任何自定义路径要求。所生成的 VolumeMount 的默认路径为 /apiserver.local.config/certificates,具有相同路径的任何现有 VolumeMount 均会被替换掉。

11.4.6.2. 必需的 APIService

OLM 可保证所有必需的 CSV 均有可用 APIService,且所有预期的 group-version-kinds 在试图安装前均可发现。这样 CSV 便可依赖由 APIService 提供的、并非它拥有的特定类别。

表 11.10. 必需的 APIService 字段

字段描述必填/选填

Group

由 APIService 提供的组,如 database.example.com

必填

Version

APIService 的版本,如 v1alpha1

必填

Kind

预期由 APIService 提供的类型。

必填

DisplayName

APIService 名称的人类可读版本,如 MongoDB Standalone

必填

描述

有关 Operator 如何使用该 APIService 的简短描述,或有关 APIService 所提供功能的描述。

必填