第11章 Operator SDK
11.1. Operator SDK の使用を開始する
以下では、Operator SDK の基本事項についての概要を説明し、単純な Go ベースの Memcached Operator のビルドおよびインストールからアップグレードまでのそのライフサイクル管理の例を使って、(OpenShift Container Platform などの) クラスター管理者の Kubernetes ベースのクラスターへのアクセスを持つ Operator の作成者を支援します。
これは、Operator SDK (operator-sdk
CLI ツールおよび controller-runtime
ライブラリー API) と Operator Lifecycle Manager (OLM) という 2 つの Operator Framework の重要な構成要素を使用して実行されます。
OpenShift Container Platform 4 は Operator SDK v0.7.0 以降をサポートします。
11.1.1. Operator SDK のアーキテクチャー
Operator Framework は Operator という Kubernetes ネイティブアプリケーションを効果的かつ自動化された拡張性のある方法で管理するためのオープンソースツールキットです。Operator は、プロビジョニング、スケーリング、バックアップおよび復元などのクラウドサービスの自動化の利点を提供し、同時に Kubernetes が実行されるいずれの場所でも実行できます。
Operator により、Kubernetes の上部に複雑で、ステートフルなアプリケーションを管理することが容易になります。ただし、現時点で Operator の作成は、低レベルの API の使用、スケルトンコードの作成、モジュール化の欠如による重複の発生などの課題があるために困難になる場合があります。
Operator SDK は、以下を提供して Operator をより容易に作成できるように設計されたフレームワークです。
- 運用ロジックをより直感的に作成するための高レベルの API および抽象化
- 新規プロジェクトを迅速にブートストラップするためのスケルトンコードの作成およびコード生成ツール
- 共通する Operator ユースケースに対応する拡張機能
11.1.1.1. ワークフロー
Operator SDK は、新規 Operator を開発するために以下のワークフローを提供します。
- Operator SDK コマンドラインインターフェース (CLI) を使用した新規 Operator プロジェクトの作成。
- カスタムリソース定義 (CRD) を追加することによる新規リソース API の定義。
- Operator SDK API を使用した監視対象リソースの指定。
- 指定されたハンドラーでの Operator 調整 (reconciliation) ロジックの定義、およびリソースと対話するための Operator SDK API の使用。
- Operator Deployment マニフェストをビルドし、生成するための Operator SDK CLI の使用。
図11.1 Operator SDK ワークフロー
高次元では、Operator SDK を使用する Operator は Operator の作成者が定義するハンドラーで監視対象のリソースについてのイベントを処理し、アプリケーションの状態を調整するための動作を実行します。
11.1.1.2. マネージャーファイル
Operator の主なプログラムは、cmd/manager/main.go
のマネージャーファイルです。マネージャーは、pkg/apis/
で定義されるすべてのカスタムリソース(CR) のスキームを自動的に登録し、pkg/controller/
下のすべてのコントローラーを実行します。
マネージャーは、すべてのコントローラーがリソースの監視に使用する namespace を制限できます。
mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
デフォルトでは、これは Operator が実行されている namespace です。すべての namespace を確認するには、namespace オプションのオプションを空のままにすることができます。
mgr, err := manager.New(cfg, manager.Options{Namespace: ""})
11.1.1.3. Prometheus Operator
Prometheus はオープンソースのシステムモニタリングおよびアラートツールキットです。Prometheus Operator は、 OpenShift Container Platform などの Kubernetes ベースのクラスターで実行される Prometheus クラスターを作成し、設定し、管理します。
ヘルパー関数は、デフォルトで Operator SDK に存在し、Prometheus Operator がデプロイされているクラスターで使用できるように生成された Go ベースの Operator にメトリクスを自動的にセットアップします。
11.1.2. Operator SDK CLI のインストール
Operator SDK には、開発者による新規 Operator プロジェクトの作成、ビルドおよびデプロイを支援をする CLI ツールが含まれます。ワークステーションに SDK CLI をインストールして、独自の Operator のオーサリングを開始することができます。
11.1.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.1.2.2. Homebrew からのインストール
Homebrew を使用して SDK CLI をインストールできます。
前提条件
手順
brew
コマンドを使用して SDK CLI をインストールします。$ brew install operator-sdk
CLI ツールが正しくインストールされていることを確認します。
$ operator-sdk version
11.1.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.1.3. Operator SDK を使用した Go ベースの Memcached Operator のビルド
Operator SDK は、詳細なアプリケーション固有の運用上の知識を必要とする可能性のあるプロセスである、Kubernetes ネイティブアプリケーションのビルドを容易にします。SDK はこの障壁を低くするだけでなく、メータリングやモニタリングなどの数多くの一般的な管理機能に必要なスケルトンコードの量を減らします。
この手順では、SDK によって提供されるツールおよびライブラリーを使用して単純な Memcached Operator をビルドする例を示します。
前提条件
- 開発ワークステーションにインストールされる Operator SDK CLI
-
OpenShift Container Platform 4.1 などの、Kubernetes ベースのクラスター (v1.8 以上の
apps/v1beta2
API グループをサポートするもの) にインストールされる Operator Lifecycle Manager (OLM) -
cluster-admin
パーミッションのあるアカウントを使用したクラスターへのアクセス -
OpenShift CLI (
oc
) v4.1+ (インストール済み)
手順
新規プロジェクトを作成します。
CLI を使用して新規
memcached-operator
プロジェクトを作成します。$ mkdir -p $GOPATH/src/github.com/example-inc/ $ cd $GOPATH/src/github.com/example-inc/ $ operator-sdk new memcached-operator --dep-manager dep $ cd memcached-operator
新規カスタムリソース定義 (CRD) を追加します。
APIVersion
をcache.example.com/v1apha1
に設定し、Kind
をMemcached
に設定した状態で、CLI を使用してMemcached
という新規 CRD API を追加します。$ operator-sdk add api \ --api-version=cache.example.com/v1alpha1 \ --kind=Memcached
これにより、
pkg/apis/cache/v1alpha1/
の下で Memcached resource API のスキャフォールディングが実行されます。pkg/apis/cache/v1alpha1/memcached_types.go
ファイルで、Memcached
カスタムリソース (CR) の仕様およびステータスを変更します。type MemcachedSpec struct { // Size is the size of the memcached deployment Size int32 `json:"size"` } type MemcachedStatus struct { // Nodes are the names of the memcached pods Nodes []string `json:"nodes"` }
*_types.go
ファイルを変更後は、以下のコマンドを常に実行し、該当するリソースタイプ用に生成されたコードを更新します。$ operator-sdk generate k8s
新規コントローラーを追加します。
新規コントローラーをプロジェクトに追加し、 Memcached リソースを確認し、調整します。
$ operator-sdk add controller \ --api-version=cache.example.com/v1alpha1 \ --kind=Memcached
これにより、
pkg/controller/memcached/
の下で新規コントローラー実装のスキャフォールディングが実行されます。この例では、生成されたコントローラーファイル
pkg/controller/memcached/memcached_controller.go
を実装例に置き換えます。コントローラーのサンプルは、それぞれの
Memcached
CR について以下の調整 (reconciliation) ロジックを実行します。- Memcached Deployment を作成します (ない場合)。
-
Deployment のサイズが、
Memcached
CR 仕様で指定されるのと同じであることを確認します。 -
Memcached
CR ステータスを Memcached Pod の名前で置き換えます。
次の 2 つのサブステップでは、コントローラーがリソースを監視する方法および調整ループがトリガーされる方法を検査します。これらの手順を省略し、直接 Operator のビルドおよび実行に進むことができます。
pkg/controller/memcached/memcached_controller.go
ファイルでコントローラーの実装を検査し、コントローラーのリソースの監視方法を確認します。最初の監視は、プライマリーソースとしての Memcached タイプに対して実行します。それぞれの Add、Update、または Delete イベントについて、reconcile ループに Memcached オブジェクトの reconcile
Request
(<namespace>:<name>
キー) が送られます。err := c.Watch( &source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{})
次の監視は、Deployment に対して実行されますが、イベントハンドラーは各イベントを、Deployment のオーナーの reconcile
Request
にマップします。この場合、これは Deployment が作成された Memcached オブジェクトです。これにより、コントローラーは Deployment をセカンダリーリソースとして監視できます。err := c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ IsController: true, OwnerType: &cachev1alpha1.Memcached{}, })
すべてのコントローラーには、reconcile ループを実装する
Reconcile()
メソッドのある Reconciler オブジェクトがあります。この reconcile ループには、キャッシュからプライマリーリソースオブジェクトの Memcached を検索するために使用される<namespace>:<name>
キーであるRequest
引数が渡されます。func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error) { // Lookup the Memcached instance for this reconcile request memcached := &cachev1alpha1.Memcached{} err := r.client.Get(context.TODO(), request.NamespacedName, memcached) ... }
Reconcile()
の戻り値に応じて、reconcileRequest
は再度キューに入れられ、ループが再びトリガーされる可能性があります。// Reconcile successful - don't requeue return reconcile.Result{}, nil // Reconcile failed due to error - requeue return reconcile.Result{}, err // Requeue for any reason other than error return reconcile.Result{Requeue: true}, nil
Operator をビルドし、実行します 。
Operator の実行前に、CRD を Kubernetes API サーバーに再度登録する必要があります。
$ oc create \ -f deploy/crds/cache_v1alpha1_memcached_crd.yaml
CRD の登録後に、Operator を実行するための 2 つのオプションを選択できます。
- Kubernetes クラスター内の Deployment を使用
- クラスター内の Go プログラムを使用
以下の方法のいずれかを選択します。
オプション A: クラスター内の Deployment として実行する。
memcached-operator
イメージをビルドし、これをレジストリーにプッシュします。$ operator-sdk build quay.io/example/memcached-operator:v0.0.1
Deployment マニフェストは
deploy/operator.yaml
に生成されます。デフォルトはプレースホルダーでしかないため、以下のように Deployment イメージを更新します。$ sed -i 's|REPLACE_IMAGE|quay.io/example/memcached-operator:v0.0.1|g' deploy/operator.yaml
-
次のステップについての quay.io にアカウントがあることを確認するか、または優先しているコンテナーレジストリーで置き換えます。レジストリーには、memcached-operator という名前の
新規パブリックイメージ
リポジトリーを作成します。 イメージをレジストリーにプッシュします。
$ docker push quay.io/example/memcached-operator:v0.0.1
RBAC をセットアップし、
memcached-operator
をデプロイします。$ oc create -f deploy/role.yaml $ oc create -f deploy/role_binding.yaml $ oc create -f deploy/service_account.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
オプション B: クラスター外でローカルに実行する。
この方法は、迅速にデプロイメントおよびテストを実行するための開発サイクルで優先される方法です。
$HOME/.kube/config
にあるデフォルトの Kubernetes 設定ファイルを使用して Operator をローカルで実行します。$ operator-sdk up local --namespace=default
フラグ
--kubeconfig=<path/to/kubeconfig>
を使用して特定のkubeconfig
を使用できます。
Memcached CR を作成して、Operator が Memcached アプリケーションをデプロイできることを確認します。
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
ステータスが
memcached
Pod 名で更新されていることを確認するために、Pod および CR ステータスをチェックします。$ 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 $ oc get memcached/example-memcached -o yaml apiVersion: cache.example.com/v1alpha1 kind: Memcached metadata: clusterName: "" creationTimestamp: 2018-03-31T22:51:08Z generation: 0 name: example-memcached namespace: default resourceVersion: "245453" selfLink: /apis/cache.example.com/v1alpha1/namespaces/default/memcacheds/example-memcached uid: 0026cc97-3536-11e8-bd83-0800274106a1 spec: size: 3 status: nodes: - example-memcached-6fd7c98d8-7dqdr - example-memcached-6fd7c98d8-g5k7v - example-memcached-6fd7c98d8-m7vn7
デプロイメントのサイズを更新し、Operator がデプロイ済みの Memcached アプリケーションを管理できることを確認します 。
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/crds/cache_v1alpha1_memcached_crd.yaml $ oc delete -f deploy/operator.yaml $ oc delete -f deploy/role.yaml $ oc delete -f deploy/role_binding.yaml $ oc delete -f deploy/service_account.yaml
11.1.4. Operator Lifecycle Manager を使用した Memcached Operator の管理
直前のセクションでは、Operator を手動で実行することについて説明しました。次のセクションでは、実稼働環境で実行される Operator のより堅牢なデプロイメントモデルを可能にする Operator Lifecycle Manager (OLM) の使用方法について説明します。
OLM は、Kubernetes クラスターで Operator (およびそれらの関連サービス) をインストールし、更新し、通常はそれらすべての Operator のライフサイクルを管理するのに役立ちます。これは、Kubernetes 拡張として実行され、追加のツールなしにすべてのライフサイクル管理機能について oc
を使用できます。
前提条件
-
OLM が (
apps/v1beta2
API グループをサポートする v1.8 以上のバージョンの) Kubernetes ベースのクラスターにインストールされていること。 たとえば、 OpenShift Container Platform 4.1 Preview OLM が有効にされていること。 - Memcached Operator がビルドされていること。
手順
Operator マニフェストを生成します 。
Operator マニフェストは、アプリケーションを表示し、作成し、管理する方法について説明します (この場合は Memcached)。これは
ClusterServiceVersion
(CSV) オブジェクトで定義され、OLM が機能するために必要です。以下のコマンドを使用して CSV マニフェストを生成することができます。
$ operator-sdk olm-catalog gen-csv --csv-version 0.0.1
注記このコマンドは、Memcached Operator のビルド時に作成された
memcached-operator/
ディレクトリーから実行されます。本書の目的を考慮し、次のいくつかのステップにおいても引き続きこの事前に定義されたマニフェストファイルを使用します。このマニフェスト内のイメージフィールドを変更して、直前のステップでビルドしたイメージを反映させることができますが、これは不要です。
注記マニフェストファイルの手動による定義についての詳細は、「Building a CSV for the Operator Framework」を参照してください。
Operator をデプロイします。
Operator がターゲットとする namespace を指定する OperatorGroup を作成します。以下の OperatorGroup を、CSV を作成する namespace に作成します。この例では、
default
namespace が使用されます。apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: memcached-operator-group namespace: default spec: targetNamespaces: - default
Operator の CSV マニフェストをクラスターの指定された namespace に適用します。
$ curl -Lo memcachedoperator.0.0.1.csv.yaml https://raw.githubusercontent.com/operator-framework/getting-started/master/memcachedoperator.0.0.1.csv.yaml $ oc apply -f memcachedoperator.0.0.1.csv.yaml $ oc get csv memcachedoperator.v0.0.1 -n default -o json | jq '.status'
このマニフェストを適用する際に、クラスターはマニフェストで指定された要件を満たしていないためにすぐに更新を実行しません。
リソースパーミッションを Operator に付与するためにロール、ロールバインディング、およびサービスアカウントを作成し、Operator が管理する Memcached タイプを作成するためにカスタムリソース定義 (CRD、Custom Resource Definition) を作成します。
$ oc create -f deploy/crds/cache_v1alpha1_memcached_crd.yaml $ oc create -f deploy/service_account.yaml $ oc create -f deploy/role.yaml $ oc create -f deploy/role_binding.yaml
注記これらのファイルは、Memcached Operator のビルド時に Operator SDK よって
deploy/
ディレクトリーに生成されています。マニフェストの適用時に OLM は Operator を特定の namespace に作成するため、管理者は、Operator をインストールできるユーザーを制限するためのネイティブの Kubernetes RBAC パーミッションモデルを利用できます。
アプリケーションインスタンスを作成します 。
Memcached Operator が
default
namespace で実行されるようになります。ユーザーはCustomResources
のインスタンス経由で Operator と対話します。この場合、リソースにはMemcached
の種類が設定されます。ネイティブの Kubernetes RBAC はCustomResources
に適用され、管理者には各 Operater と対話できるユーザーへの制御が提供されます。この namespace で Memcached のインスタンスを作成することにより、Operator で管理される memcached サーバーを実行する Pod をインスタンス化するために Memcached Operator がトリガーされます。
CustomResources
をより多く作成すると、Memcached のより多くの固有なインスタンスがこの namespace で実行されている Memcached Operator によって管理されます。$ cat <<EOF | oc apply -f - apiVersion: "cache.example.com/v1alpha1" kind: "Memcached" metadata: name: "memcached-for-wordpress" spec: size: 1 EOF $ cat <<EOF | oc apply -f - apiVersion: "cache.example.com/v1alpha1" kind: "Memcached" metadata: name: "memcached-for-drupal" spec: size: 1 EOF $ oc get Memcached NAME AGE memcached-for-drupal 22s memcached-for-wordpress 27s $ oc get pods NAME READY STATUS RESTARTS AGE memcached-app-operator-66b5777b79-pnsfj 1/1 Running 0 14m memcached-for-drupal-5476487c46-qbd66 1/1 Running 0 3s memcached-for-wordpress-65b75fd8c9-7b9x7 1/1 Running 0 8s
アプリケーションを更新します。
新規 Operator マニフェストを、古い Operator マニフェストを参照する
replaces
フィールドを使って作成し、更新を Operator に手動で適用します。OLM は、古い Operator で管理されているすべてのリソースの所有権が、いずれのプログラムも停止することなく新規 Operator に移行できるようにします。新規バージョンの Operator 下で実行するリソースのアップグレードに必要なデータ移行を実行するかどうかは Operator によって異なります。以下のコマンドは、新規バージョンの Operator を使用して新規 Operator マニフェストファイルを適用する方法を示し、Pod が実行状態であることを示します。
$ curl -Lo memcachedoperator.0.0.2.csv.yaml https://raw.githubusercontent.com/operator-framework/getting-started/master/memcachedoperator.0.0.2.csv.yaml $ oc apply -f memcachedoperator.0.0.2.csv.yaml $ oc get pods NAME READY STATUS RESTARTS AGE memcached-app-operator-66b5777b79-pnsfj 1/1 Running 0 3s memcached-for-drupal-5476487c46-qbd66 1/1 Running 0 14m memcached-for-wordpress-65b75fd8c9-7b9x7 1/1 Running 0 14m
11.1.5. 追加リソース
- Operator SDK によって作成されるプロジェクトディレクトリー構造についての詳細は、「Appendices」を参照してください。
- Operator Development Guide for Red Hat Partners