4.9. 管理自定义目录

集群管理员和 Operator 目录维护人员可以使用 OpenShift Container Platform 的 Operator Lifecycle Manager (OLM) 上的捆绑包格式创建和管理打包的自定义目录。

重要

Kubernetes 定期弃用后续版本中删除的某些 API。因此,从使用删除 API 的 Kubernetes 版本的 OpenShift Container Platform 版本开始,Operator 无法使用删除 API 的 API。

如果您的集群使用自定义目录,请参阅控制 Operator 与 OpenShift Container Platform 版本的兼容性,以了解更多有关 Operator 作者如何更新其项目的详细信息,以帮助避免工作负载问题并防止不兼容的升级。

4.9.1. 先决条件

4.9.2. 基于文件的目录

基于文件的目录是 Operator Lifecycle Manager (OLM) 中目录格式的最新迭代。它是基于纯文本(JSON 或 YAML)和早期 SQLite 数据库格式的声明式配置演变,并且完全向后兼容。

如需有关基于文件的目录规格的更多详情,请参阅 Operator Framework 打包格式

4.9.2.1. 创建基于文件的目录镜像

您可以创建一个目录镜像,它 使用基于纯文本文件的目录 格式(JSON 或 YAML),替换已弃用的 SQLite 数据库格式。opm CLI 提供了有助于以基于文件的格式初始化目录、呈现新记录到其中的工具,并验证目录是否有效。

先决条件

  • opm
  • podman 版本 1.9.3+
  • 构建并推送到支持 Docker v2-2 的 registry 的捆绑包镜像

流程

  1. 为基于文件的目录初始化目录:

    1. 为目录创建一个目录:

      $ mkdir <operator_name>-index
    2. 创建可构建目录镜像的 Dockerfile:

      <operator_name>-index.Dockerfile示例

      # The base image is expected to contain
      # /bin/opm (with a serve subcommand) and /bin/grpc_health_probe
      FROM registry.redhat.io/openshift4/ose-operator-registry:v4.9
      
      # Configure the entrypoint and command
      ENTRYPOINT ["/bin/opm"]
      CMD ["serve", "/configs"]
      
      # Copy declarative config root into image at /configs
      ADD <operator_name>-index /configs
      
      # Set DC-specific label for the location of the DC root directory
      # in the image
      LABEL operators.operatorframework.io.index.configs.v1=/configs

      Dockerfile 必须与您在上一步中创建的目录目录位于相同的父目录中:

      目录结构示例

      .
      ├── <operator_name>-index
      └── <operator_name>-index.Dockerfile

    3. 使用软件包定义填充目录:

      $ opm init <operator_name> \ 1
          --default-channel=preview \ 2
          --description=./README.md \ 3
          --icon=./operator-icon.svg \ 4
          --output yaml \ 5
          > <operator_name>-index/index.yaml 6
      1
      operator,或软件包、名称。
      2
      如果未指定,则该订阅将默认为 频道。
      3
      Operator 的 README.md 或者其它文档的路径。
      4
      Operator 图标的路径。
      5
      输出格式:JSON 或 YAML。
      6
      创建目录配置文件的路径。

      此命令在指定的目录配置文件中生成 olm.package 声明性配置 blob。

  2. 在目录中添加捆绑包:

    $ opm render <registry>/<namespace>/<bundle_image_name>:<tag> \ 1
        --output=yaml \
        >> <operator_name>-index/index.yaml 2
    1
    拉取捆绑包镜像的 spec。
    2
    目录配置文件的路径。

    opm rendered 命令从提供的目录镜像和捆绑包镜像生成声明性配置 blob。

    注意

    频道必须至少包含一个捆绑包。

  3. 为捆绑包添加频道条目。例如,根据您的规格修改以下示例,并将其添加到 <operator_name>-index/index.yaml 文件中:

    频道条目示例

    ---
    schema: olm.channel
    package: <operator_name>
    name: preview
    entries:
      - name: <operator_name>.v0.1.0 1

    1
    确定在 <operator_name> 之后、版本 v 中包含句点 (.)。否则,该条目将无法通过 opm validate 命令。
  4. 验证基于文件的目录:

    1. 针对目录目录运行 opm validate 命令:

      $ opm validate <operator_name>-index
    2. 检查错误代码是否为 0:

      $ echo $?

      输出示例

      0

  5. 构建目录镜像:

    $ podman build . \
        -f <operator_name>-index.Dockerfile \
        -t <registry>/<namespace>/<catalog_image_name>:<tag>
  6. 将目录镜像推送到 registry:

    1. 如果需要,与目标 registry 进行身份验证:

      $ podman login <registry>
    2. 推送目录镜像:

      $ podman push <registry>/<namespace>/<catalog_image_name>:<tag>

4.9.3. 基于 SQLite 的目录

重要

Operator 目录的 SQLite 数据库格式是一个弃用的功能。弃用的功能仍然包含在 OpenShift Container Platform 中,并将继续被支持。但是,这个功能会在以后的发行版本中被删除,且不建议在新的部署中使用。

有关 OpenShift Container Platform 中已弃用或删除的主要功能的最新列表,请参阅 OpenShift Container Platform 发行注记中已弃用和删除的功能部分。

4.9.3.1. 创建基于 SQLite 的索引镜像

您可以使用 opm CLI 根据 SQLite 数据库格式创建索引镜像。

先决条件

  • opm
  • podman 版本 1.9.3+
  • 构建并推送到支持 Docker v2-2 的 registry 的捆绑包镜像

流程

  1. 启动一个新的索引:

    $ opm index add \
        --bundles <registry>/<namespace>/<bundle_image_name>:<tag> \1
        --tag <registry>/<namespace>/<index_image_name>:<tag> \2
        [--binary-image <registry_base_image>] 3
    1
    要添加到索引中的捆绑包镜像以逗号分隔的列表。
    2
    希望索引镜像具有的镜像标签。
    3
    可选:用于为目录提供服务的备选 registry 基础镜像。
  2. 将索引镜像推送到 registry。

    1. 如果需要,与目标 registry 进行身份验证:

      $ podman login <registry>
    2. 推送索引镜像:

      $ podman push <registry>/<namespace>/<index_image_name>:<tag>

4.9.3.2. 更新基于 SQLite 的索引镜像

在将 OperatorHub 配置为使用引用自定义索引镜像的目录源后,集群管理员可通过将捆绑包镜像添加到索引镜像来保持其集群上的可用 Operator 最新状态。

您可以使用 opm index add 命令来更新存在的索引镜像。

先决条件

  • opm
  • podman 版本 1.9.3+
  • 构建并推送到 registry 的索引镜像。
  • 引用索引镜像的现有目录源。

流程

  1. 通过添加捆绑包镜像来更新现有索引:

    $ opm index add \
        --bundles <registry>/<namespace>/<new_bundle_image>@sha256:<digest> \1
        --from-index <registry>/<namespace>/<existing_index_image>:<existing_tag> \2
        --tag <registry>/<namespace>/<existing_index_image>:<updated_tag> \3
        --pull-tool podman 4
    1
    --bundles 标志指定要添加到索引中的、以逗号分隔的额外捆绑包镜像列表。
    2
    --from-index 标志指定之前推送的索引。
    3
    --tag 标志指定要应用到更新的索引镜像的镜像标签。
    4
    --pull-tool 标志指定用于拉取容器镜像的工具。

    其中:

    <registry>
    指定 registry 的主机名,如 quay.iomirror.example.com
    <namespace>
    指定 registry 的命名空间,如 ocs-devabc
    <new_bundle_image>
    指定要添加到 registry 的新捆绑包镜像,如 ocs-operator
    <digest>
    指定捆绑包镜像的 SHA 镜像 ID 或摘要,如 c7f11097a628f092d8bad148406aa0e0951094a03445fd4bc0775431ef683a41
    <existing_index_image>
    指定之前推送的镜像,如 abc-redhat-operator-index
    <existing_tag>
    指定之前推送的镜像标签,如 4.10
    <updated_tag>
    指定要应用到更新的索引镜像的镜像标签,如 4.10.1

    示例命令

    $ opm index add \
        --bundles quay.io/ocs-dev/ocs-operator@sha256:c7f11097a628f092d8bad148406aa0e0951094a03445fd4bc0775431ef683a41 \
        --from-index mirror.example.com/abc/abc-redhat-operator-index:4.10 \
        --tag mirror.example.com/abc/abc-redhat-operator-index:4.10.1 \
        --pull-tool podman

  2. 推送更新的索引镜像:

    $ podman push <registry>/<namespace>/<existing_index_image>:<updated_tag>
  3. Operator Lifecycle Manager(OLM)会在常规时间段内自动轮询目录源中引用的索引镜像,验证是否已成功添加新软件包:

    $ oc get packagemanifests -n openshift-marketplace

4.9.3.3. 过滤基于 SQLite 的索引镜像

基于 Operator Bundle Format 的索引镜像是 Operator 目录的容器化快照。您可以过滤或 prune(修剪)除指定的软件包列表以外的所有索引,创建只包含您想要的 Operator 的源索引副本。

先决条件

  • podman 版本 1.9.3+
  • grpcurl (第三方命令行工具)
  • opm
  • 访问支持 Docker v2-2 的 registry

流程

  1. 通过目标 registry 进行身份验证:

    $ podman login <target_registry>
  2. 确定您要包括在您的修剪索引中的软件包列表。

    1. 运行您要修剪容器中的源索引镜像。例如:

      $ podman run -p50051:50051 \
          -it registry.redhat.io/redhat/redhat-operator-index:v4.10

      输出示例

      Trying to pull registry.redhat.io/redhat/redhat-operator-index:v4.10...
      Getting image source signatures
      Copying blob ae8a0c23f5b1 done
      ...
      INFO[0000] serving registry                              database=/database/index.db port=50051

    2. 在一个单独的终端会话中,使用 grpcurl 命令获取由索引提供的软件包列表:

      $ grpcurl -plaintext localhost:50051 api.Registry/ListPackages > packages.out
    3. 检查 package.out 文件,确定要保留在此列表中的哪个软件包名称。例如:

      软件包列表片断示例

      ...
      {
        "name": "advanced-cluster-management"
      }
      ...
      {
        "name": "jaeger-product"
      }
      ...
      {
      {
        "name": "quay-operator"
      }
      ...

    4. 在您执行 podman run 命令的终端会话中,按 CtrlC 停止容器进程。
  3. 运行以下命令来修剪指定软件包以外的所有源索引:

    $ opm index prune \
        -f registry.redhat.io/redhat/redhat-operator-index:v4.10 \1
        -p advanced-cluster-management,jaeger-product,quay-operator \2
        [-i registry.redhat.io/openshift4/ose-operator-registry:v4.9] \3
        -t <target_registry>:<port>/<namespace>/redhat-operator-index:v4.10 4
    1
    到修剪的索引。
    2
    要保留的软件包用逗号隔开。
    3
    只适用于 IBM Power 和 IBM Z 镜像: Operator Registry 基础镜像和与目标 OpenShift Container Platform 集群主版本和次版本匹配的标签。
    4
    用于正在构建新索引镜像的自定义标签。
  4. 运行以下命令将新索引镜像推送到目标 registry:

    $ podman push <target_registry>:<port>/<namespace>/redhat-operator-index:v4.10

    其中 <namespace> 是 registry 上的任何现有命名空间。

4.9.4. 在集群中添加目录源

将目录源添加到 OpenShift Container Platform 集群可为用户发现和安装 Operator。集群管理员可以创建一个 CatalogSource 对象来引用索引镜像。OperatorHub 使用目录源来填充用户界面。

先决条件

  • 构建并推送到 registry 的索引镜像。

流程

  1. 创建一个 CatalogSource 对象来引用索引镜像。

    1. 根据您的规格修改以下内容,并将它保存为 catalogSource.yaml 文件:

      apiVersion: operators.coreos.com/v1alpha1
      kind: CatalogSource
      metadata:
        name: my-operator-catalog
        namespace: openshift-marketplace 1
        annotations:
          olm.catalogImageTemplate: 2
            "<registry>/<namespace>/<index_image_name>:v{kube_major_version}.{kube_minor_version}.{kube_patch_version}"
      spec:
        sourceType: grpc
        image: <registry>/<namespace>/<index_image_name>:<tag> 3
        displayName: My Operator Catalog
        publisher: <publisher_name> 4
        updateStrategy:
          registryPoll: 5
            interval: 30m
      1
      如果您希望目录源对所有命名空间中的用户全局可用,请指定 openshift-marketplace 命名空间。否则,您可以指定一个不同的命名空间来对目录进行作用域并只对该命名空间可用。
      2
      可选:将 olm.catalogImageTemplate 注解设置为索引镜像名称,并使用一个或多个 Kubernetes 集群版本变量,如为镜像标签构建模板时所示。
      3
      指定索引镜像。如果您在镜像名称后指定了标签,如 :v4.10,则目录源 Pod 会使用镜像 pull 策略 Always,这意味着 pod 始终在启动容器前拉取镜像。如果您指定了摘要,如 @sha256:<id>,则镜像拉取策略为 IfNotPresent,这意味着仅在节点上不存在的镜像时才拉取镜像。
      4
      指定发布目录的名称或机构名称。
      5
      目录源可以自动检查新版本以保持最新。
    2. 使用该文件创建 CatalogSource 对象:

      $ oc apply -f catalogSource.yaml
  2. 确定成功创建以下资源。

    1. 检查 pod:

      $ oc get pods -n openshift-marketplace

      输出示例

      NAME                                    READY   STATUS    RESTARTS  AGE
      my-operator-catalog-6njx6               1/1     Running   0         28s
      marketplace-operator-d9f549946-96sgr    1/1     Running   0         26h

    2. 检查目录源:

      $ oc get catalogsource -n openshift-marketplace

      输出示例

      NAME                  DISPLAY               TYPE PUBLISHER  AGE
      my-operator-catalog   My Operator Catalog   grpc            5s

    3. 检查软件包清单:

      $ oc get packagemanifest -n openshift-marketplace

      输出示例

      NAME                          CATALOG               AGE
      jaeger-product                My Operator Catalog   93s

现在,您可以在 OpenShift Container Platform Web 控制台中通过 OperatorHub 安装 Operator。

4.9.5. 从私有 registry 访问 Operator 的镜像

如果与 Operator Lifecycle Manager(OLM)管理的 Operator 相关的某些镜像托管在需要经过身份验证的容器镜像 registry(也称为私有 registry)中时,在默认情况下,OLM 和 OperatorHub 将无法拉取镜像。要启用访问权限,可以创建一个包含 registry 验证凭证的 pull secret。通过引用一个或多个目录源的 pull secret,OLM 可以处理将 secret 放置到 Operator 和目录命名空间中以允许进行安装。

Operator 或其 Operands 所需的其他镜像可能会需要访问私有 registry。对于这种情况,OLM 不处理将 secret 放置到目标租户命名空间中,但身份验证凭证可以添加到全局范围集群 pull secret 中,或单独的命名空间服务帐户中,以启用所需的访问权限。

在决定由 OLM 管理的 Operator 是否有适当的拉取访问权限时,应该考虑以下类型的镜像:

索引镜像
CatalogSource 对象可以引用索引镜像,该镜像使用 Operator 捆绑包格式,并作为托管在镜像 registry 中的容器镜像的目录源打包。如果索引镜像托管在私有 registry 中,可以使用 secret 来启用拉取访问。
捆绑包镜像
Operator 捆绑包镜像是元数据和清单,并被打包为容器镜像,代表 Operator 的一个特定版本。如果目录源中引用的任何捆绑包镜像托管在一个或多个私有 registry 中,可以使用一个 secret 来启用拉取(pull)访问。
Operator 和 Operand 镜像

如果从目录源安装的 Operator 使用私有镜像,对于 Operator 镜像本身或它监视的 Operand 镜像之一,Operator 将无法安装,因为部署无法访问所需的 registry 身份验证。在目录源中引用 secret 不会使 OLM 将 secret 放置到安装 Operands 的目标租户命名空间中。

相反,身份验证详情被添加到 openshift-config 命名空间中的全局集群 pull secret 中,该 secret 提供对集群上所有命名空间的访问。另外,如果不允许访问整个集群,则可将 pull secret 添加到目标租户命名空间的 default 服务帐户中。

先决条件

  • 至少以下之一被托管在私有 registry 中:

    • 一个索引镜像或目录镜像。
    • 一个 Operator 捆绑包镜像。
    • 一个 Operator 或 Operand 镜像。

流程

  1. 为每个必需的私有 registry 创建 secret。

    1. 登录到私有 registry 以创建或更新 registry 凭证文件:

      $ podman login <registry>:<port>
      注意

      registry 凭证的文件路径可能会根据用于登录到 registry 的容器工具的不同而有所不同。对于 podman CLI,默认位置为 ${XDG_RUNTIME_DIR}/containers/auth.json。对于 docker CLI,默认位置为 /root/.docker/config.json

    2. 建议您为每个 secret 只包含一个 registry 的凭证,并在单独的 secret 中为多个 registry 管理凭证。后续步骤中的 CatalogSource 可包括多个 secret,OpenShift Container Platform 会将这些 secret 合并为一个单独的虚拟凭证文件,以便在镜像拉取过程中使用。

      默认情况下,registry 凭证文件可以在一个 registry 中存储多个 registry 或多个存储库的详细信息。确认您的文件的当前内容。例如:

      为多个 registry 存储凭证的文件

      {
          "auths": {
              "registry.redhat.io": {
                  "auth": "FrNHNydQXdzclNqdg=="
              },
              "quay.io": {
                  "auth": "fegdsRib21iMQ=="
              },
              "https://quay.io/my-namespace/my-user/my-image": {
                  "auth": "eWfjwsDdfsa221=="
              },
              "https://quay.io/my-namespace/my-user": {
                  "auth": "feFweDdscw34rR=="
              },
              "https://quay.io/my-namespace": {
                  "auth": "frwEews4fescyq=="
              }
          }
      }

      由于此文件用于后续步骤中创建 secret,请确保为每个文件只存储一个 registry 的详情。这可使用以下方法之一完成:

      • 使用 podman logout <registry> 命令为额外 registry 删除凭证,直到您只保留一个 registry。
      • 编辑 registry 凭证文件,将 registry 详情分开以存储在多个文件中。例如:

        为一个 registry 存储凭证的文件

        {
                "auths": {
                        "registry.redhat.io": {
                                "auth": "FrNHNydQXdzclNqdg=="
                        }
                }
        }

        为另一个 registry 存储凭证的文件

        {
                "auths": {
                        "quay.io": {
                                "auth": "Xd2lhdsbnRib21iMQ=="
                        }
                }
        }

    3. openshift-marketplace 命名空间中创建 secret,其中包含私有 registry 的身份验证凭证:

      $ oc create secret generic <secret_name> \
          -n openshift-marketplace \
          --from-file=.dockerconfigjson=<path/to/registry/credentials> \
          --type=kubernetes.io/dockerconfigjson

      重复此步骤,为任何其他需要的私有 registry 创建额外的 secret,更新 --from-file 标志以指定另一个 registry 凭证文件路径。

  2. 创建或更新现有的 CatalogSource 对象以引用一个或多个 secret:

    apiVersion: operators.coreos.com/v1alpha1
    kind: CatalogSource
    metadata:
      name: my-operator-catalog
      namespace: openshift-marketplace
    spec:
      sourceType: grpc
      secrets: 1
      - "<secret_name_1>"
      - "<secret_name_2>"
      image: <registry>:<port>/<namespace>/<image>:<tag>
      displayName: My Operator Catalog
      publisher: <publisher_name>
      updateStrategy:
        registryPoll:
          interval: 30m
    1
    添加 spec.secrets 部分并指定任何所需 secret。
  3. 如果订阅的 Operator 引用的任何 Operator 或 Operand 镜像需要访问私有 registry,您可以提供对集群中的所有命名空间或单独的目标租户命名空间的访问。

    • 要访问集群中的所有命名空间,请将身份验证详情添加到 openshift-config 命名空间中的全局集群 pull secret 中。

      警告

      集群资源必须调整为新的全局 pull secret,这样可暂时限制集群的可用性。

      1. 从全局 pull secret 中提取 .dockerconfigjson 文件:

        $ oc extract secret/pull-secret -n openshift-config --confirm
      2. 使用所需私有 registry 或 registry 的身份验证凭证更新 .dockerconfigjson 文件,并将它保存为新文件:

        $ cat .dockerconfigjson | \
            jq --compact-output '.auths["<registry>:<port>/<namespace>/"] |= . + {"auth":"<token>"}' \1
            > new_dockerconfigjson
        1
        <registry>:<port> /<namespace> 替换为私有 registry 的详情,将 <token> 替换为您的身份验证凭证。
      3. 使用新文件更新全局 pull secret:

        $ oc set data secret/pull-secret -n openshift-config \
            --from-file=.dockerconfigjson=new_dockerconfigjson
    • 要更新单个命名空间,请向 Operator 的服务帐户添加一个 pull secret,以便在目标租户命名空间中访问该 Operator。

      1. 在租户命名空间中为 openshift-marketplace 重新创建 secret:

        $ oc create secret generic <secret_name> \
            -n <tenant_namespace> \
            --from-file=.dockerconfigjson=<path/to/registry/credentials> \
            --type=kubernetes.io/dockerconfigjson
      2. 通过搜索租户命名空间来验证 Operator 的服务帐户名称:

        $ oc get sa -n <tenant_namespace> 1
        1
        如果 Operator 安装在单独的命名空间中,请搜索该命名空间。如果 Operator 已为所有命名空间安装,请搜索 openshift-operators 命名空间。

        输出示例

        NAME            SECRETS   AGE
        builder         2         6m1s
        default         2         6m1s
        deployer        2         6m1s
        etcd-operator   2         5m18s 1

        1
        已安装的 etcd Operator 的服务帐户。
      3. 将 secret 链接到 Operator 的服务帐户:

        $ oc secrets link <operator_sa> \
            -n <tenant_namespace> \
             <secret_name> \
            --for=pull

其他资源

4.9.6. 禁用默认的 OperatorHub 源

在 OpenShift Container Platform 安装过程中,默认为 OperatorHub 配置由红帽和社区项目提供的源内容的 operator 目录。作为集群管理员,您可以禁用默认目录集。

流程

  • 通过在 OperatorHub 对象中添加 disableAllDefaultSources: true 来 禁用默认目录的源:

    $ oc patch OperatorHub cluster --type json \
        -p '[{"op": "add", "path": "/spec/disableAllDefaultSources", "value": true}]'
提示

或者,您可以使用 Web 控制台管理目录源。在 AdministrationCluster SettingsConfigurationOperatorHub 页面中,点 Sources 选项卡,您可以在其中创建、删除、禁用和启用单独的源。

4.9.7. 删除自定义目录

作为集群管理员,您可以删除之前添加到集群中的自定义 Operator 目录,方法是删除相关的目录源。

流程

  1. 在 Web 控制台的 Administrator 视角中,导航到 AdministrationCluster Settings
  2. Configuration 选项卡,然后点 OperatorHub
  3. Sources 选项卡。
  4. 选择您要删除的目录的 Options 菜单 kebab ,然后点 Delete CatalogSource