11.3. Helm ベース Operator の作成
以下では、Operator SDK での Helm チャートのサポートについての概要を説明し、Operator 作成者を対象に、既存の Helm チャートを使用する operator-sdk
CLI ツールで Nginx Operator をビルドし、実行する例を示します。
11.3.1. Operator SDK での Helm チャートのサポート
Operator Framework は Operator という Kubernetes ネイティブアプリケーションを効果的かつ自動化された拡張性のある方法で管理するためのオープンソースツールキットです。このフレームワークには Operator SDK が含まれ、これは Kubernetes API の複雑性を把握していなくても、それぞれの専門知識に基づいて Operator のブートストラップおよびビルドを実行できるように開発者を支援します。
Operator プロジェクトを生成するための Operator SDK のオプションの 1 つとして、Go コードを作成せずに既存の Helm チャートを使用して Kubernetes リソースを統一されたアプリケーションとしてデプロイするオプションがあります。このような Helm ベースの Operator では、変更はチャートの一部として生成される Kubernetes オブジェクトに適用されるため、ロールアウト時にロジックをほとんど必要としないステートレスなアプリケーションを使用する際に適しています。いくらか制限があるような印象を与えるかもしれませんが、Kubernetes コミュニティーがビルドする Helm チャートが急速に増加していることからも分かるように、この Operator は数多くのユーザーケースに対応することができます。
Operator の主な機能として、アプリケーションインスタンスを表すカスタムオブジェクトから読み取り、必要な状態を実行されている内容に一致させることができます。Helm ベース Operator の場合、オブジェクトの仕様フィールドは、通常 Helm の values.yaml
ファイルに記述される設定オプションの一覧です。Helm CLI を使用してフラグ付きの値を設定する代わりに (例: helm install -f values.yaml
)、これらをカスタムリソース (CR) 内で表現することができます。 これにより、ネイティブ Kubernetes オブジェクトとして、適用される RBAC および監査証跡の利点を活用できます。
Tomcat
という単純な CR の例:
apiVersion: apache.org/v1alpha1 kind: Tomcat metadata: name: example-app spec: replicaCount: 2
この場合の replicaCount
値、2
は以下が使用されるチャートのテンプレートに伝播されます。
{{ .Values.replicaCount }}
Operator のビルドおよびデプロイ後に、CR の新規インスタンスを作成してアプリケーションの新規インスタンスをデプロイしたり、 oc
コマンドを使用してすべての環境で実行される異なるインスタンスを一覧表示したりすることができます。
$ oc get Tomcats --all-namespaces
Helm CLI を使用したり、Tiller をインストールしたりする必要はありません。Helm ベースの Operator はコードを Helm プロジェクトからインポートします。Operator のインスタンスを実行状態にし、カスタムリソース定義 (CRD) に CR を登録することのみが必要になります。 さらにこれは RBAC に準拠するため、実稼働環境の変更を簡単に防止することができます。
11.3.2. Operator SDK CLI のインストール
Operator SDK には、開発者による新規 Operator プロジェクトの作成、ビルドおよびデプロイを支援をする CLI ツールが含まれます。ワークステーションに SDK CLI をインストールして、独自の Operator のオーサリングを開始することができます。
11.3.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.3.2.2. Homebrew からのインストール
Homebrew を使用して SDK CLI をインストールできます。
前提条件
手順
brew
コマンドを使用して SDK CLI をインストールします。$ brew install operator-sdk
CLI ツールが正しくインストールされていることを確認します。
$ operator-sdk version
11.3.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.3.3. Operator SDK を使用した Helm ベースの Operator のビルド
以下の手順では、Operator SDK が提供するツールおよびライブラリーを使用して Helm チャートがサポートする単純な Nginx Operator のビルドの例について説明します。
各チャートについて新規 Operator をビルドすることは最も効果的な方法と言えます。これにより、Hem ベースの Operator から移行して Go で完全装備の Operator を作成する場合などに、さらに多くのネイティブ動作をする Kubernetes API (例: oc get Nginx
) の使用および柔軟性が可能になります。
前提条件
- 開発ワークステーションにインストールされる Operator SDK CLI
-
cluster-admin
パーミッションを持つアカウントを使用した Kubernetes ベースのクラスターr v1.11.3+ (OpenShift Container Platform 4.2 など) へのアクセス -
OpenShift CLI (
oc
) v4.1+ (インストール済み)
手順
operator-sdk new
コマンドを使用して、namespace スコープまたはクラスタースコープのいずれかで 新規 Operator プロジェクトを作成します。以下のいずれかを選択します。namespace スコープ Operator (デフォルト) は単一 namespace でリソースを監視し、管理します。namespace スコープの Operator は柔軟性があるために優先して使用されます。これらの Operator は切り離されたアップグレード、障害対応およびモニタリングのための namespace の分離、および API 定義の差異化を可能にします。
新規の Helm ベース、namespace スコープの
nginx-operator
プロジェクトを作成するには、以下のコマンドを使用します。$ operator-sdk new nginx-operator \ --api-version=example.com/v1alpha1 \ --kind=Nginx \ --type=helm $ cd nginx-operator
これにより、とりわけ APIVersion
example.com/v1apha1
および KindNginx
の Nginx リソースを監視する目的でnginx-operator
プロジェクトが作成されます。クラスタースコープの Operator はクラスター全体でリソースを監視し、管理します。これは、 クラスター全体で発行される証明書を管理できるようにクラスタースコープのパーミッションでデプロイされ、監視される
cert-manager
Operator などの場合に役立ちます。nginx-operator
プロジェクトをクラスタースコープになるように作成するには、以下のコマンドを実行します。$ operator-sdk new nginx-operator \ --cluster-scoped \ --api-version=example.com/v1alpha1 \ --kind=Nginx \ --type=helm
--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 ロジックをカスタマイズします。
この例では、
nginx-operator
はそれぞれのNginx
カスタムリソース (CR) について以下の調整 (reconciliation) ロジックを実行します。- Nginx デプロイメントを作成します (ない場合)。
- Nginx サービスを作成します (ない場合)。
- Nginx Ingress を作成します (有効にされているが存在しない場合)。
- Deployment、Service、およびオプションの Ingress が Nginx CR で指定される必要な設定 (レプリカ数、イメージ、サービスタイプなど) に一致することを確認します。
デフォルトで、
nginx-operator
はwatches.yaml
ファイルに示されるようにNginx
リソースイベントを監視し、指定されたチャートを使用して Helm リリースを実行します。- version: v1alpha1 group: example.com kind: Nginx chart: /opt/helm/helm-charts/nginx
Nginx Helm チャートを確認します。
Helm Operator プロジェクトの作成時に、Operator SDK は、単純な Nginx リリース用のテンプレートセットが含まれる Helm チャートのサンプルを作成します。
この例では、Helm チャート開発者がリリースについての役立つ情報を伝えるために使用する
NOTES.txt
テンプレートと共に、Deployment、Service、および Ingress リソース用にテンプレートを利用できます。Helm チャートの使用に慣れていない場合は、Helm Chart 開発者用のドキュメントを参照してください。
Nginx CR 仕様を確認します。
Helm は値 (value) という概念を使用して、Helm チャートの
values.yaml
ファイルに定義される Helm チャートのデフォルトをカスタマイズします。CR 仕様に必要な値を設定し、これらのデフォルトを上書きします。例としてレプリカ数を使用することができます。
まず、
helm-charts/nginx/values.yaml
ファイルで、チャートにreplicaCount
という値が含まれ、これがデフォルトで1
に設定されていることを検査します。デプロイメントに 2 つの Nginx インスタンスを設定するには、CR 仕様にreplicaCount: 2
が含まれる必要があります。deploy/crds/example_v1alpha1_nginx_cr.yaml
ファイルを以下のように更新します。apiVersion: example.com/v1alpha1 kind: Nginx metadata: name: example-nginx spec: replicaCount: 2
同様に、デフォルトのサービスポートは
80
に設定されます。8080
を代わりに使用するには、サービスポートの上書きを追加してdeploy/crds/example_v1alpha1_nginx_cr.yaml
ファイルを再度更新します。apiVersion: example.com/v1alpha1 kind: Nginx metadata: name: example-nginx spec: replicaCount: 2 service: port: 8080
Helm Operator は、
helm install -f ./overrides.yaml
コマンドが機能するように、仕様全体を values ファイルの内容のように適用します。
CRD をデプロイします。
Operator の実行前に、Kubernetes は Operator が監視する新規カスタムリソース定義 (CRD) について把握している必要があります。以下の CRD をデプロイします。
$ oc create -f deploy/crds/example_v1alpha1_nginx_crd.yaml
Operator をビルドし、実行します 。
Operator をビルドし、実行する方法として 2 つの方法を使用できます。
- Kubernetes クラスター内の Pod を使用
-
operator-sdk up
コマンドを使用してクラスター外で Go プログラムを使用
以下の方法のいずれかを選択します。
Kubernetes クラスター内で Pod として実行 します。これは実稼働環境での優先される方法です。
nginx-operator
イメージをビルドし、これをレジストリーにプッシュします。$ operator-sdk build quay.io/example/nginx-operator:v0.0.1 $ docker push quay.io/example/nginx-operator:v0.0.1
Deployment マニフェストは
deploy/operator.yaml
ファイルに生成されます。このファイルの Deployment イメージは、プレースホルダーREPLACE_IMAGE
から直前にビルドされたイメージに変更される必要があります。これを実行するには、以下を実行します。$ sed -i 's|REPLACE_IMAGE|quay.io/example/nginx-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/nginx-operator:v0.0.1|g' deploy/operator.yaml $ sed -i "" "s|REPLACE_NAMESPACE|$OPERATOR_NAMESPACE|g" deploy/role_binding.yaml
nginx-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
nginx-operator
が稼働していることを確認します。$ oc get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-operator 1 1 1 1 1m
クラスター外で実行します。この方法は、デプロイメントおよびテストの速度を上げるために開発サイクル時に優先される方法です。
watches.yaml
ファイルで参照されるチャートパスがマシン上に存在している必要があります。デフォルトで、watches.yaml
ファイルはoperator-sdk build
コマンドでビルドされるOperator イメージを使用できるようにスキャフォールディングされます。Operator をoperator-sdk up local
コマンドで開発し、テストする場合、SDK はローカルファイルシステムでこのパスを検索します。この場所に、Helm チャートのパスを参照するシンボリックリンクを作成します。
$ sudo mkdir -p /opt/helm/helm-charts $ sudo ln -s $PWD/helm-charts/nginx /opt/helm/helm-charts/nginx
$HOME/.kube/config
にあるデフォルトの Kubernetes 設定ファイルを使って Operator をローカルに実行するには、以下を実行します。$ operator-sdk up local
提供された Kubernetes 設定ファイルを使って Operator をローカルに実行するには、以下を実行します。
$ operator-sdk up local --kubeconfig=<path_to_config>
Nginx
CR をデプロイします。これまでに変更した
Nginx
CR を適用します。$ oc apply -f deploy/crds/example_v1alpha1_nginx_cr.yaml
nginx-operator
が CR の Deployment を作成することを確認します。$ oc get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 2 2 2 2 1m
Pod で 2 つのレプリカが作成されていることを確認します。
$ oc get pods NAME READY STATUS RESTARTS AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1-f8f9c875d-fjcr9 1/1 Running 0 1m example-nginx-b9phnoz9spckcrua7ihrbkrt1-f8f9c875d-ljbzl 1/1 Running 0 1m
サービスポートが
8080
に設定されていることを確認します。$ oc get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 ClusterIP 10.96.26.3 <none> 8080/TCP 1m
replicaCount
を更新し、ポートを削除します。spec.replicaCount
フィールドを2
から3
に変更し、spec.service
フィールドを削除して、変更を適用します。$ cat deploy/crds/example_v1alpha1_nginx_cr.yaml apiVersion: "example.com/v1alpha1" kind: "Nginx" metadata: name: "example-nginx" spec: replicaCount: 3 $ oc apply -f deploy/crds/example_v1alpha1_nginx_cr.yaml
Operator が Deployment サイズを変更することを確認します。
$ oc get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 3 3 3 3 1m
サービスポートがデフォルトの
80
に設定されていることを確認します。$ oc get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 ClusterIP 10.96.26.3 <none> 80/TCP 1m
リソースをクリーンアップします。
$ oc delete -f deploy/crds/example_v1alpha1_nginx_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/example_v1alpha1_nginx_crd.yaml
11.3.4. 追加リソース
- Operator SDK によって作成されるプロジェクトディレクトリー構造についての詳細は、「Appendices」を参照してください。
- Operator Development Guide for Red Hat Partners