Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

11.2. Ansible ベース Operator の作成

以下では、Operator SDK における Ansible サポートについての概要を説明し、Operator の作成者に、Ansible Playbook およびモジュールを使用する operator-sdk CLI ツールを使って Ansible ベースの Operator をビルドし、実行するサンプルを示します。

11.2.1. Operator SDK における Ansible サポート

Operator FrameworkOperator という Kubernetes ネイティブアプリケーションを効果的かつ自動化された拡張性のある方法で管理するためのオープンソースツールキットです。このフレームワークには Operator SDK が含まれ、これは Kubernetes API の複雑性を把握していなくても、それぞれの専門知識に基づいて Operator のブートストラップおよびビルドを実行できるように開発者を支援します。

Operator プロジェクトを生成するための Operator SDK のオプションの 1 つに、Go コードを作成することなしに Kubernetes リソースを統一されたアプリケーションとしてデプロイするために既存の Ansible Playbook およびモジュールを使用できるオプションがあります。

11.2.1.1. カスタムリソースファイル

Operator は Kubernetes の拡張メカニズムであるカスタムリソース定義 (CRD) を使用するため、カスタムリソース (CR) は、組み込み済みのネイティブ Kubernetes オブジェクトのように表示され、機能します。

CR ファイル形式は Kubernetes リソースファイルです。オブジェクトには、必須およびオプションフィールドが含まれます。

表11.1 カスタムリソースフィールド

フィールド説明

apiVersion

作成される CR のバージョン。

kind

作成される CR の種類。

metadata

作成される Kubernetes 固有のメタデータ。

spec (オプション)

Ansible に渡される変数のキーと値の一覧。このフィールドは、デフォルトでは空です。

status

オブジェクトの現在の状態の概要を示します。Ansible ベースの Operator の場合、status サブリソース はデフォルトで CRD について有効にされ、k8s_status Ansible モジュールによって管理されます。 これには、CR の status に対する condition 情報が含まれます。

annotations

CR に付加する Kubernetes 固有のアノテーション。

CR アノテーションの以下の一覧は Operator の動作を変更します。

表11.2 Ansible ベースの Operator アノテーション

アノテーション説明

ansible.operator-sdk/reconcile-period

CR の調整間隔を指定します。この値は標準的な Golang パッケージ time を使用して解析されます。とくに、ParseDuration は、s のデフォルトサフィックスを適用し、秒単位で値を指定します。

Ansible ベースの Operator アノテーションの例

apiVersion: "foo.example.com/v1alpha1"
kind: "Foo"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

11.2.1.2. 監視ファイル

監視ファイルには、GroupVersion、および Kind などによって特定される、カスタムリソース (CR) から Ansible ロールまたは Playbook へのマッピングの一覧が含まれます。Operator はこのマッピングファイルが事前に定義された場所の /opt/ansible/watches.yaml にあることを予想します。

表11.3 監視ファイルのマッピング

フィールド説明

group

監視する CR のグループ。

version

監視する CR のバージョン。

kind

監視する CR の種類。

role (デフォルト)

コンテナーに追加される Ansible ロールへのパスです。たとえば、 roles ディレクトリーが /opt/ansible/roles/ にあり、ロールの名前が busybox の場合、この値は /opt/ansible/roles/busybox になります。このフィールドは playbook フィールドと相互に排他的です。

playbook

コンテナーに追加される Ansible Playbook へのパスです。この Playbook は単純にロールを呼び出す方法になります。このフィールドは role フィールドと相互に排他的です。

reconcilePeriod (オプション)

ロールまたは Playbook が特定の CR について実行される調整 期間および頻度。

manageStatus (オプション)

true (デフォルト) に設定されると、Operator は CR のステータスを汎用的に管理します。false に設定されると、指定されたロール、または別のコントローラーの Playbook により、CR のステータスは他の場所で管理されます。

監視ファイルの例

- version: v1alpha1 1
  group: foo.example.com
  kind: Foo
  role: /opt/ansible/roles/Foo

- version: v1alpha1 2
  group: bar.example.com
  kind: Bar
  playbook: /opt/ansible/playbook.yml

- version: v1alpha1 3
  group: baz.example.com
  kind: Baz
  playbook: /opt/ansible/baz.yml
  reconcilePeriod: 0
  manageStatus: false

1
FooFoo ロールへの単純なマッピング例。
2
Bar の Playbook への単純なマッピング例。
3
Baz の種類についてのより複雑な例。Playbook での CR ステータスを再度キューに入れるタスクまたはその管理を無効にします。
11.2.1.2.1. 高度なオプション

高度な機能は、それらを GVK (グループ、バージョン、および種類) ごとに監視ファイルに追加して有効にできます。それらは groupversionkind および playbook または role フィールドの下に移行できます。

一部の機能は、カスタムリソース (CR) のアノテーションを使用してリソースごとに上書きできます。オーバーライドできるオプションには、以下に指定されるアノテーションが含まれます。

表11.4 高度な監視対象ファイルオプション

機能YAML キー説明上書きのアノテーションデフォルト値

調整期間

reconcilePeriod

特定の CR についての調整実行の間隔。

ansbile.operator-sdk/reconcile-period

1m

ステータスの管理

manageStatus

Operator は各 CR の status セクションの conditions セクションを管理できます。

 

true

依存するリソースの監視

watchDependentResources

Operator は Ansible によって作成されるリソースを動的に監視できます。

 

true

クラスタースコープのリソースの監視

watchClusterScopedResources

Operator は Ansible によって作成されるクラスタースコープのリソースを監視できます。

 

false

最大 Runner アーティファクト

maxRunnerArtifacts

Ansible Runner が各リソースについて Operator コンテナーに保持するアーティファクトディレクトリーの数を管理します。

ansible.operator-sdk/max-runner-artifacts

20

高度なオプションを含む監視ファイルの例

- version: v1alpha1
  group: app.example.com
  kind: AppService
  playbook: /opt/ansible/playbook.yml
  maxRunnerArtifacts: 30
  reconcilePeriod: 5s
  manageStatus: False
  watchDependentResources: False

11.2.1.3. Ansible に送信される追加変数

追加の変数を Ansible に送信し、Operator で管理できます。カスタマーリソース (CR) の spec セクションでは追加変数としてキーと値のペアを渡します。これは、ansible-playbook コマンドに渡される追加変数と同等です。

また Operator は、CR の名前および CR の namespace についての meta フィールドの下に追加の変数を渡します。

以下は CR の例になります。

apiVersion: "app.example.com/v1alpha1"
kind: "Database"
metadata:
  name: "example"
spec:
  message:"Hello world 2"
  newParameter: "newParam"

追加変数として Ansible に渡される構造は以下のとおりです。

{ "meta": {
        "name": "<cr_name>",
        "namespace": "<cr_namespace>",
  },
  "message": "Hello world 2",
  "new_parameter": "newParam",
  "_app_example_com_database": {
     <full_crd>
   },
}

message および newParameter フィールドは追加変数として上部に設定され、meta は Operator に定義されるように CR の関連メタデータを提供します。meta フィールドは、Ansible のドット表記などを使用してアクセスできます。

- debug:
    msg: "name: {{ meta.name }}, {{ meta.namespace }}"

11.2.1.4. Ansible Runner ディレクトリー

Ansible Runner はコンテナーに Ansible 実行についての情報を維持します。これは /tmp/ansible-operator/runner/<group>/<version>/<kind>/<namespace>/<name> に置かれます。

追加リソース

11.2.2. Operator SDK CLI のインストール

Operator SDK には、開発者による新規 Operator プロジェクトの作成、ビルドおよびデプロイを支援をする CLI ツールが含まれます。ワークステーションに SDK CLI をインストールして、独自の Operator のオーサリングを開始することができます。

注記

以下では、ローカル Kubernetes クラスターとしての minikube v0.25.0+ とパブリックレジストリーの quay.io を使用します。

11.2.2.1. GitHub リリースからのインストール

GitHub のプロジェクトから SDK CLI の事前ビルドリリースのバイナリーをダウンロードし、インストールできます。

前提条件

  • docker v17.03+
  • OpenShift CLI (oc) v4.1+ (インストール済み)
  • Kubernetes v1.11.3+ に基づくクラスターへのアクセス
  • コンテナーレジストリーへのアクセス

手順

  1. リリースバージョン変数を設定します。

    RELEASE_VERSION=v0.8.0
  2. リリースバイナリーをダウンロードします。

    • Linux の場合

      $ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu
    • MacOS の場合

      $ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin
  3. ダウンロードしたリリースのバイナリーを確認します。

    1. 提供された ASC ファイルをダウンロードします。

      • Linux の場合

        $ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu.asc
      • MacOS の場合

        $ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin.asc
    2. バイナリーと対応する ASC ファイルを同じディレクトリーに置き、以下のコマンドを実行してバイナリーを確認します。

      • Linux の場合

        $ gpg --verify operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu.asc
      • MacOS の場合

        $ gpg --verify operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin.asc

      保守管理者の公開キーがワークステーションにない場合は、以下のエラーが出されます。

      $ gpg --verify operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin.asc
      $ gpg: assuming signed data in 'operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin'
      $ gpg: Signature made Fri Apr  5 20:03:22 2019 CEST
      $ gpg:                using RSA key <key_id> 1
      $ gpg: Can't check signature: No public key
      1
      RSA キー文字列。

      キーをダウンロードするには、以下のコマンドを実行し、 <key_id> を直前のコマンドの出力で提供された RSA キー文字列に置き換えます。

      $ gpg [--keyserver keys.gnupg.net] --recv-key "<key_id>" 1
      1
      キーサーバーが設定されていない場合、これを --keyserver オプションで指定します。
  4. リリースバイナリーを PATH にインストールします。

    • Linux の場合

      $ chmod +x operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu
      $ sudo cp operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu /usr/local/bin/operator-sdk
      $ rm operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu
    • MacOS の場合

      $ chmod +x operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin
      $ sudo cp operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin /usr/local/bin/operator-sdk
      $ rm operator-sdk-${RELEASE_VERSION}-x86_64-apple-darwin
  5. CLI ツールが正しくインストールされていることを確認します。

    $ operator-sdk version

11.2.2.2. Homebrew からのインストール

Homebrew を使用して SDK CLI をインストールできます。

前提条件

  • Homebrew
  • docker v17.03+
  • OpenShift CLI (oc) v4.1+ (インストール済み)
  • Kubernetes v1.11.3+ に基づくクラスターへのアクセス
  • コンテナーレジストリーへのアクセス

手順

  1. brew コマンドを使用して SDK CLI をインストールします。

    $ brew install operator-sdk
  2. CLI ツールが正しくインストールされていることを確認します。

    $ operator-sdk version

11.2.2.3. ソースを使用したコンパイルおよびインストール

Operator SDK ソースコードを取得して、SDK CLI をコンパイルし、インストールできます。

前提条件

  • dep v0.5.0+
  • Git
  • Go v1.10+
  • docker v17.03+
  • OpenShift CLI (oc) v4.1+ (インストール済み)
  • Kubernetes v1.11.3+ に基づくクラスターへのアクセス
  • コンテナーレジストリーへのアクセス

手順

  1. operator-sdk リポジトリーのクローンを作成します。

    $ mkdir -p $GOPATH/src/github.com/operator-framework
    $ cd $GOPATH/src/github.com/operator-framework
    $ git clone https://github.com/operator-framework/operator-sdk
    $ cd operator-sdk
  2. 必要なリリースブランチをチェックアウトします。

    $ git checkout master
  3. SDK CLI ツールをコンパイルし、インストールします。

    $ make dep
    $ make install

    これにより、$GOPATH/bin に CLI バイナリー operator-sdk がインストールされます。

  4. CLI ツールが正しくインストールされていることを確認します。

    $ operator-sdk version

11.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.1 など) へのアクセス
  • OpenShift CLI (oc) v4.1+ (インストール済み)
  • ansible v2.6.0+
  • ansible-runner v1.1.0+
  • ansible-runner-http v1.0.0+

手順

  1. operator-sdk new コマンドを使用して、namespace スコープまたはクラスタースコープのいずれかで 新規 Operator プロジェクトを作成します。以下のいずれかを選択します。

    1. 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 はクラスター全体でリソースを監視し、管理します。これは、 クラスター全体で発行される証明書を管理できるようにクラスタースコープのパーミッションでデプロイされ、監視される cert-manager Operator などの場合に役立ちます。

      memcached-operator プロジェクトをクラスタースコープになるように作成し、そのディレクトリーに切り換えるには、以下のコマンドを実行します。

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

      --cluster-scoped フラグを使用することにより、以下の変更を含む新規の Operator のスキャフォールディングが実行されます。

      • deploy/operator.yaml: Pod の namespace に設定するのではなく、WATCH_NAMESPACE="" を設定します。
      • deploy/role.yaml: Role ではなく ClusterRole を使用します。
      • deploy/role_binding.yaml:

        • RoleBinding ではなく ClusterRoleBinding を使用します。
        • subject の namespace を REPLACE_NAMESPACE に設定します。これは、Operator がデプロイされる namespace に変更される必要があります。
  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_v1alpha1_memcached_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. --cluster-scoped=true フラグを使用して Operator を作成した場合、生成された ClusterRoleBinding でサービスアカウント namespace を Operator をデプロイする場所に一致するように更新します。

        $ export OPERATOR_NAMESPACE=$(oc config view --minify -o jsonpath='{.contexts[0].context.namespace}')
        $ sed -i "s|REPLACE_NAMESPACE|$OPERATOR_NAMESPACE|g" deploy/role_binding.yaml

        OSX でこれらの手順を実行している場合には、代わりに以下のコマンドを使用します。

        $ sed -i "" 's|REPLACE_IMAGE|quay.io/example/memcached-operator:v0.0.1|g' deploy/operator.yaml
        $ sed -i "" "s|REPLACE_NAMESPACE|$OPERATOR_NAMESPACE|g" deploy/role_binding.yaml
      4. 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
      5. 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 up local

        提供された Kubernetes 設定ファイルを使って Operator をローカルに実行するには、以下を実行します。

        $ operator-sdk up 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

11.2.4. K8S Ansible モジュールの使用によるアプリケーションライフサイクルの管理

Ansible を使用して Kubernetes でアプリケーションのライフサイクルを管理するには、k8s Ansible モジュールを使用できます。この Ansible モジュールにより、開発者は既存の Kubernetes リソースファイル (YAML で作成されている) を利用するか、またはネイティブの Ansible でライフサイクル管理を表現することができます。

Ansible を既存の Kubernetes リソースファイルと併用する最大の利点の 1 つに、Ansible のいくつかを変数のみを使う単純な方法でのリソースのカスタマイズを可能にする Jinja テンプレートを使用できる点があります。

このセクションでは、k8s Ansible モジュールの使用法を詳細に説明します。使用を開始するには、Playbook を使用してローカルワークステーションにモジュールをインストールし、これをテストしてから、Operator 内での使用を開始します。

11.2.4.1. k8s Ansible モジュールのインストール

k8s Ansible モジュールをローカルワークステーションにインストールするには、以下を実行します。

手順

  1. Ansible 2.6+ をインストールします。

    $ sudo yum install ansible
  2. pip を使用して OpenShift python クライアントパッケージをインストールします。

    $ pip install openshift

11.2.4.2. k8s Ansible モジュールのローカルでのテスト

開発者が毎回 Operator を実行し、再ビルドするのではなく、Ansible コードをローカルマシンから実行する方が利点がある場合があります。

手順

  1. 新規 Ansible ベースの Operator プロジェクトを初期化します。

    $ operator-sdk new --type ansible --kind Foo --api-version foo.example.com/v1alpha1 foo-operator
    Create foo-operator/tmp/init/galaxy-init.sh
    Create foo-operator/tmp/build/Dockerfile
    Create foo-operator/tmp/build/test-framework/Dockerfile
    Create foo-operator/tmp/build/go-test.sh
    Rendering Ansible Galaxy role [foo-operator/roles/Foo]...
    Cleaning up foo-operator/tmp/init
    Create foo-operator/watches.yaml
    Create foo-operator/deploy/rbac.yaml
    Create foo-operator/deploy/crd.yaml
    Create foo-operator/deploy/cr.yaml
    Create foo-operator/deploy/operator.yaml
    Run git init ...
    Initialized empty Git repository in /home/dymurray/go/src/github.com/dymurray/opsdk/foo-operator/.git/
    Run git init done
    $ cd foo-operator
  2. 必要な Ansible ロジックを使用して roles/Foo/tasks/main.yml ファイルを変更します。この例では、変数の切り替えと共に namespace を作成し、削除します。

    - name: set test namespace to {{ state }}
      k8s:
        api_version: v1
        kind: Namespace
        state: "{{ state }}"
      ignore_errors: true 1
    1
    ignore_errors: true を設定することにより、存在しないプロジェクトを削除しても失敗しません。
  3. roles/Foo/defaults/main.yml ファイルを、デフォルトで statepresent に設定するように変更します。

    state: present
  4. 上部ディレクトリーに、Foo ロールを含む Ansible Playbook playbook.yml を作成します。

    - hosts: localhost
      roles:
        - Foo
  5. Playbook を実行します。

    $ ansible-playbook playbook.yml
     [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ***************************************************************************
    
    TASK [Gathering Facts] *********************************************************************
    ok: [localhost]
    
    Task [Foo : set test namespace to present]
    changed: [localhost]
    
    PLAY RECAP *********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0
  6. namespace が作成されていることを確認します。

    $ oc get namespace
    NAME          STATUS    AGE
    default       Active    28d
    kube-public   Active    28d
    kube-system   Active    28d
    test          Active    3s
  7. stateabsent に設定して Playbook を再実行します。

    $ ansible-playbook playbook.yml --extra-vars state=absent
     [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ***************************************************************************
    
    TASK [Gathering Facts] *********************************************************************
    ok: [localhost]
    
    Task [Foo : set test namespace to absent]
    changed: [localhost]
    
    PLAY RECAP *********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0
  8. namespace が削除されていることを確認します。

    $ oc get namespace
    NAME          STATUS    AGE
    default       Active    28d
    kube-public   Active    28d
    kube-system   Active    28d

11.2.4.3. Operator 内での k8s Ansible モジュールのテスト

k8s Ansible モジュールをローカルで使用することに慣れたら、カスタムリソース (CR) の変更時に Operator 内で同じ Ansible ロジックをトリガーできます。この例では、Ansible ロールを、Operator が監視する特定の Kubernetes リソースにマップします。このマッピングは監視ファイルで実行されます。

11.2.4.3.1. Ansible ベース Operator のローカルでのテスト

Ansible ワークフローのテストをローカルで実行することに慣れたら、ローカルに実行される Ansible ベースの Operator 内でロジックをテストできます。

これを実行するには、Operator プロジェクトの上部ディレクトリーから operator-sdk up local コマンドを使用します。このコマンドは ./watches.yaml ファイルから読み取り、 ~/.kube/config ファイルを使用して k8s Ansible モジュールが実行するように Kubernetes クラスターと通信します。

手順

  1. up local コマンドは ./watches.yaml ファイルから読み取るため、Operator の作成者はいくつかのオプションを選択できます。role が単独で残される場合 (デフォルトでは /opt/ansible/roles/<name>)、ロールを Operator から /opt/ansible/roles/ ディレクトリーに直接コピーする必要があります。

    これは、現行ディレクトリーからの変更が反映されないために複雑になります。この代わりに、role フィールドを現行ディレクトリーを参照するように変更し、既存の行をコメントアウトします。

    - version: v1alpha1
      group: foo.example.com
      kind: Foo
      #  role: /opt/ansible/roles/Foo
      role: /home/user/foo-operator/Foo
  2. カスタムリソース定義 (CRD) およびカスタムリソース (CR) Foo の適切なロールベースアクセス制御 (RBAC) 定義を作成します。operator-sdk コマンドは、deploy/ ディレクトリー内にこれらのファイルを自動生成します。

    $ oc create -f deploy/crds/foo_v1alpha1_foo_crd.yaml
    $ oc create -f deploy/service_account.yaml
    $ oc create -f deploy/role.yaml
    $ oc create -f deploy/role_binding.yaml
  3. up local コマンドを実行します。

    $ operator-sdk up local
    [...]
    INFO[0000] Starting to serve on 127.0.0.1:8888
    INFO[0000] Watching foo.example.com/v1alpha1, Foo, default
  4. Operator はリソース Foo でイベントを監視しているため、CR の作成により、Ansible ロールの実行がトリガーされます。deploy/cr.yaml ファイルを表示します。

    apiVersion: "foo.example.com/v1alpha1"
    kind: "Foo"
    metadata:
      name: "example"

    spec フィールドは設定されていないため、Ansible は追加の変数なしで起動します。次のセクションでは、追加の変数が CR から Ansible に渡される方法について説明します。このため、Operator に同じでデフォルト値を設定することが重要になります。

  5. デフォルト変数 statepresent に設定し、Foo の CR インスタンスを作成します。

    $ oc create -f deploy/cr.yaml
  6. namespace test が作成されていることを確認します。

    $ oc get namespace
    NAME          STATUS    AGE
    default       Active    28d
    kube-public   Active    28d
    kube-system   Active    28d
    test          Active    3s
  7. deploy/cr.yaml ファイルを、state フィールドを absent に設定するように変更します。

    apiVersion: "foo.example.com/v1alpha1"
    kind: "Foo"
    metadata:
      name: "example"
    spec:
      state: "absent"
  8. 変更を適用し、namespace が定義されていることを確認します。

    $ oc apply -f deploy/cr.yaml
    
    $ oc get namespace
    NAME          STATUS    AGE
    default       Active    28d
    kube-public   Active    28d
    kube-system   Active    28d
11.2.4.3.2. Ansible ベース Operator のクラスター上でのテスト

Ansible ロジックを Ansible ベース Operator 内でローカルに実行することに慣れたら、OpenShift Container Platform などの Kubernetes クラスターの Pod 内で Operator をテストすることができます。Pod のクラスターでの実行は、実稼働環境で優先される方法です。

手順

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

    $ operator-sdk build quay.io/example/foo-operator:v0.0.1
    $ podman push quay.io/example/foo-operator:v0.0.1
  2. Deployment マニフェストは deploy/operator.yaml ファイルに生成されます。このファイルの Deployment イメージはプレースホルダーの REPLACE_IMAGE から以前にビルドされたイメージに変更される必要があります。これを実行するには、以下のコマンドを実行します。

    $ sed -i 's|REPLACE_IMAGE|quay.io/example/foo-operator:v0.0.1|g' deploy/operator.yaml

    OSX でこれらの手順を実行している場合には、代わりに以下のコマンドを実行します。

    $ sed -i "" 's|REPLACE_IMAGE|quay.io/example/foo-operator:v0.0.1|g' deploy/operator.yaml
  3. foo-operator をデプロイします。

    $ oc create -f deploy/crds/foo_v1alpha1_foo_crd.yaml # if CRD doesn't exist already
    $ 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. foo-operator が稼働していることを確認します。

    $ oc get deployment
    NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    foo-operator       1         1         1            1           1m

11.2.5. k8s_status Ansible モジュールの使用によるカスタムリソースステータスの管理

Ansible ベースの Operator は、カスタムリソース (CR) status サブリソースを以前の Ansible 実行についての一般的な情報で自動的に更新します。これには、以下のように成功したタスクおよび失敗したタスクの数と関連するエラーメッセージが含まれます。

status:
  conditions:
    - ansibleResult:
      changed: 3
      completion: 2018-12-03T13:45:57.13329
      failures: 1
      ok: 6
      skipped: 0
    lastTransitionTime: 2018-12-03T13:45:57Z
    message: 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno
      113] No route to host>'
    reason: Failed
    status: "True"
    type: Failure
  - lastTransitionTime: 2018-12-03T13:46:13Z
    message: Running reconciliation
    reason: Running
    status: "True"
    type: Running

Ansible ベースの Operator は、Operator の作成者が k8s_status Ansible モジュールでカスタムステータスの値を指定することも可能にします。これにより、作成者は必要に応じ、任意のキー/値のペアを使って Ansible から status を更新できます。

デフォルトでは、Ansible ベースの Operator には、上記のように常に汎用的な Ansible 実行出力が含まれます。アプリケーションのステータスが Ansible 出力で更新 されない ようにする必要がある場合に、アプリケーションからステータスを手動で追跡することができます。

手順

  1. CR ステータスをアプリケーションから手動で追跡するには、 manageStatus フィールドを false に設定して監視ファイルを更新します。

    - version: v1
      group: api.example.com
      kind: Foo
      role: /opt/ansible/roles/Foo
      manageStatus: false
  2. 次に、k8s_status Ansible モジュールを使用してサブリソースを更新します。たとえば、キー foo および値 bar を使用して更新するには、k8s_status を以下のように使用することができます。

    - k8s_status:
      api_version: app.example.com/v1
      kind: Foo
      name: "{{ meta.name }}"
      namespace: "{{ meta.namespace }}"
      status:
        foo: bar

追加リソース

  • Ansible ベース Operator からのユーザー主導のステータス管理を行う方法についての詳細は、「Ansible Operator Status Proposal」を参照してください。

11.2.5.1. ローカルでのテスト時の k8s_status Ansible モジュールの使用

Operator が k8s_status Ansible モジュールを使用し、Operator を operator-sdk up local コマンドでローカルにテストする必要がある場合、モジュールを Ansible が予想する場所にインストールする必要があります。これは、Ansible の library 設定オプションを使用して実行されます。

この例では、ユーザーがサードパーティーの Ansible モジュールを /usr/share/ansible/library/ ディレクトリーに配置することを前提としています。

手順

  1. k8s_status モジュールをインストールするには、ansible.cfg ファイルを、インストール済みの Ansible モジュールを /usr/share/ansible/library/ ディレクトリーで検索するように設定します。

    $ echo "library=/usr/share/ansible/library/" >> /etc/ansible/ansible.cfg
  2. k8s_status.py ファイルを /usr/share/ansible/library/ ディレクトリーに追加します。

    $ wget https://raw.githubusercontent.com/openshift/ocp-release-operator-sdk/master/library/k8s_status.py -O /usr/share/ansible/library/k8s_status.py

11.2.6. 追加リソース