11.2. Ansible ベース Operator の作成
以下では、Operator SDK における Ansible サポートについての概要を説明し、Operator の作成者に、Ansible Playbook およびモジュールを使用する operator-sdk
CLI ツールを使って Ansible ベースの Operator をビルドし、実行するサンプルを示します。
11.2.1. Operator SDK における Ansible サポート
Operator Framework は Operator という 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 リソースファイルです。オブジェクトには、必須およびオプションフィールドが含まれます。
フィールド | 説明 |
---|---|
| 作成される CR のバージョン。 |
| 作成される CR の種類。 |
| 作成される Kubernetes 固有のメタデータ。 |
| Ansible に渡される変数のキーと値の一覧。このフィールドは、デフォルトでは空です。 |
|
オブジェクトの現在の状態の概要を示します。Ansible ベースの Operator の場合、 |
| CR に付加する Kubernetes 固有のアノテーション。 |
CR アノテーションの以下の一覧は Operator の動作を変更します。
アノテーション | 説明 |
---|---|
|
CR の調整間隔を指定します。この値は標準的な Golang パッケージ |
Ansible ベースの Operator アノテーションの例
apiVersion: "foo.example.com/v1alpha1" kind: "Foo" metadata: name: "example" annotations: ansible.operator-sdk/reconcile-period: "30s"
11.2.1.2. 監視ファイル
監視ファイルには、Group
、Version
、および Kind
などによって特定される、カスタムリソース (CR) から Ansible ロールまたは Playbook へのマッピングの一覧が含まれます。Operator はこのマッピングファイルが事前に定義された場所の /opt/ansible/watches.yaml
にあることを予想します。
フィールド | 説明 |
---|---|
| 監視する CR のグループ。 |
| 監視する CR のバージョン。 |
| 監視する CR の種類。 |
|
コンテナーに追加される Ansible ロールへのパスです。たとえば、 |
|
コンテナーに追加される Ansible Playbook へのパスです。この Playbook は単純にロールを呼び出す方法になります。このフィールドは |
| ロールまたは 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
11.2.1.2.1. 高度なオプション
高度な機能は、それらを GVK (グループ、バージョン、および種類) ごとに監視ファイルに追加して有効にできます。それらは group
、version
、kind
および playbook
または role
フィールドの下に移行できます。
一部の機能は、カスタムリソース (CR) のアノテーションを使用してリソースごとに上書きできます。オーバーライドできるオプションには、以下に指定されるアノテーションが含まれます。
機能 | YAML キー | 説明 | 上書きのアノテーション | デフォルト値 |
---|---|---|---|---|
調整期間 |
| 特定の CR についての調整実行の間隔。 |
|
|
ステータスの管理 |
|
Operator は各 CR の |
| |
依存するリソースの監視 |
| Operator は Ansible によって作成されるリソースを動的に監視できます。 |
| |
クラスタースコープのリソースの監視 |
| Operator は Ansible によって作成されるクラスタースコープのリソースを監視できます。 |
| |
最大 Runner アーティファクト |
| Ansible Runner が各リソースについて Operator コンテナーに保持するアーティファクトディレクトリーの数を管理します。 |
|
|
高度なオプションを含む監視ファイルの例
- 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>
に置かれます。
追加リソース
-
runner
ディレクトリーについての詳細は、Ansible Runner ドキュメントを参照してください。
11.2.2. Operator SDK CLI のインストール
Operator SDK には、開発者による新規 Operator プロジェクトの作成、ビルドおよびデプロイを支援をする CLI ツールが含まれます。ワークステーションに SDK CLI をインストールして、独自の Operator のオーサリングを開始することができます。
11.2.2.1. GitHub リリースからのインストール
GitHub のプロジェクトから SDK CLI の事前ビルドリリースのバイナリーをダウンロードし、インストールできます。
前提条件
-
docker
v17.03+ -
OpenShift CLI (
oc
) v4.1+ (インストール済み) - Kubernetes v1.11.3+ に基づくクラスターへのアクセス
- コンテナーレジストリーへのアクセス
手順
リリースバージョン変数を設定します。
RELEASE_VERSION=v0.8.0
リリースバイナリーをダウンロードします。
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
ダウンロードしたリリースのバイナリーを確認します。
提供された 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
バイナリーと対応する 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
オプションで指定します。
リリースバイナリーを
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
CLI ツールが正しくインストールされていることを確認します。
$ operator-sdk version
11.2.2.2. Homebrew からのインストール
Homebrew を使用して SDK CLI をインストールできます。
前提条件
手順
brew
コマンドを使用して SDK CLI をインストールします。$ brew install operator-sdk
CLI ツールが正しくインストールされていることを確認します。
$ operator-sdk version
11.2.2.3. ソースを使用したコンパイルおよびインストール
Operator SDK ソースコードを取得して、SDK CLI をコンパイルし、インストールできます。
前提条件
手順
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
必要なリリースブランチをチェックアウトします。
$ git checkout master
SDK CLI ツールをコンパイルし、インストールします。
$ make dep $ make install
これにより、$GOPATH/bin に CLI バイナリー
operator-sdk
がインストールされます。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.2 など) へのアクセス -
OpenShift CLI (
oc
) v4.1+ (インストール済み) -
ansible
v2.6.0+ -
ansible-runner
v1.1.0+ -
ansible-runner-http
v1.0.0+
手順
operator-sdk new
コマンドを使用して、namespace スコープまたはクラスタースコープのいずれかで 新規 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
および KindMemcached
の Memcached リソースを監視するためのmemcached-operator
プロジェクトが作成されます。クラスタースコープの 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 に変更される必要があります。
-
-
Operator ロジックをカスタマイズします。
この例では、
memcached-operator
はそれぞれのMemcached
カスタムリソース (CR) について以下の調整 (reconciliation) ロジックを実行します。-
memcached
Deployment を作成します (ない場合)。 -
Deployment のサイズが
Memcached
CR で指定されるのと同じであることを確認します。
デフォルトで、
memcached-operator
はwatches.yaml
ファイルに示されるようにMemcached
リソースイベントを監視し、Ansible ロールMemcached
を実行します。- version: v1alpha1 group: cache.example.com kind: Memcached
オプションで、以下のロジックを
watches.yaml
ファイルでカスタマイズできます。role
オプションを指定して、ansible-runner
を Ansible ロールを使って起動する際に Operator がこの特定のパスを使用するように設定します。デフォルトでは、新規コマンドでロールが置かれる場所への絶対パスが入力されます。- version: v1alpha1 group: cache.example.com kind: Memcached role: /opt/ansible/roles/memcached
playbook
オプションをwatches.yaml
ファイルに指定して、ansible-runner
を Ansible Playbook で起動する際に Operator がこの指定されたパスを使用するように設定します。- version: v1alpha1 group: cache.example.com kind: Memcached playbook: /opt/ansible/playbook.yaml
-
Memcached Ansible ロールをビルドします。
生成された Ansible ロールを
roles/memcached/
ディレクトリーの下で変更します。この Ansible ロールは、リソースの変更時に実行されるロジックを制御します。Memcached
仕様を定義します。Ansible ベースの Operator の定義は Ansible 内ですべて実行できます。Ansible Operator は CR 仕様フィールドのすべてのキー/値ペアを 変数として Ansible に渡します。仕様フィールドのすべての変数の名前は、Ansible の実行前に Operator によってスネークケース (小文字 + アンダースコア) に変換されます。たとえば、仕様の
serviceAccount
は Ansible ではservice_account
になります。ヒントAnsible で変数についてのタイプの検証を実行し、アプリケーションが予想される入力を受信できることを確認する必要があります。
ユーザーが
spec
フィールドを設定しない場合、roles/memcached/defaults/main.yml
ファイルを変更してデフォルトを設定します。size: 1
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 を作成することができます。
CRD をデプロイします。
Operator の実行前に、Kubernetes は Operator が監視する新規カスタムリソース定義 (CRD) について把握している必要があります。
Memcached
CRD をデプロイします。$ oc create -f deploy/crds/cache_v1alpha1_memcached_crd.yaml
Operator をビルドし、実行します 。
Operator をビルドし、実行する方法として 2 つの方法を使用できます。
- Kubernetes クラスター内の Pod を使用
-
operator-sdk up
コマンドを使用してクラスター外で Go プログラムを使用
以下の方法のいずれかを選択します。
Kubernetes クラスター内で Pod として実行 します。これは実稼働環境での優先される方法です。
memcached-operator
イメージをビルドし、これをレジストリーにプッシュします。$ operator-sdk build quay.io/example/memcached-operator:v0.0.1 $ podman push quay.io/example/memcached-operator:v0.0.1
Deployment マニフェストは
deploy/operator.yaml
ファイルに生成されます。このファイルの Deployment イメージは、プレースホルダーREPLACE_IMAGE
から直前にビルドされたイメージに変更される必要があります。これを実行するには、以下を実行します。$ sed -i 's|REPLACE_IMAGE|quay.io/example/memcached-operator:v0.0.1|g' deploy/operator.yaml
--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
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
memcached-operator
が稼働していることを確認します。$ oc get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE memcached-operator 1 1 1 1 1m
クラスター外で実行します。この方法は、デプロイメントおよびテストの速度を上げるために開発サイクル時に優先される方法です。
Ansible Runner および Ansible Runner HTTP プラグインがインストールされていることを確認します。 インストールされていない場合、CR の作成時に Ansible Runner から予想しないエラーが発生します。
さらに、
watches.yaml
ファイルで参照されるロールパスがマシン上にある必要があります。通常、コンテナーはディスク上のロールが置かれる場所で使用されるため、ロールは設定済みの Ansible ロールパス (例:/etc/ansible/roles
) に手動でコピーされる必要があります。$HOME/.kube/config
にあるデフォルトの Kubernetes 設定ファイルを使って Operator をローカルに実行するには、以下を実行します。$ operator-sdk up local
提供された Kubernetes 設定ファイルを使って Operator をローカルに実行するには、以下を実行します。
$ operator-sdk up local --kubeconfig=config
Memcached
CR を作成します。以下に示されるように
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
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
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
サイズを更新します。
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
Operator が Deployment サイズを変更することを確認します。
$ oc get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-memcached 4 4 4 4 5m
リソースをクリーンアップします。
$ 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 モジュールをローカルワークステーションにインストールするには、以下を実行します。
手順
Ansible 2.6+ をインストールします。
$ sudo yum install ansible
pip を使用して
OpenShift python クライアント
パッケージをインストールします。$ pip install openshift
11.2.4.2. k8s Ansible モジュールのローカルでのテスト
開発者が毎回 Operator を実行し、再ビルドするのではなく、Ansible コードをローカルマシンから実行する方が利点がある場合があります。
手順
新規 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
必要な 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
を設定することにより、存在しないプロジェクトを削除しても失敗しません。
roles/Foo/defaults/main.yml
ファイルを、デフォルトでstate
をpresent
に設定するように変更します。state: present
上部ディレクトリーに、
Foo
ロールを含む Ansible Playbookplaybook.yml
を作成します。- hosts: localhost roles: - Foo
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
namespace が作成されていることを確認します。
$ oc get namespace NAME STATUS AGE default Active 28d kube-public Active 28d kube-system Active 28d test Active 3s
state
をabsent
に設定して 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
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 クラスターと通信します。
手順
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
カスタムリソース定義 (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
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
Operator はリソース
Foo
でイベントを監視しているため、CR の作成により、Ansible ロールの実行がトリガーされます。deploy/cr.yaml
ファイルを表示します。apiVersion: "foo.example.com/v1alpha1" kind: "Foo" metadata: name: "example"
spec
フィールドは設定されていないため、Ansible は追加の変数なしで起動します。次のセクションでは、追加の変数が CR から Ansible に渡される方法について説明します。このため、Operator に同じでデフォルト値を設定することが重要になります。デフォルト変数
state
をpresent
に設定し、Foo
の CR インスタンスを作成します。$ oc create -f deploy/cr.yaml
namespace
test
が作成されていることを確認します。$ oc get namespace NAME STATUS AGE default Active 28d kube-public Active 28d kube-system Active 28d test Active 3s
deploy/cr.yaml
ファイルを、state
フィールドをabsent
に設定するように変更します。apiVersion: "foo.example.com/v1alpha1" kind: "Foo" metadata: name: "example" spec: state: "absent"
変更を適用し、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 のクラスターでの実行は、実稼働環境で優先される方法です。
手順
foo-operator
イメージをビルドし、これをレジストリーにプッシュします。$ operator-sdk build quay.io/example/foo-operator:v0.0.1 $ podman push quay.io/example/foo-operator:v0.0.1
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
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
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 出力で更新 されない ようにする必要がある場合に、アプリケーションからステータスを手動で追跡することができます。
手順
CR ステータスをアプリケーションから手動で追跡するには、
manageStatus
フィールドをfalse
に設定して監視ファイルを更新します。- version: v1 group: api.example.com kind: Foo role: /opt/ansible/roles/Foo manageStatus: false
次に、
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/
ディレクトリーに配置することを前提としています。
手順
k8s_status
モジュールをインストールするには、ansible.cfg
ファイルを、インストール済みの Ansible モジュールを/usr/share/ansible/library/
ディレクトリーで検索するように設定します。$ echo "library=/usr/share/ansible/library/" >> /etc/ansible/ansible.cfg
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. 追加リソース
- Operator SDK によって作成されるプロジェクトディレクトリー構造についての詳細は、「Appendices」を参照してください。
- Reaching for the Stars with Ansible Operator - Red Hat OpenShift Blog
- Operator Development Guide for Red Hat Partners