5.4.2. 使用 Operator SDK 来构建基于 Ansible 的 Operator

本流程介绍了使用 Operator SDK 中的工具和库来构建由 Ansible playbook 和模块提供技术支持的简单 Memcached Operator 示例。

先决条件

  • 开发工作站上安装 operator SDK v0.19.4 CLI
  • 使用具有 cluster-admin 权限的账户访问基于 Kubernetes 的集群 v1.11.3+(如 OpenShift Container Platform 4.6)
  • 已安装 OpenShift CLI(oc)v4.6+
  • ansible v2.9.0+
  • ansible-runner v1.1.0+
  • ansible-runner-http v1.0.0+

流程

  1. 创建新 Operator 项目。命名空间范围的 Operator 会监视和管理单一命名空间中的资源。命名空间范围的 Operator 因具有高灵活性而常被视为首选。这类 Operator 支持解耦升级、针对故障和监控隔离命名空间以及区别化 API 定义。

    要创建基于 Ansible 的、全命名空间范围的新 memcached-operator 项目并改为新目录,请使用以下命令:

    $ operator-sdk new memcached-operator \
        --api-version=cache.example.com/v1alpha1 \
        --kind=Memcached \
        --type=ansible
    $ cd memcached-operator

    这会创建 memcached-operator 项目,专门用于监视 API 版本 example.com/v1apha1 和 kind MemcachedMemcached 资源。

  2. 自定义 Operator 逻辑。

    在本例中,memcached-operator 会针对每个 Memcached 自定义资源 (CR) 执行以下协调逻辑:

    • 如果尚无 Memcached 部署,创建一个。
    • 确保部署的大小与 Memcached CR 指定的大小相同。

    默认情况下,memcached-operator 会监视 Memcached 资源事件,如 watches.yaml 文件中所示,并执行 Ansible 角色 Memcached

    - version: v1alpha1
      group: cache.example.com
      kind: Memcached

    您可选择在 watches.yaml 文件中自定义以下逻辑:

    1. 指定 role 选项会将 Operator 配置为在通过 Ansible 角色启动 ansible-runner 时使用该指定路径。默认情况下,operator-sdk new 命令会填写到您的角色应前往的绝对路径:

      - version: v1alpha1
        group: cache.example.com
        kind: Memcached
        role: /opt/ansible/roles/memcached
    2. 指定 watches.yaml 文件中的 playbook 选项会将 Operator 配置为在通过 Ansible playbook 启动 ansible-runner 时使用该指定路径。

      - version: v1alpha1
        group: cache.example.com
        kind: Memcached
        playbook: /opt/ansible/playbook.yaml
  3. 构建 Memcached Ansible 角色。

    修改 roles/memcached/ 目录下生成的 Ansible 角色。该 Ansible 角色会控制修改资源时所执行的逻辑。

    1. 定义 Memcached spec。

      可完全在 Ansible 中定义基于 Ansible 的 Operator spec。Ansible Operator 会将 CR spec 字段中列出的所有键值对作为变量传递给 Ansible。在运行 Ansible 之前,Operator 会将 spec 字段中所有变量的名称转换为 snake 格式(小写并附带下划线)。例如,spec 中的 serviceAccount 在 Ansible 中会变成 service_account

      提示

      您应在 Ansible 中对变量执行一些类型验证,以确保应用程序收到所需输入。

      如果用户未设置 spec 字段,则请修改 roles/memcached/defaults/main.yml 文件设置默认值:

      size: 1
    2. 定义 Memcached 部署。

      定义了 Memcached spec 后,即可定义资源发生更改时实际应执行的 Ansible。因为这是一个 Ansible 角色,所以默认行为是执行 roles/memcached/tasks/main.yml 文件中的任务。

      目的是在不存在部署的情况下让 Ansible 创建 Deployment,该 Deployment 将运行 memcached:1.4.36-alpine 镜像。Ansible 2.7+ 支持 k8s Ansible 模块,本例利用该模块来控制部署定义。

      修改 roles/memcached/tasks/main.yml 以匹配以下内容:

      - name: start memcached
        k8s:
          definition:
            kind: Deployment
            apiVersion: apps/v1
            metadata:
              name: '{{ meta.name }}-memcached'
              namespace: '{{ 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
      注意

      本例使用 size 变量来控制 Memcached 部署的副本数。本示例将默认值设定为 1,但任何用户都可以创建一个 CR 覆盖该默认值。

  4. 部署 CRD。

    在运行 Operator 之前,Kubernetes 需要了解 Operator 将会监视的新自定义资源定义 (CRD)。部署 Memcached CRD:

    $ oc create -f deploy/crds/cache.example.com_memcacheds_crd.yaml
  5. 构建并运行 Operator。

    有两种方式来构建和运行 Operator:

    • 作为 Kubernetes 集群内的一个 pod。
    • 作为集群外的 Go 程序,使用 operator-sdk up 命令。

    选择以下任一方法:

    1. 作为 Kubernetes 集群内的一个 pod 来运行。这是生产环境的首先方法。

      1. 构建 memcached-operator 镜像并将其推送至 registry:

        $ operator-sdk build quay.io/example/memcached-operator:v0.0.1
        $ podman push quay.io/example/memcached-operator:v0.0.1
      2. deploy/operator.yaml 文件中会生成 Deployment 清单。本文件中的部署镜像需要从占位符 REPLACE_IMAGE 修改为之前构建的镜像。为此,请运行:

        $ sed -i 's|REPLACE_IMAGE|quay.io/example/memcached-operator:v0.0.1|g' deploy/operator.yaml
      3. 部署 memcached-operator 清单:

        $ oc create -f deploy/service_account.yaml
        $ oc create -f deploy/role.yaml
        $ oc create -f deploy/role_binding.yaml
        $ oc create -f deploy/operator.yaml
      4. 验证 memcached-operator 部署是否正在运行:

        $ oc get deployment
        NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
        memcached-operator       1         1         1            1           1m
    2. 在集群外运行。这是开发阶段的首选方法,可加快部署和测试的速度。

      请确保已安装 Ansible Runner 和 Ansible Runner HTTP Plug-in,否则在创建 CR 时,系统会显示 Ansible Runner 出现意外错误。

      此外,还务必要确保您的计算机上存在 watches.yaml 文件中引用的角色路径。因为通常会在磁盘上角色所处的位置使用容器,所以必须手动将角色复制到已配置的 Ansible 角色路径中(如 /etc/ansible/roles)。

      1. 要使用 $HOME/.kube/config 中的默认 Kubernetes 配置文件在本地运行 Operator:

        $ operator-sdk run --local

        要使用所提供的 Kubernetes 配置文件在本地运行 Operator:

        $ operator-sdk run --local --kubeconfig=config
  6. 创建一个 Memcached CR。

    1. 按所示方式修改 deploy/crds/cache_v1alpha1_memcached_cr.yaml 文件并创建一个 Memcached CR:

      $ cat deploy/crds/cache_v1alpha1_memcached_cr.yaml

      输出示例

      apiVersion: "cache.example.com/v1alpha1"
      kind: "Memcached"
      metadata:
        name: "example-memcached"
      spec:
        size: 3

      $ oc apply -f deploy/crds/cache_v1alpha1_memcached_cr.yaml
    2. 确保 memcached-operator 为 CR 创建部署:

      $ oc get deployment

      输出示例

      NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
      memcached-operator       1         1         1            1           2m
      example-memcached        3         3         3            3           1m

    3. 检查 pod,确认已创建三个副本:

      $ oc get pods
      NAME                                  READY     STATUS    RESTARTS   AGE
      example-memcached-6fd7c98d8-7dqdr     1/1       Running   0          1m
      example-memcached-6fd7c98d8-g5k7v     1/1       Running   0          1m
      example-memcached-6fd7c98d8-m7vn7     1/1       Running   0          1m
      memcached-operator-7cc7cfdf86-vvjqk   1/1       Running   0          2m
  7. 更新大小。

    1. memcached CR 中的 spec.size 字段从 3 改为 4,并应用以下更改:

      $ cat deploy/crds/cache_v1alpha1_memcached_cr.yaml

      输出示例

      apiVersion: "cache.example.com/v1alpha1"
      kind: "Memcached"
      metadata:
        name: "example-memcached"
      spec:
        size: 4

      $ oc apply -f deploy/crds/cache_v1alpha1_memcached_cr.yaml
    2. 确认 Operator 已更改部署大小:

      $ oc get deployment

      输出示例

      NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
      example-memcached    4         4         4            4           5m

  8. 清理资源:

    $ oc delete -f deploy/crds/cache_v1alpha1_memcached_cr.yaml
    $ oc delete -f deploy/operator.yaml
    $ oc delete -f deploy/role_binding.yaml
    $ oc delete -f deploy/role.yaml
    $ oc delete -f deploy/service_account.yaml
    $ oc delete -f deploy/crds/cache_v1alpha1_memcached_crd.yaml