2.2. Operator Framework パッケージ形式
以下で、OpenShift Container Platform の Operator Lifecycle Manager (OLM) によってサポートされる Operator のパッケージ形式を説明します。
2.2.1. Bundle Format
Operator の Bundle Format は、Operator Framework によって導入されるパッケージ形式です。スケーラビリティーを向上させ、アップストリームユーザーがより効果的に独自のカタログをホストできるようにするために、Bundle Format 仕様は Operator メタデータのディストリビューションを単純化します。
Operator バンドルは、Operator の単一バージョンを表します。ディスク上の バンドルマニフェスト は、Kubernetes マニフェストおよび Operator メタデータを保存する実行不可能なコンテナーイメージである バンドルイメージ としてコンテナー化され、提供されます。次に、バンドルイメージの保存および配布は、podman
、docker
、および Quay などのコンテナーレジストリーを使用して管理されます。
Operator メタデータには以下を含めることができます。
- Operator を識別する情報 (名前およびバージョンなど)。
- UI を駆動する追加情報 (アイコンや一部のカスタムリソース (CR) など)。
- 必須および提供される API。
- 関連するイメージ。
マニフェストを Operator レジストリーデータベースに読み込む際に、以下の要件が検証されます。
- バンドルには、アノテーションで定義された 1 つ以上のチャネルが含まれる必要がある。
- すべてのバンドルには、1 つのクラスターサービスバージョン (CSV) がある。
- CSV がクラスターリソース定義 (CRD) を所有する場合、その CRD はバンドルに存在する必要がある。
2.2.1.1. マニフェスト
バンドルマニフェストは、Operator のデプロイメントおよび RBAC モデルを定義する Kubernetes マニフェストのセットを指します。
バンドルにはディレクトリーごとに 1 つの CSV が含まれ、通常は manifest/
ディレクトリーの CSV の所有される API を定義する CRD が含まれます。
Bundle Format のレイアウトの例
etcd ├── manifests │ ├── etcdcluster.crd.yaml │ └── etcdoperator.clusterserviceversion.yaml │ └── secret.yaml │ └── configmap.yaml └── metadata └── annotations.yaml └── dependencies.yaml
その他のサポート対象のオブジェクト
以下のオブジェクトタイプは、バンドルの /manifests
ディレクトリーにオプションとして追加することもできます。
サポート対象のオプションオブジェクトタイプ
-
ClusterRole
-
ClusterRoleBinding
-
ConfigMap
-
ConsoleCLIDownload
-
ConsoleLink
-
ConsoleQuickStart
-
ConsoleYamlSample
-
PodDisruptionBudget
-
PriorityClass
-
PrometheusRule
-
Role
-
RoleBinding
-
Secret
-
Service
-
ServiceAccount
-
ServiceMonitor
-
VerticalPodAutoscaler
これらのオプションオブジェクトがバンドルに含まれる場合、Operator Lifecycle Manager (OLM) はバンドルからこれらを作成し、CSV と共にそれらのライフサイクルを管理できます。
オプションオブジェクトのライフサイクル
- CSV が削除されると、OLM はオプションオブジェクトを削除します。
CSV がアップグレードされると、以下を実行します。
- オプションオブジェクトの名前が同じである場合、OLM はこれを更新します。
- オプションオブジェクトの名前がバージョン間で変更された場合、OLM はこれを削除し、再作成します。
2.2.1.2. アノテーション
バンドルには、その metadata/
ディレクトリーに annotations.yaml
ファイルも含まれます。このファイルは、バンドルをバンドルのインデックスに追加する方法に関する形式およびパッケージ情報の記述に役立つ高レベルの集計データを定義します。
annotations.yaml
の例
annotations: operators.operatorframework.io.bundle.mediatype.v1: "registry+v1" 1 operators.operatorframework.io.bundle.manifests.v1: "manifests/" 2 operators.operatorframework.io.bundle.metadata.v1: "metadata/" 3 operators.operatorframework.io.bundle.package.v1: "test-operator" 4 operators.operatorframework.io.bundle.channels.v1: "beta,stable" 5 operators.operatorframework.io.bundle.channel.default.v1: "stable" 6
- 1
- Operator バンドルのメディアタイプまたは形式。
registry+v1
形式の場合、これに CSV および関連付けられた Kubernetes オブジェクトが含まれることを意味します。 - 2
- Operator マニフェストが含まれるディレクトリーへのイメージのパス。このラベルは今後使用するために予約され、現時点ではデフォの
manifests/
に設定されています。manifests.v1
の値は、バンドルに Operator マニフェストが含まれることを示します。 - 3
- バンドルに関するメタデータファイルが含まれるディレクトリーへのイメージのパス。このラベルは今後使用するために予約され、現時点ではデフォの
metadata/
に設定されています。metadata.v1
の値は、このバンドルに Operator メタデータがあることを意味します。 - 4
- バンドルのパッケージ名。
- 5
- Operator レジストリーに追加される際にバンドルがサブスクライブするチャネルのリスト。
- 6
- レジストリーからインストールされる場合に Operator がサブスクライブされるデフォルトチャネル。
一致しない場合、annotations.yaml
ファイルは、これらのアノテーションに依存するクラスター上の Operator レジストリーのみがこのファイルにアクセスできるために権威を持つファイルになります。
2.2.1.3. Dependencies
Operator の依存関係は、バンドルの metadata/
フォルダー内の dependencies.yaml
ファイルに一覧表示されます。このファイルはオプションであり、現時点では明示的な Operator バージョンの依存関係を指定するためにのみ使用されます。
依存関係の一覧には、依存関係の内容を指定するために各項目の type
フィールドが含まれます。次のタイプの Operator 依存関係がサポートされています。
olm.package
-
このタイプは、特定の Operator バージョンの依存関係であることを意味します。依存関係情報には、パッケージ名とパッケージのバージョンを semver 形式で含める必要があります。たとえば、
0.5.2
などの特定バージョンや>0.5.1
などのバージョンの範囲を指定することができます。 olm.gvk
- このタイプの場合、作成者は CSV の既存の CRD および API ベースの使用方法と同様に group/version/kind (GVK) 情報で依存関係を指定できます。これは、Operator の作成者がすべての依存関係、API または明示的なバージョンを同じ場所に配置できるようにするパスです。
olm.constraint
- このタイプは、任意の Operator プロパティーに対するジェネリック制約を宣言します。
以下の例では、依存関係は Prometheus Operator および etcd CRD について指定されます。
dependencies.yaml
ファイルの例
dependencies: - type: olm.package value: packageName: prometheus version: ">0.27.0" - type: olm.gvk value: group: etcd.database.coreos.com kind: EtcdCluster version: v1beta2
2.2.1.4. opm CLI について
opm
CLI ツールは、Operator Bundle Format で使用するために Operator Framework によって提供されます。このツールを使用して、ソフトウェアリポジトリーに相当する Operator バンドルのリストから Operator のカタログを作成し、維持することができます。結果として、コンテナーイメージをコンテナーレジストリーに保存し、その後にクラスターにインストールできます。
カタログには、コンテナーイメージの実行時に提供される組み込まれた API を使用してクエリーできる、Operator マニフェストコンテンツへのポインターのデータベースが含まれます。OpenShift Container Platform では、Operator Lifecycle Manager (OLM) は、CatalogSource
オブジェクトが定義したカタログソース内のイメージ参照できます。これにより、クラスター上にインストールされた Operator への頻度の高い更新を可能にするためにイメージを一定の間隔でポーリングできます。
-
opm
CLI のインストール手順は、CLI ツール を参照してください。
2.2.2. ファイルベースのカタログ
ファイルベースのカタログは、Operator Lifecycle Manager(OLM) のカタログ形式の最新の反復になります。この形式は、プレーンテキストベース (JSON または YAML) であり、以前の SQLite データベース形式の宣言的な設定の進化であり、完全な下位互換性があります。この形式の目標は、Operator のカタログ編集、設定可能性、および拡張性を有効にすることです。
- 編集
ファイルベースのカタログを使用すると、カタログの内容を操作するユーザーは、形式を直接変更し、変更が有効であることを確認できます。この形式はプレーンテキストの JSON または YAML であるため、カタログメンテナーは、一般的に知られている、サポート対象の JSON または YAML ツール (例:
jq
CLI) を使用して、手動でカタログメタデータを簡単に操作できます。この編集機能により、以下の機能とユーザー定義の拡張が有効になります。
- 既存のバンドルの新規チャネルへのプロモート
- パッケージのデフォルトチャネルの変更
- アップグレードエッジを追加、更新、および削除するためのカスタムアルゴリズム
- コンポーザービリティー
ファイルベースのカタログは、任意のディレクトリー階層に保管され、カタログの作成が可能になります。たとえば、2 つのファイルベースのカタログディレクトリー (
catalogA
およびcatalogB
) を見てみましょう。カタログメンテナーは、新規のディレクトリーcatalogC
を作成してcatalogA
とcatalogB
をそのディレクトリーにコピーし、新しく結合カタログを作成できます。このコンポーザービリティーにより、カタログの分散化が可能になります。この形式により、Operator の作成者は Operator 固有のカタログを維持でき、メンテナーは個別の Operator カタログで構成されるカタログを簡単にビルドできます。ファイルベースのカタログは、他の複数のカタログを組み合わせたり、1 つのカタログのサブセットを抽出したり、またはこれらの両方を組み合わせたりすることで作成できます。
注記パッケージ内でパッケージおよびバンドルを重複できません。
opm validate
コマンドは、重複が見つかった場合はエラーを返します。Operator の作成者は Operator、その依存関係およびそのアップグレードの互換性について最も理解しているので、Operator 固有のカタログを独自のカタログに維持し、そのコンテンツを直接制御できます。ファイルベースのカタログの場合に、Operator の作成者はカタログでパッケージをビルドして維持するタスクを所有します。ただし、複合カタログメンテナーは、カタログ内のパッケージのキュレートおよびユーザーにカタログを公開するタスクのみを所有します。
- 拡張性
ファイルベースのカタログ仕様は、カタログの低レベル表現です。これは低レベルの形式で直接保守できますが、カタログメンテナーは、このレベルの上に任意の拡張をビルドして、独自のカスタムツールを使用して任意数の変更を加えることができます。
たとえば、ツールは
(mode=semver)
などの高レベルの API を、アップグレードエッジ用に低レベルのファイルベースのカタログ形式に変換できます。または、カタログ保守担当者は、特定の条件を満たすバンドルに新規プロパティーを追加して、すべてのバンドルメタデータをカスタマイズする必要がある場合があります。このような拡張性を使用すると、今後の OpenShift Container Platform リリース向けに、追加の正式なツールを下層の API 上で開発できますが、主な利点として、カタログメンテナーにもこの機能がある点が挙げられます。
OpenShift Container Platform 4.11 の時点で、デフォルトの Red Hat が提供する Operator カタログは、ファイルベースのカタログ形式でリリースされます。OpenShift Container Platform 4.6 から 4.10 までのデフォルトの Red Hat が提供する Operator カタログは、非推奨の SQLite データベース形式でリリースされました。
opm
サブコマンド、フラグ、および SQLite データベース形式に関連する機能も非推奨となり、今後のリリースで削除されます。機能は引き続きサポートされており、非推奨の SQLite データベース形式を使用するカタログに使用する必要があります。
opm index prune
などの SQLite データベース形式を使用する opm
サブコマンドおよびフラグの多くは、ファイルベースのカタログ形式では機能しません。ファイルベースのカタログを使用する方法の詳細は、カスタムカタログの管理 と oc-mirror プラグインを使用した非接続インストールのイメージのミラーリング を参照してください。
2.2.2.1. ディレクトリー構造
ファイルベースのカタログは、ディレクトリーベースのファイルシステムから保存してロードできます。opm
CLI は、root ディレクトリーを元に、サブディレクトリーに再帰してカタログを読み込みます。CLI は、検出されるすべてのファイルの読み込みを試行し、エラーが発生した場合には失敗します。
.gitignore
ファイルとパターンと優先順位が同じ .indexignore
ファイルを使用して、カタログ以外のファイルを無視できます。
例: .indexignore
ファイル
# Ignore everything except non-object .json and .yaml files **/* !*.json !*.yaml **/objects/*.json **/objects/*.yaml
カタログメンテナーは、必要なレイアウトを柔軟に選択できますが、各パッケージのファイルベースのカタログ Blob は別々のサブディレクトリーに保管することを推奨します。個々のファイルは JSON または YAML のいずれかをしようしてください。カタログ内のすべてのファイルが同じ形式を使用する必要はありません。
推奨される基本構造
catalog ├── packageA │ └── index.yaml ├── packageB │ ├── .indexignore │ ├── index.yaml │ └── objects │ └── packageB.v0.1.0.clusterserviceversion.yaml └── packageC └── index.json
この推奨の構造には、ディレクトリー階層内の各サブディレクトリーは自己完結型のカタログであるという特性があるので、カタログの作成、検出、およびナビゲーションなどのファイルシステムの操作が簡素化されます。このカタログは、親カタログのルートディレクトリーにコピーして親カタログに追加することもできます。
2.2.2.2. スキーマ
ファイルベースのカタログは、任意のスキーマで拡張できる CUE 言語仕様 に基づく形式を使用します。以下の _Meta
CUE スキーマは、すべてのファイルベースのカタログ Blob が順守する必要のある形式を定義します。
_Meta
スキーマ
_Meta: { // schema is required and must be a non-empty string schema: string & !="" // package is optional, but if it's defined, it must be a non-empty string package?: string & !="" // properties is optional, but if it's defined, it must be a list of 0 or more properties properties?: [... #Property] } #Property: { // type is required type: string & !="" // value is required, and it must not be null value: !=null }
この仕様にリストされている CUE スキーマは網羅されていると見なされます。opm validate
コマンドには、CUE で簡潔に記述するのが困難または不可能な追加の検証が含まれます。
Operator Lifecycle Manager(OLM) カタログは、現時点で OLM の既存のパッケージおよびバンドルの概念に対応する 3 つのスキーマ (olm.package
、olm.channel
および olm.bundle
) を使用します。
カタログの各 Operator パッケージには、olm.package
Blob が 1 つ (少なくとも olm.channel
Blob 1 つ、および 1 つ以上の olm.bundle
Blob) が必要です。
olm.*
スキーマは OLM 定義スキーマ用に予約されています。カスタムスキーマには、所有しているドメインなど、一意の接頭辞を使用する必要があります。
2.2.2.2.1. olm.package スキーマ
olm.package
スキーマは Operator のパッケージレベルのメタデータを定義します。これには、名前、説明、デフォルトのチャネル、およびアイコンが含まれます。
例2.1 olm.package
スキーマ
#Package: { schema: "olm.package" // Package name name: string & !="" // A description of the package description?: string // The package's default channel defaultChannel: string & !="" // An optional icon icon?: { base64data: string mediatype: string } }
2.2.2.2.2. olm.channel スキーマ
olm.channel
スキーマは、パッケージ内のチャネル、チャネルのメンバーであるバンドルエントリー、およびそれらのバンドルのアップグレードエッジを定義します。
バンドルは複数の olm.channel
Blob のエントリーとして含めることができますが、チャネルごとに設定できるエントリーは 1 つだけです。
このカタログまたは別のカタログで検索できない場合に、エントリーの置換値が別のバンドル名を参照することは有効です。ただし、他のすべてのチャネルの普遍条件に該当する必要があります (チャネルに複数のヘッドがない場合など)。
例2.2 olm.channel
スキーマ
#Channel: { schema: "olm.channel" package: string & !="" name: string & !="" entries: [...#ChannelEntry] } #ChannelEntry: { // name is required. It is the name of an `olm.bundle` that // is present in the channel. name: string & !="" // replaces is optional. It is the name of bundle that is replaced // by this entry. It does not have to be present in the entry list. replaces?: string & !="" // skips is optional. It is a list of bundle names that are skipped by // this entry. The skipped bundles do not have to be present in the // entry list. skips?: [...string & !=""] // skipRange is optional. It is the semver range of bundle versions // that are skipped by this entry. skipRange?: string & !="" }
skipRange
フィールドを使用すると、スキップされた Operator バージョンが更新グラフからプルーニングされるため、ユーザーは Subscription
オブジェクトの spec.startingCSV
プロパティーを使用してインストールできなくなります。
Operator バージョンを複数の以前のバージョンから直接 (1 バージョンずつ) 更新し、それらの以前のバージョンをユーザーがインストールできるようにしておく場合は、常に stopRange
フィールドと replaces
フィールドを使用してください。replaces
フィールドが当該 Operator バージョンの直前のバージョンを参照していることを確認してください。
2.2.2.2.3. olm.bundle スキーマ
例2.3 olm.bundle
スキーマ
#Bundle: { schema: "olm.bundle" package: string & !="" name: string & !="" image: string & !="" properties: [...#Property] relatedImages?: [...#RelatedImage] } #Property: { // type is required type: string & !="" // value is required, and it must not be null value: !=null } #RelatedImage: { // image is the image reference image: string & !="" // name is an optional descriptive name for an image that // helps identify its purpose in the context of the bundle name?: string & !="" }
2.2.2.3. プロパティー
プロパティーは、ファイルベースのカタログスキーマに追加できる任意のメタデータです。type
フィールドは、value
フィールドのセマンティックおよび構文上の意味を効果的に指定する文字列です。値には任意の JSON または YAML を使用できます。
OLM は、予約済みの olm.*
接頭辞をもう一度使用して、いくつかのプロパティータイプを定義します。
2.2.2.3.1. olm.package プロパティー
olm.package
プロパティーは、パッケージ名とバージョンを定義します。これはバンドルの必須プロパティーであり、これらのプロパティーが 1 つ必要です。packageName
フィールドはバンドルのファーストクラス package
フィールドと同じでなければならず、version
フィールドは有効なセマンティクスバージョンである必要があります。
例2.4 olm.package
プロパティー
#PropertyPackage: { type: "olm.package" value: { packageName: string & !="" version: string & !="" } }
2.2.2.3.2. olm.gvk プロパティー
olm.gvk
プロパティーは、このバンドルで提供される Kubernetes API の group/version/kind(GVK) を定義します。このプロパティーは、OLM が使用して、必須の API と同じ GVK をリストする他のバンドルの依存関係として、このプロパティーでバンドルを解決します。GVK は Kubernetes GVK の検証に準拠する必要があります。
例2.5 olm.gvk
プロパティー
#PropertyGVK: { type: "olm.gvk" value: { group: string & !="" version: string & !="" kind: string & !="" } }
2.2.2.3.3. olm.package.required
olm.package.required
プロパティーは、このバンドルが必要な別のパッケージのパッケージ名とバージョン範囲を定義します。バンドルにリストされている必要なパッケージプロパティーごとに、OLM は、リストされているパッケージのクラスターに必要なバージョン範囲で Operator がインストールされていることを確認します。versionRange
フィールドは有効なセマンティクスバージョン (semver) の範囲である必要があります。
例2.6 olm.package.required
プロパティー
#PropertyPackageRequired: { type: "olm.package.required" value: { packageName: string & !="" versionRange: string & !="" } }
2.2.2.3.4. olm.gvk.required
olm.gvk.required
プロパティーは、このバンドルが必要とする Kubernetes API の group/version/kind(GVK) を定義します。バンドルにリストされている必要な GVK プロパティーごとに、OLM は、提供する Operator がクラスターにインストールされていることを確認します。GVK は Kubernetes GVK の検証に準拠する必要があります。
例2.7 olm.gvk.required
プロパティー
#PropertyGVKRequired: { type: "olm.gvk.required" value: { group: string & !="" version: string & !="" kind: string & !="" } }
2.2.2.4. カタログの例
ファイルベースのカタログを使用すると、カタログメンテナーは Operator のキュレーションおよび互換性に集中できます。Operator の作成者は Operator 用に Operator 固有のカタログをすでに生成しているので、カタログメンテナーは、各 Operator カタログをカタログのルートディレクトリーのサブディレクトリーにレンダリングしてビルドできます。
ファイルベースのカタログをビルドする方法は多数あります。以下の手順は、単純なアプローチの概要を示しています。
カタログの設定ファイルを 1 つ維持し、カタログ内に Operator ごとにイメージの参照を含めます。
カタログ設定ファイルのサンプル
name: community-operators repo: quay.io/community-operators/catalog tag: latest references: - name: etcd-operator image: quay.io/etcd-operator/index@sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 - name: prometheus-operator image: quay.io/prometheus-operator/index@sha256:e258d248fda94c63753607f7c4494ee0fcbe92f1a76bfdac795c9d84101eb317
設定ファイルを解析し、その参照から新規カタログを作成するスクリプトを実行します。
スクリプトの例
name=$(yq eval '.name' catalog.yaml) mkdir "$name" yq eval '.name + "/" + .references[].name' catalog.yaml | xargs mkdir for l in $(yq e '.name as $catalog | .references[] | .image + "|" + $catalog + "/" + .name + "/index.yaml"' catalog.yaml); do image=$(echo $l | cut -d'|' -f1) file=$(echo $l | cut -d'|' -f2) opm render "$image" > "$file" done opm alpha generate dockerfile "$name" indexImage=$(yq eval '.repo + ":" + .tag' catalog.yaml) docker build -t "$indexImage" -f "$name.Dockerfile" . docker push "$indexImage"
2.2.2.5. ガイドライン
ファイルベースのカタログを維持する場合には、以下のガイドラインを考慮してください。
2.2.2.5.1. イミュータブルなバンドル
Operator Lifecycle Manager(OLM) に関する一般的なアドバイスとして、バンドルイメージとそのメタデータをイミュータブルとして処理する必要がある点があります。
破損したバンドルがカタログにプッシュされている場合には、少なくとも 1 人のユーザーがそのバンドルにアップグレードしたと想定する必要があります。この仮定に基づいて、破損したバンドルがインストールされたユーザーがアップグレードを受信できるように、破損したバンドルから、アップグレードエッジが含まれる別のバンドルをリリースする必要があります。OLM は、カタログでバンドルの内容が更新された場合に、インストールされたバンドルは再インストールされません。
ただし、カタログメタデータの変更が推奨される場合があります。
-
チャネルプロモーション: バンドルをすでにリリースし、後で別のチャネルに追加することにした場合は、バンドルのエントリーを別の
olm.channel
Blob に追加できます。 -
新規アップグレードエッジ:
1.2.z
バンドルバージョンを新たにリリースしたが (例:1.2.4
)、1.3.0
がすでにリリースされている場合は、1.2.4
をスキップするように1.3.0
のカタログメタデータを更新できます。
2.2.2.5.2. ソース制御
カタログメタデータはソースコントロールに保存され、信頼できる情報源として処理される必要があります。以下の手順で、カタログイメージを更新する必要があります。
- ソース制御されたカタログディレクトリーを新規コミットを使用して更新します。
-
カタログイメージをビルドし、プッシュします。ユーザーがカタログが利用可能になり次第更新を受信できるように、一貫性のあるタグ付け (
:latest
or:<target_cluster_version>
) を使用します。
2.2.2.6. CLI の使用
opm
CLI を使用してファイルベースのカタログを作成する方法は、カスタムカタログの管理 を参照してください。
ファイルベースのカタログの管理に関連する opm
CLI コマンドの参考情報は、CLI ツール を参照してください。
2.2.2.7. 自動化
Operator の作成者およびカタログメンテナーは、CI/CD ワークフローを使用してカタログのメンテナンスを自動化することが推奨されます。カタログメンテナーは、GitOps 自動化をビルドして以下のタスクを実行し、これをさらに向上させることができます。
- パッケージのイメージ参照の更新など、プル要求 (PR) の作成者が要求された変更を実行できることを確認します。
-
カタログの更新で
opm validate
コマンドが指定されていることを確認します。 - 更新されたバンドルまたはカタログイメージの参照が存在し、カタログイメージがクラスターで正常に実行され、そのパッケージの Operator が正常にインストールされることを確認します。
- 以前のチェックに合格した PR を自動的にマージします。
- カタログイメージを自動的にもう一度ビルドして公開します。
2.2.3. RukPak (テクノロジープレビュー)
RukPak はテクノロジープレビュー機能です。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。
Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。
OpenShift Container Platform 4.12 では、プラットフォーム Operator タイプがテクノロジープレビュー機能として導入されています。プラットフォーム Operator メカニズムは、同じく OpenShift Container Platform 4.12 で導入された RukPak コンポーネントと、コンテンツを管理するためのそのリソースに依存しています。
RukPak は、プロビジョナー と呼ばれる一連のコントローラーで設定され、Kubernetes クラスターにコンテンツをインストールして管理します。RukPak は、Bundle
と BundleDeployment
という 2 つの主要な API も提供します。これらのコンポーネントが連携してコンテンツをクラスターに取り込み、インストールして、クラスター内にリソースを生成します。
プロビジョナーは、プロビジョナーを明示的に参照する Bundle
リソースと BundleDeployment
リソースの両方にウォッチを配置します。特定のバンドルについて、プロビジョナーは Bundle
リソースのコンテンツをクラスターにアンパックします。次に、そのバンドルを参照する BundleDeployment
リソースを指定すると、プロビジョナーはバンドルのコンテンツをインストールし、それらのリソースのライフサイクルを管理します。
2 つのプロビジョナーが現在実装され、RukPak にバンドルされています。これらは、plain+v0
バンドルをソースおよびアンパックする プレーンプロビジョナー と、Operator Lifecycle Manager (OLM) registry+v1
バンドルをソースおよびアンパックする レジストリープロビジョナー です。
2.2.3.1. バンドル
RukPak Bundle
オブジェクトは、クラスター内の他のコンシューマーが利用できるようにするコンテンツを表します。Pod が使用を開始するためにコンテナーイメージのコンテンツをプルしてアンパックする必要があるのと同じように、Bundle
オブジェクトは、プルしてアンパックする必要がある可能性があるコンテンツを参照するために使用されます。この意味で、バンドルはイメージの概念を一般化したものであり、あらゆるタイプのコンテンツを表すために使用できます。
バンドルは単独では何もできません。プロビジョナーがアンパックしてコンテンツをクラスターで利用できるようにする必要があります。これらは、プロビジョナー Pod にマウントされたディレクトリー内の tar.gz
ファイルなど、任意のストレージメディアに解凍できます。各 Bundle
オブジェクトには、その特定のバンドルタイプを監視およびアンパックする Provisioner
オブジェクトを示す、関連付けられた spec.provisionerClassName
フィールドがあります。
プレーンプロビジョナーと連携するように設定された Bundle
オブジェクトの例
apiVersion: core.rukpak.io/v1alpha1 kind: Bundle metadata: name: my-bundle spec: source: type: image image: ref: my-bundle@sha256:xyz123 provisionerClassName: core-rukpak-io-plain
バンドルは、作成後は不変と見なされます。
2.2.3.1.1. バンドルの不変性
Bundle
オブジェクトが API サーバーによって受け入れられると、そのバンドルは RukPak システムの残りの部分によって不変のアーティファクトと見なされます。この動作により、バンドルはクラスターにソーシングする一意の静的なコンテンツを表すという概念が適用されます。ユーザーは、特定のバンドルが特定の一連のマニフェストを指していて、新しいバンドルを作成しないと更新できないという確信を持つことができます。このプロパティーは、スタンドアロンバンドルと、組み込みの BundleTemplate
オブジェクトによって作成された動的バンドルの両方に当てはまります。
バンドルの不変性は、コア RukPak Webhook によって適用されます。この Webhook は Bundle
オブジェクトイベントを監視し、バンドルの更新について、既存のバンドルの spec
フィールドが提案された更新されたバンドルのそれと意味的に等しいかどうかをチェックします。それらが等しくない場合、更新は Webhook によって拒否されます。metadata
や status
などの他の Bundle
オブジェクトフィールドは、バンドルのライフサイクル中に更新されます。不変と見なされるのは spec
フィールドのみです。
Bundle
オブジェクトを適用してからその仕様を更新しようとすると失敗するはずです。たとえば、次の例はバンドルを作成します。
$ oc apply -f -<<EOF apiVersion: core.rukpak.io/v1alpha1 kind: Bundle metadata: name: combo-tag-ref spec: source: type: git git: ref: tag: v0.0.2 repository: https://github.com/operator-framework/combo provisionerClassName: core-rukpak-io-plain EOF
出力例
bundle.core.rukpak.io/combo-tag-ref created
次に、新しいタグを指すようにバンドルにパッチを適用すると、エラーが返されます。
$ oc patch bundle combo-tag-ref --type='merge' -p '{"spec":{"source":{"git":{"ref":{"tag":"v0.0.3"}}}}}'
出力例
Error from server (bundle.spec is immutable): admission webhook "vbundles.core.rukpak.io" denied the request: bundle.spec is immutable
コアの RukPak 受付 Webhook は、バンドルの仕様が不変であるため、パッチを拒否しました。バンドルのコンテンツを変更するための推奨される方法は、インプレースで更新するのではなく、新しい Bundle
オブジェクトを作成することです。
不変性に関するその他の考慮事項
Bundle
オブジェクトの spec
フィールドは不変ですが、基本となる spec
フィールドを変更せずに、BundleDeployment
オブジェクトを新しいバージョンのバンドルコンテンツにピボットすることは可能です。この意図しないピボットは、次のシナリオで発生する可能性があります。
-
ユーザーは、イメージタグ、Git ブランチ、または Git タグを
Bundle
オブジェクトのspec.source
フィールドに設定します。 - イメージタグが新しいダイジェストに移動するか、ユーザーが変更を Git ブランチにプッシュするか、ユーザーが別のコミットで Git タグを削除して再プッシュします。
- ユーザーが、アンパック Pod の削除など、バンドルアンパック Pod を再作成するために何らかの操作を行います。
このシナリオが発生した場合、手順 2 の新しいコンテンツは、手順 3 の結果としてアンパックされます。バンドルのデプロイメントにより、変更が検出され、新しいバージョンのコンテンツにピボットされます。
これは、Pod のコンテナーイメージの 1 つがタグを使用し、そのタグが別のダイジェストに移動され、将来のある時点で既存の Pod が別のノードで再スケジュールされる Pod の動作に似ています。その時点で、ノードは新しいダイジェストで新しいイメージをプルし、ユーザーが明示的に要求することなく別の何かを実行します。
基になる Bundle
仕様コンテンツが変更されないことを確信するには、バンドルを作成するときにダイジェストベースのイメージまたは Git コミット参照を使用します。
2.2.3.1.2. プレーンバンドル仕様
RukPak のプレーンバンドルは、特定のディレクトリーにある静的で任意の Kubernetes YAML マニフェストのコレクションです。
現在実装されているプレーンバンドル形式は、plain+v0
形式です。バンドル形式の名前 plain+v0
は、バンドルのタイプ (plain
) と現在のスキーマバージョン (v0
) を組み合わせたものです。
plain+v0
バンドル形式はスキーマバージョン v0
です。これは、変更される可能性がある実験的な形式であることを意味します。
たとえば、以下は、plain+v0
バンドルのファイルツリーを示しています。アプリケーションのデプロイに必要な Kubernetes リソースを含む manifests/
ディレクトリーが必要です。
plain+v0
バンドルファイルツリーの例
manifests ├── namespace.yaml ├── cluster_role.yaml ├── role.yaml ├── serviceaccount.yaml ├── cluster_role_binding.yaml ├── role_binding.yaml └── deployment.yaml
静的マニフェストは、プロビジョナーがアンパックできる有効な plain+v0
バンドルになるように、少なくとも 1 つのリソースを含む manifests/
ディレクトリーに配置する必要があります。manifests/
ディレクトリーもフラットである必要があります。すべてのマニフェストは、サブディレクトリーのない最上位にある必要があります。
静的なマニフェストではないプレーンバンドルの manifests/
ディレクトリーにコンテンツを含めないでください。そうしないと、そのバンドルからクラスター上でコンテンツを作成するときにエラーが発生します。oc apply
コマンドで正常に適用されないファイルは、エラーになります。マルチオブジェクト YAML または JSON ファイルも有効です。
2.2.3.1.3. レジストリーバンドルの仕様
レジストリーバンドル、または registry+v1
バンドルには、従来の Operator Lifecycle Manager (OLM) バンドル形式で編成された一連の静的 Kubernetes YAML マニフェストが含まれています。
関連情報
2.2.3.2. BundleDeployment
BundleDeployment
オブジェクトは、オブジェクトのインストールと削除によって Kubernetes クラスターの状態を変更します。インストールされるコンテンツを検証して信頼し、RBAC を使用して BundleDeployment
API へのアクセスを、それらのアクセス許可を必要とするユーザーのみに制限することが重要です。
RukPak BundleDeployment
API は Bundle
オブジェクトを指し、それがアクティブであることを示します。これには、アクティブなバンドルの古いバージョンからのピボットが含まれます。BundleDeployment
オブジェクトには、目的のバンドルの組み込み仕様も含まれる場合があります。
Pod がコンテナーイメージのインスタンスを生成するのと同じように、バンドルのデプロイではデプロイされたバージョンのバンドルが生成されます。バンドルのデプロイは、Pod の概念の一般化と見なすことができます。
バンドルのデプロイが参照されたバンドルに基づいてクラスターに変更を加える方法の詳細は、そのバンドルのデプロイを監視するように設定されているプロビジョナーによって定義されます。
プレーンプロビジョナーと連携するように設定された BundleDeployment
オブジェクトの例
apiVersion: core.rukpak.io/v1alpha1 kind: BundleDeployment metadata: name: my-bundle-deployment spec: provisionerClassName: core-rukpak-io-plain template: metadata: labels: app: my-bundle spec: source: type: image image: ref: my-bundle@sha256:xyz123 provisionerClassName: core-rukpak-io-plain
2.2.3.3. プロビジョナー
RukPak プロビジョナーは、BundleDeployment
および Bundle
API を理解し、アクションを実行できるコントローラーです。各プロビジョナーには一意の ID が割り当てられ、特定の ID に一致する spec.provisionerClassName
フィールドを使用して Bundle
および BundleDeployment
オブジェクトを調整します。
たとえば、プレーンプロビジョナーは、指定された plain+v0
バンドルをクラスターにアンパックしてからインスタンス化し、バンドルのコンテンツをクラスターで利用できるようにすることができます。