×

Operator 开发人员可以利用 Operator SDK 中的 Ansible 支持来构建一个基于 Ansible 的 Memcached(一个分布式键值存储)Operator 示例,并管理其生命周期。本教程将逐步介绍以下流程

  • 创建 Memcached 部署

  • 确保部署大小与 Memcached 自定义资源 (CR) 规范中指定的大小相同

  • 使用状态写入器更新 Memcached CR 状态,其中包含 memcached Pod 的名称

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

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

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

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

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

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

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

此过程是通过使用 Operator Framework 的两个核心部分来完成的

Operator SDK

operator-sdk CLI 工具和 controller-runtime 库 API

Operator Lifecycle Manager (OLM)

在集群上安装、升级和基于角色的访问控制 (RBAC) Operator

先决条件

创建项目

使用 Operator SDK CLI 创建名为 memcached-operator 的项目。

步骤
  1. 为项目创建一个目录

    $ mkdir -p $HOME/projects/memcached-operator
  2. 更改为该目录

    $ cd $HOME/projects/memcached-operator
  3. 使用 ansible 插件运行 operator-sdk init 命令来初始化项目

    $ operator-sdk init \
        --plugins=ansible \
        --domain=example.com

PROJECT 文件

operator-sdk init 命令生成的几个文件里包含一个 Kubebuilder PROJECT 文件。从项目根目录运行的后续 operator-sdk 命令以及 help 输出会读取此文件,并知道项目类型是 Ansible。例如

domain: example.com
layout:
- ansible.sdk.operatorframework.io/v1
plugins:
  manifests.sdk.operatorframework.io/v2: {}
  scorecard.sdk.operatorframework.io/v2: {}
  sdk.x-openshift.io/v1: {}
projectName: memcached-operator
version: "3"

创建 API

使用 Operator SDK CLI 创建 Memcached API。

步骤
  • 运行以下命令创建具有组cache、版本v1和种类Memcached的 API

    $ operator-sdk create api \
        --group cache \
        --version v1 \
        --kind Memcached \
        --generate-role (1)
    1 生成 API 的 Ansible 角色。

创建 API 后,您的 Operator 项目将更新为以下结构

Memcached CRD

包含一个示例Memcached资源

管理器

通过使用以下程序协调集群状态与期望状态:

  • 一个协调器,可以是 Ansible 角色或剧本

  • 一个watches.yaml文件,它将Memcached资源连接到memcached Ansible 角色

修改管理器

更新您的 Operator 项目以提供协调逻辑(Ansible 角色的形式),该逻辑在每次创建、更新或删除Memcached资源时运行。

步骤
  1. 使用以下结构更新roles/memcached/tasks/main.yml文件

    ---
    - name: start memcached
      k8s:
        definition:
          kind: Deployment
          apiVersion: apps/v1
          metadata:
            name: '{{ ansible_operator_meta.name }}-memcached'
            namespace: '{{ ansible_operator_meta.namespace }}'
          spec:
            replicas: "{{size}}"
            selector:
              matchLabels:
                app: memcached
            template:
              metadata:
                labels:
                  app: memcached
              spec:
                containers:
                - name: memcached
                  command:
                  - memcached
                  - -m=64
                  - -o
                  - modern
                  - -v
                  image: "docker.io/memcached:1.4.36-alpine"
                  ports:
                    - containerPort: 11211

    memcached角色确保memcached部署存在并设置部署大小。

  2. 通过编辑roles/memcached/defaults/main.yml文件,为 Ansible 角色中使用的变量设置默认值。

    ---
    # defaults file for Memcached
    size: 1
  3. 使用以下结构更新config/samples/cache_v1_memcached.yaml文件中Memcached示例资源

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      labels:
        app.kubernetes.io/name: memcached
        app.kubernetes.io/instance: memcached-sample
        app.kubernetes.io/part-of: memcached-operator
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/created-by: memcached-operator
      name: memcached-sample
    spec:
      size: 3

    自定义资源 (CR) spec 中的键值对作为额外变量传递给 Ansible。

Operator 在运行 Ansible 之前,会将 spec 字段中所有变量的名称转换为蛇形命名法(小写字母加下划线)。例如,spec 中的serviceAccount在 Ansible 中变为service_account

您可以通过在watches.yaml文件中将snakeCaseParameters选项设置为false来禁用此大小写转换。建议您在 Ansible 中对变量执行一些类型验证,以确保您的应用程序正在接收预期的输入。

启用代理支持

Operator 作者可以开发支持网络代理的 Operator。集群管理员为 Operator Lifecycle Manager (OLM) 处理的环境变量配置代理支持。要支持使用代理的集群,您的 Operator 必须检查环境中是否存在以下标准代理变量并将值传递给 Operands

  • HTTP_PROXY

  • HTTPS_PROXY

  • NO_PROXY

本教程使用HTTP_PROXY作为示例环境变量。

先决条件
  • 启用了集群范围出口代理的集群。

步骤
  1. 通过使用以下内容更新roles/memcached/tasks/main.yml文件,将环境变量添加到部署中

    ...
    env:
       - name: HTTP_PROXY
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
       - name: http_proxy
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
    ...
  2. 通过向config/manager/manager.yaml文件添加以下内容,在 Operator 部署中设置环境变量

    containers:
     - args:
       - --leader-elect
       - --leader-election-id=ansible-proxy-demo
       image: controller:latest
       name: manager
       env:
         - name: "HTTP_PROXY"
           value: "http_proxy_test"

运行 Operator

您可以使用 Operator SDK CLI 来构建和运行您的 Operator,方法有三种:

  • 作为 Go 程序在集群外部本地运行。

  • 在集群上作为部署运行。

  • 打包您的 Operator 并使用 Operator Lifecycle Manager (OLM) 在集群上部署。

在集群外部本地运行

您可以在集群外部作为 Go 程序运行您的 Operator 项目。这对于开发目的很有用,可以加快部署和测试速度。

步骤
  • 运行以下命令以安装在您的~/.kube/config文件中配置的集群中的自定义资源定义 (CRD) 并本地运行 Operator

    $ make install run
    示例输出
    ...
    {"level":"info","ts":1612589622.7888272,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612589622.7897573,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612589622.789971,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612589622.7899997,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612589622.8904517,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612589622.8905244,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

在集群上作为部署运行

您可以在集群上作为部署运行您的 Operator 项目。

步骤
  1. 运行以下make命令来构建和推送 Operator 镜像。修改以下步骤中的IMG参数以引用您有权访问的存储库。您可以在 Quay.io 等存储库站点获取用于存储容器的帐户。

    1. 构建镜像

      $ make docker-build IMG=<registry>/<user>/<image_name>:<tag>

      SDK 为 Operator 生成的 Dockerfile 明确引用了用于go buildGOARCH=amd64。这可以修改为GOARCH=$TARGETARCH用于非 AMD64 架构。Docker 将自动将环境变量设置为–platform指定的 value。对于 Buildah,需要使用–build-arg。更多信息,请参阅 多架构

    2. 将镜像推送到存储库

      $ make docker-push IMG=<registry>/<user>/<image_name>:<tag>

      两个命令中的镜像名称和标签(例如IMG=<registry>/<user>/<image_name>:<tag>)也可以在您的 Makefile 中设置。修改IMG ?= controller:latest值以设置您的默认镜像名称。

  2. 运行以下命令部署 Operator

    $ make deploy IMG=<registry>/<user>/<image_name>:<tag>

    默认情况下,此命令创建一个名称为 Operator 项目名称的命名空间,形式为<project_name>-system,并用于部署。此命令还安装来自config/rbac的 RBAC 清单。

  3. 运行以下命令以验证 Operator 是否正在运行

    $ oc get deployment -n <project_name>-system
    示例输出
    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    <project_name>-controller-manager       1/1     1            1           8m

打包 Operator 并使用 Operator Lifecycle Manager 部署

打包 Operator

Operator 包格式是 Operator SDK 和 Operator Lifecycle Manager (OLM) 的默认打包方法。您可以使用 Operator SDK 将您的 Operator 项目构建并推送为包镜像,以使其准备好用于 OLM。

先决条件
  • 在开发工作站上安装了 Operator SDK CLI

  • 安装了 OpenShift CLI (oc) v4.17+

  • 使用 Operator SDK 初始化了 Operator 项目

步骤
  1. 在您的 Operator 项目目录中运行以下make命令以构建和推送您的 Operator 镜像。修改以下步骤中的IMG参数以引用您有权访问的存储库。您可以在 Quay.io 等存储库站点获取用于存储容器的帐户。

    1. 构建镜像

      $ make docker-build IMG=<registry>/<user>/<operator_image_name>:<tag>

      SDK 为 Operator 生成的 Dockerfile 明确引用了用于go buildGOARCH=amd64。这可以修改为GOARCH=$TARGETARCH用于非 AMD64 架构。Docker 将自动将环境变量设置为–platform指定的 value。对于 Buildah,需要使用–build-arg。更多信息,请参阅 多架构

    2. 将镜像推送到存储库

      $ make docker-push IMG=<registry>/<user>/<operator_image_name>:<tag>
  2. 通过运行make bundle命令创建您的 Operator 包清单,该命令将调用多个命令,包括 Operator SDK 的generate bundlebundle validate子命令

    $ make bundle IMG=<registry>/<user>/<operator_image_name>:<tag>

    Operator 的包清单描述了如何显示、创建和管理应用程序。make bundle命令在您的 Operator 项目中创建以下文件和目录

    • 名为bundle/manifests的包清单目录,其中包含一个ClusterServiceVersion对象

    • 名为bundle/metadata的包元数据目录

    • config/crd目录中的所有自定义资源定义 (CRD)

    • Dockerfile bundle.Dockerfile

    然后,这些文件将使用operator-sdk bundle validate自动验证,以确保磁盘上的包表示正确。

  3. 通过运行以下命令构建和推送您的包镜像。OLM 使用索引镜像来使用 Operator 包,该索引镜像引用一个或多个包镜像。

    1. 构建包镜像。使用注册表、用户命名空间和您打算推送镜像的镜像标签的详细信息设置BUNDLE_IMG

      $ make bundle-build BUNDLE_IMG=<registry>/<user>/<bundle_image_name>:<tag>
    2. 推送包镜像

      $ docker push <registry>/<user>/<bundle_image_name>:<tag>

使用 Operator Lifecycle Manager 部署 Operator

Operator Lifecycle Manager (OLM) 可帮助您安装、更新和管理 Kubernetes 集群上 Operator 及其关联服务的生命周期。OLM 在 OpenShift Container Platform 上默认安装,并作为 Kubernetes 扩展运行,因此您可以使用 Web 控制台和 OpenShift CLI (oc) 完成所有 Operator 生命周期管理功能,无需任何其他工具。

Operator 包格式是 Operator SDK 和 OLM 的默认打包方法。您可以使用 Operator SDK 快速在 OLM 上运行包镜像,以确保其正常运行。

先决条件
  • 在开发工作站上安装了 Operator SDK CLI

  • 已构建并推送到注册表的 Operator 包镜像

  • 在基于 Kubernetes 的集群上安装了 OLM(如果您使用apiextensions.k8s.io/v1 CRD,则为 v1.16.0 或更高版本,例如 OpenShift Container Platform 4.17)

  • 使用具有cluster-admin权限的帐户使用oc登录到集群

步骤
  • 输入以下命令以在集群上运行 Operator

    $ operator-sdk run bundle \(1)
        -n <namespace> \(2)
        <registry>/<user>/<bundle_image_name>:<tag> (3)
    1 run bundle 命令会创建一个有效的基于文件的目录,并使用 OLM 在您的集群上安装 Operator bundle。
    2 可选:默认情况下,该命令会将 Operator 安装到您 ~/.kube/config 文件中当前活动的项目中。您可以添加 -n 标志来设置安装的不同命名空间范围。
    3 如果您没有指定镜像,该命令将使用 quay.io/operator-framework/opm:latest 作为默认索引镜像。如果您指定了镜像,则该命令将使用 bundle 镜像本身作为索引镜像。

    从 OpenShift Container Platform 4.11 开始,run bundle 命令默认支持 Operator 目录的基于文件的目录格式。已弃用的 Operator 目录的 SQLite 数据库格式继续受支持;但是,它将在将来的版本中删除。建议 Operator 作者将其工作流程迁移到基于文件的目录格式。

    此命令执行以下操作:

    • 创建一个引用您的 bundle 镜像的索引镜像。索引镜像是不透明且短暂的,但准确地反映了如何在生产环境中将 bundle 添加到目录中。

    • 创建一个指向您的新索引镜像的目录源,这使 OperatorHub 能够发现您的 Operator。

    • 通过创建 OperatorGroupSubscriptionInstallPlan 和所有其他必需的资源(包括 RBAC)来将您的 Operator 部署到您的集群。

创建自定义资源

安装 Operator 后,您可以通过创建 Operator 现在在集群上提供的自定义资源 (CR) 来对其进行测试。

先决条件
  • 示例 Memcached Operator,它提供安装在集群上的 Memcached CR

步骤
  1. 更改到安装 Operator 的命名空间。例如,如果您使用 make deploy 命令部署了 Operator

    $ oc project memcached-operator-system
  2. 编辑位于 config/samples/cache_v1_memcached.yaml 的示例 Memcached CR 清单,使其包含以下规范:

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    ...
    spec:
    ...
      size: 3
  3. 创建 CR

    $ oc apply -f config/samples/cache_v1_memcached.yaml
  4. 确保 Memcached Operator 使用正确的规模为示例 CR 创建部署。

    $ oc get deployments
    示例输出
    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    memcached-operator-controller-manager   1/1     1            1           8m
    memcached-sample                        3/3     3            3           1m
  5. 检查 Pod 和 CR 状态以确认状态已更新为 Memcached Pod 名称。

    1. 检查 Pod

      $ oc get pods
      示例输出
      NAME                                  READY     STATUS    RESTARTS   AGE
      memcached-sample-6fd7c98d8-7dqdr      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-g5k7v      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-m7vn7      1/1       Running   0          1m
    2. 检查 CR 状态

      $ oc get memcached/memcached-sample -o yaml
      示例输出
      apiVersion: cache.example.com/v1
      kind: Memcached
      metadata:
      ...
        name: memcached-sample
      ...
      spec:
        size: 3
      status:
        nodes:
        - memcached-sample-6fd7c98d8-7dqdr
        - memcached-sample-6fd7c98d8-g5k7v
        - memcached-sample-6fd7c98d8-m7vn7
  6. 更新部署规模。

    1. 更新 config/samples/cache_v1_memcached.yaml 文件,将 Memcached CR 中的 spec.size 字段从 3 更改为 5

      $ oc patch memcached memcached-sample \
          -p '{"spec":{"size": 5}}' \
          --type=merge
    2. 确认 Operator 是否更改了部署规模。

      $ oc get deployments
      示例输出
      NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
      memcached-operator-controller-manager   1/1     1            1           10m
      memcached-sample                        5/5     5            5           3m
  7. 运行以下命令删除 CR:

    $ oc delete -f config/samples/cache_v1_memcached.yaml
  8. 清理在此教程中创建的资源。

    • 如果您使用 make deploy 命令测试 Operator,请运行以下命令:

      $ make undeploy
    • 如果您使用 operator-sdk run bundle 命令测试 Operator,请运行以下命令:

      $ operator-sdk cleanup <project_name>