×

在您熟悉了在本地使用Kubernetes Collection for Ansible之后,您可以在自定义资源(CR)发生更改时,在操作符内部触发相同的Ansible逻辑。此示例将Ansible角色映射到操作符监视的特定Kubernetes资源。此映射在watches.yaml文件中完成。

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

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

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

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

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

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

自定义资源文件

Operator 使用 Kubernetes 扩展机制,即自定义资源定义 (CRD),因此您的自定义资源 (CR) 看起来就像内置的 Kubernetes 原生对象一样,并且行为也一样。

CR 文件格式是 Kubernetes 资源文件。该对象具有必填字段和可选字段。

表 1. 自定义资源字段
字段 描述

apiVersion

要创建的 CR 的版本。

kind

要创建的 CR 的种类。

metadata

要创建的 Kubernetes 特定元数据。

spec(可选)

传递给 Ansible 的变量的键值列表。此字段默认为空。

status

总结对象的当前状态。对于基于 Ansible 的 Operator,status 子资源已为 CRD 启用,并默认由 operator_sdk.util.k8s_status Ansible 模块管理,其中包括添加到 CR statuscondition 信息。status 子资源

annotations

要添加到 CR 的 Kubernetes 特定注释。

以下 CR 注释列表会修改 Operator 的行为。

表 2. 基于 Ansible 的 Operator 注释
注释 描述

ansible.operator-sdk/reconcile-period

指定 CR 的协调间隔。此值使用标准 Golang 包 time 进行解析。具体来说,使用 ParseDuration,它应用默认后缀 s,以秒为单位提供值。

基于 Ansible 的 Operator 注释示例
apiVersion: "test1.example.com/v1alpha1"
kind: "Test1"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

在本地测试基于 Ansible 的 Operator

您可以使用 Operator 项目顶级目录中的 make run 命令来测试在本地运行的基于 Ansible 的 Operator 中的逻辑。make run Makefile 目标在本地运行 ansible-operator 二进制文件,该文件从 watches.yaml 文件读取,并使用您的 ~/.kube/config 文件与 Kubernetes 集群通信,就像 k8s 模块一样。

您可以通过设置环境变量 ANSIBLE_ROLES_PATH 或使用 ansible-roles-path 标志来自定义角色路径。如果在 ANSIBLE_ROLES_PATH 值中找不到角色,则 Operator 会在 {{当前目录}}/roles 中查找它。

先决条件
步骤
  1. 安装您的自定义资源定义 (CRD) 和自定义资源 (CR) 的正确的基于角色的访问控制 (RBAC) 定义。

    $ make install
    示例输出
    /usr/bin/kustomize build config/crd | kubectl apply -f -
    customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created
  2. 运行 make run 命令

    $ make run
    示例输出
    /home/user/memcached-operator/bin/ansible-operator run
    {"level":"info","ts":1612739145.2871568,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    ...
    {"level":"info","ts":1612739148.347306,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
    {"level":"info","ts":1612739148.3488882,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612739148.3490262,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612739148.3490646,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612739148.350217,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612739148.3506632,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612739148.350784,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612739148.5511978,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612739148.5512562,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

    现在 Operator 正在监视您的 CR 以获取事件,创建 CR 将触发您的 Ansible 角色运行。

    考虑一个示例 config/samples/<gvk>.yaml CR 清单

    apiVersion: <group>.example.com/v1alpha1
    kind: <kind>
    metadata:
      name: "<kind>-sample"

    由于未设置 spec 字段,因此 Ansible 在没有额外变量的情况下被调用。从 CR 向 Ansible 传递额外变量将在另一节中介绍。为 Operator 设置合理的默认值非常重要。

  3. 创建您的 CR 实例,并将默认变量 state 设置为 present

    $ oc apply -f config/samples/<gvk>.yaml
  4. 检查是否创建了 example-config 配置映射。

    $ oc get configmaps
    示例输出
    NAME                    STATUS    AGE
    example-config          Active    3s
  5. 修改您的 config/samples/<gvk>.yaml 文件以将 state 字段设置为 absent。例如

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    spec:
      state: absent
  6. 应用更改

    $ oc apply -f config/samples/<gvk>.yaml
  7. 确认配置映射已删除

    $ oc get configmap

在集群上测试基于 Ansible 的 Operator

在本地测试了 Operator 内的自定义 Ansible 逻辑后,您可以测试 OpenShift Dedicated 集群上的 pod 中的 Operator,这在生产环境中是首选。

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

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

    1. 构建镜像

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

      Operator 的 SDK 生成的 Dockerfile 明确引用了 GOARCH=amd64 用于 go build。这可以修改为 GOARCH=$TARGETARCH 以用于非 AMD64 架构。Docker 将自动将环境变量设置为 –platform 指定的值。对于 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

Ansible 日志

基于 Ansible 的 Operator 提供有关 Ansible 运行的日志,这对于调试 Ansible 任务很有用。日志还可以包含有关 Operator 的内部结构及其与 Kubernetes 的交互的详细信息。

查看 Ansible 日志

先决条件
  • 在集群上作为部署运行的基于 Ansible 的 Operator

步骤
  • 要查看基于 Ansible 的 Operator 的日志,请运行以下命令

    $ oc logs deployment/<project_name>-controller-manager \
        -c manager \(1)
        -n <namespace> (2)
    1 查看 manager 容器的日志。
    2 如果您使用 make deploy 命令将 Operator 作为部署运行,请使用 <project_name>-system 命名空间。
    示例输出
    {"level":"info","ts":1612732105.0579333,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    {"level":"info","ts":1612732105.0587437,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""}
    I0207 21:08:26.110949       7 request.go:645] Throttling request took 1.035521578s, request: GET:https://172.30.0.1:443/apis/flowcontrol.apiserver.k8s.io/v1alpha1?timeout=32s
    {"level":"info","ts":1612732107.768025,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":"127.0.0.1:8080"}
    {"level":"info","ts":1612732107.768796,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612732107.7688773,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612732107.7688901,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612732107.770032,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    I0207 21:08:27.770185       7 leaderelection.go:243] attempting to acquire leader lease  memcached-operator-system/memcached-operator...
    {"level":"info","ts":1612732107.770202,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    I0207 21:08:27.784854       7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator
    {"level":"info","ts":1612732107.7850506,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612732107.8853772,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612732107.8854098,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}

在日志中启用完整的 Ansible 结果

您可以将环境变量 ANSIBLE_DEBUG_LOGS 设置为 True 以启用检查日志中的完整 Ansible 结果,这在调试时可能会有所帮助。

步骤
  • 编辑 config/manager/manager.yamlconfig/default/manager_auth_proxy_patch.yaml 文件以包含以下配置

          containers:
          - name: manager
            env:
            - name: ANSIBLE_DEBUG_LOGS
              value: "True"

在日志中启用详细调试

在开发基于 Ansible 的 Operator 时,启用日志中的其他调试信息可能会有所帮助。

步骤
  • ansible.sdk.operatorframework.io/verbosity 注释添加到您的自定义资源以启用所需的详细程度。例如

    apiVersion: "cache.example.com/v1alpha1"
    kind: "Memcached"
    metadata:
      name: "example-memcached"
      annotations:
        "ansible.sdk.operatorframework.io/verbosity": "4"
    spec:
      size: 4