12.2.3. Operator SDK を使用した Ansible ベースの Operator のビルド

以下の手順では、Operator SDK が提供するツールおよびライブラリーを使用した Ansible Playbook がサポートする単純な Memcached Operator のビルドの例について説明します。

前提条件

  • 開発ワークステーションにインストールされる Operator SDK CLI
  • cluster-admin パーミッションを持つアカウントを使用した Kubernetes ベースのクラスター r v1.11.3+ (OpenShift Container Platform 4.4 など) へのアクセス
  • OpenShift CLI (oc) v4.1+ (インストール済み)
  • ansible v2.6.0+
  • ansible-runner v1.1.0+
  • ansible-runner-http v1.0.0+

手順

  1. 新規 Operator プロジェクトを作成します。namespace スコープの Operator は単一 namespace でリソースを監視し、管理します。namespace スコープの Operator は柔軟性があるために優先して使用されます。これらの Operator は切り離されたアップグレード、障害対応およびモニタリングのための namespace の分離、および API 定義の差異化を可能にします。

    新規の Ansible ベース、namespace スコープの memcached-operator プロジェクトを作成し、そのディレクトリーに切り換えるには、以下のコマンドを使用します。

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

    これにより、APIVersion example.com/v1apha1 および Kind Memcached の Memcached リソースを監視するための memcached-operator プロジェクトが作成されます。

  2. Operator ロジックをカスタマイズします

    この例では、memcached-operator はそれぞれの Memcached カスタムリソース (CR) について以下の調整 (reconciliation) ロジックを実行します。

    • memcached Deployment を作成します (ない場合)。
    • Deployment のサイズが Memcached CR で指定されるのと同じであることを確認します。

    デフォルトで、memcached-operatorwatches.yaml ファイルに示されるように Memcached リソースイベントを監視し、Ansible ロール Memcached を実行します。

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

    オプションで、以下のロジックを watches.yaml ファイルでカスタマイズできます。

    1. role オプションを指定して、ansible-runner を Ansible ロールを使って起動する際に Operator がこの特定のパスを使用するように設定します。デフォルトでは、新規コマンドでロールが置かれる場所への絶対パスが入力されます。

      - version: v1alpha1
        group: cache.example.com
        kind: Memcached
        role: /opt/ansible/roles/memcached
    2. playbook オプションを watches.yaml ファイルに指定して、ansible-runner を Ansible Playbook で起動する際に Operator がこの指定されたパスを使用するように設定します。

      - version: v1alpha1
        group: cache.example.com
        kind: Memcached
        playbook: /opt/ansible/playbook.yaml
  3. Memcached Ansible ロールをビルドします

    生成された Ansible ロールを roles/memcached/ ディレクトリーの下で変更します。この Ansible ロールは、リソースの変更時に実行されるロジックを制御します。

    1. Memcached 仕様を定義します

      Ansible ベースの Operator の定義は Ansible 内ですべて実行できます。Ansible Operator は CR 仕様フィールドのすべてのキー/値ペアを 変数 として Ansible に渡します。仕様フィールドのすべての変数の名前は、Ansible の実行前に Operator によってスネークケース (小文字 + アンダースコア) に変換されます。たとえば、仕様の serviceAccount は Ansible では service_account になります。

      ヒント

      Ansible で変数についてのタイプの検証を実行し、アプリケーションが予想される入力を受信できることを確認する必要があります。

      ユーザーが spec フィールドを設定しない場合、 roles/memcached/defaults/main.yml ファイルを変更してデフォルトを設定します。

      size: 1
    2. Memcached デプロイメントを定義します

      Memcached 仕様が定義された状態で、リソースの変更に対する Ansible の実行内容を定義できます。これは Ansible ロールであるため、デフォルトの動作は roles/memcached/tasks/main.yml ファイルでタスクを実行します。

      ここでの目的は、Ansible で memcached:1.4.36-alpine イメージを実行する Deployement を作成することにあります (Deployment がない場合)。Ansible 2.7+ は k8s Ansible モジュール をサポートします。 この例では、このモジュールを活用し、Deployment 定義を制御します。

      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 Deployment のレプリカ数を制御しています。この例では、デフォルトを 1 に設定しますが、任意のユーザーがこのデフォルトを上書きする CR を作成することができます。

  4. CRD をデプロイします

    Operator の実行前に、Kubernetes は Operator が監視する新規カスタムリソース定義 (CRD) について把握している必要があります。Memcached CRD をデプロイします。

    $ oc create -f deploy/crds/cache.example.com_memcacheds_crd.yaml
  5. Operator をビルドし、実行します

    Operator をビルドし、実行する方法として 2 つの方法を使用できます。

    • Kubernetes クラスター内の Pod を使用
    • operator-sdk up コマンドを使用してクラスター外で Go プログラムを使用

    以下の方法のいずれかを選択します。

    1. Kubernetes クラスター内で Pod として実行 します。これは実稼働環境での優先される方法です。

      1. memcached-operator イメージをビルドし、これをレジストリーにプッシュします。

        $ operator-sdk build quay.io/example/memcached-operator:v0.0.1
        $ podman push quay.io/example/memcached-operator:v0.0.1
      2. Deployment マニフェストは 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 プラグインがインストールされていることを確認します。 インストールされていない場合、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 の Deployment を作成できることを確認します。

      $ 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 で 3 つのレプリカが作成されていることを確認します。

      $ 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 が Deployment サイズを変更することを確認します。

      $ 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