2.2. Operator Framework パッケージ形式
以下で、OpenShift Container Platform の Operator Lifecycle Manager (OLM) によってサポートされる Operator のパッケージ形式について説明します。
Operator のレガシー パッケージマニフェスト形式 のサポートは、OpenShift Container Platform 4.8 以降で削除されます。パッケージマニフェスト形式の既存 Operator プロジェクトは、Operator SDK の pkgman-to-bundle コマンドを使用してバンドル形式に移行できます。詳細は、パッケージマニフェストプロジェクトのバンドル形式への移行 を参照してください。
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 -
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"
operators.operatorframework.io.bundle.manifests.v1: "manifests/"
operators.operatorframework.io.bundle.metadata.v1: "metadata/"
operators.operatorframework.io.bundle.package.v1: "test-operator"
operators.operatorframework.io.bundle.channels.v1: "beta,stable"
operators.operatorframework.io.bundle.channel.default.v1: "stable"
- 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. 依存関係ファイル リンクのコピーリンクがクリップボードにコピーされました!
Operator の依存関係は、バンドルの metadata/ フォルダー内の dependencies.yaml ファイルに一覧表示されます。このファイルはオプションであり、現時点では明示的な Operator バージョンの依存関係を指定するためにのみ使用されます。
依存関係の一覧には、依存関係の内容を指定するために各項目の type フィールドが含まれます。Operator の依存関係には、サポートされる 2 つのタイプがあります。
-
olm.package: このタイプは、特定の Operator バージョンの依存関係であることを意味します。依存関係情報には、パッケージ名とパッケージのバージョンを semver 形式で含める必要があります。たとえば、0.5.2などの特定バージョンや>0.5.1などのバージョンの範囲を指定することができます。 -
olm.gvk:gvkタイプの場合、作成者は CSV の既存の CRD および API ベースの使用方法と同様に group/version/kind (GVK) 情報で依存関係を指定できます。これは、Operator の作成者がすべての依存関係、API または明示的なバージョンを同じ場所に配置できるようにするパスです。
以下の例では、依存関係は 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 への頻度の高い更新を可能にするためにイメージを一定の間隔でポーリングできます。
-
opmCLI のインストール手順については、CLI ツール を参照してください。
2.2.2. ファイルベースのカタログ リンクのコピーリンクがクリップボードにコピーされました!
ファイルベースのカタログは、Operator Lifecycle Manager(OLM) のカタログ形式の最新の反復になります。この形式は、プレーンテキストベース (JSON または YAML) であり、以前の SQLite データベース形式の宣言的な設定の進化であり、完全な下位互換性があります。この形式の目標は、Operator のカタログ編集、設定可能性、および拡張性を有効にすることです。
OpenShift Container Platform 4.6 以降のデフォルトの Red Hat が提供する Operator カタログは、現時点では引き続き SQLite データベース形式で提供されています。
- 編集
ファイルベースのカタログを使用すると、カタログの内容を操作するユーザーは、形式を直接変更し、変更が有効であることを確認できます。この形式はプレーンテキストの JSON または YAML であるため、カタログメンテナーは、一般的に知られている、サポート対象の JSON または YAML ツール (例:
jqCLI) を使用して、手動でカタログメタデータを簡単に操作できます。この編集機能により、以下の機能とユーザー定義の拡張が有効になります。
- 既存のバンドルの新規チャネルへのプロモート
- パッケージのデフォルトチャネルの変更
- アップグレードエッジを追加、更新、および削除するためのカスタムアルゴリズム
- コンポーザービリティー
ファイルベースのカタログは、任意のディレクトリー階層に保管され、カタログの作成が可能になります。たとえば、2 つのファイルベースのカタログディレクトリー (
catalogAおよびcatalogB) について見てみましょう。カタログメンテナーは、新規のディレクトリーcatalogCを作成してcatalogAとcatalogBをそのディレクトリーにコピーし、新しく結合カタログを作成できます。このコンポーザービリティーにより、カタログの分散化が可能になります。この形式により、Operator の作成者は Operator 固有のカタログを維持でき、保守担当者は個別の Operator カタログで設定されるカタログを簡単にビルドできます。ファイルベースのカタログは、他の複数のカタログを組み合わせたり、1 つのカタログのサブセットを抽出したり、またはこれらの両方を組み合わせたりすることで作成できます。
注記パッケージ内でパッケージおよびバンドルを重複できません。
opm validateコマンドは、重複が見つかった場合はエラーを返します。Operator の作成者は Operator、その依存関係およびそのアップグレードの互換性について最も理解しているので、Operator 固有のカタログを独自のカタログに維持し、そのコンテンツを直接制御できます。ファイルベースのカタログの場合に、Operator の作成者はカタログでパッケージをビルドして維持するタスクを所有します。ただし、複合カタログメンテナーは、カタログ内のパッケージのキュレートおよびユーザーにカタログを公開するタスクのみを所有します。
- 拡張性
ファイルベースのカタログ仕様は、カタログの低レベル表現です。これは低レベルの形式で直接保守できますが、カタログメンテナーは、このレベルの上に任意の拡張をビルドして、独自のカスタムツールを使用して任意数の変更を加えることができます。
たとえば、ツールは
(mode=semver)などの高レベルの API を、アップグレードエッジ用に低レベルのファイルベースのカタログ形式に変換できます。または、カタログ保守担当者は、特定の条件を満たすバンドルに新規プロパティーを追加して、すべてのバンドルメタデータをカスタマイズする必要がある場合があります。このような拡張性を使用すると、今後の OpenShift Container Platform リリース向けに、追加の正式なツールを下層の API 上で開発できますが、主な利点として、カタログメンテナーにもこの機能がある点が挙げられます。
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 & !=""
}
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.channelBlob に追加できます。 -
新規アップグレードエッジ:
1.2.zバンドルバージョンを新たにリリースしたが (例:1.2.4)、1.3.0がすでにリリースされている場合は、1.2.4をスキップするように1.3.0のカタログメタデータを更新できます。
2.2.2.5.2. ソース制御 リンクのコピーリンクがクリップボードにコピーされました!
カタログメタデータはソースコントロールに保存され、信頼できる情報源として処理される必要があります。以下の手順で、カタログイメージを更新する必要があります。
- ソース制御されたカタログディレクトリーを新規コミットを使用して更新します。
-
カタログイメージをビルドし、プッシュします。ユーザーがカタログが利用可能になり次第更新を受信できるように、一貫性のあるタグ付け (
:latestor:<target_cluster_version>) を使用します。
2.2.2.6. CLI の使用 リンクのコピーリンクがクリップボードにコピーされました!
opm CLI を使用して、ファイルベースのカタログを作成する方法については、Managing custom catalogs を参照してください。
ファイルベースのカタログの管理に関連する opm CLI コマンドの参考情報は、CLI ツール を参照してください。
2.2.2.7. 自動化 リンクのコピーリンクがクリップボードにコピーされました!
Operator の作成者およびカタログメンテナーは、CI/CD ワークフローを使用してカタログのメンテナンスを自動化することが推奨されます。カタログメンテナーは、GitOps 自動化をビルドして以下のタスクを実行し、これをさらに向上させることができます。
- パッケージのイメージ参照の更新など、プル要求 (PR) の作成者が要求された変更を実行できることを確認します。
-
カタログの更新で
opm validateコマンドが指定されていることを確認します。 - 更新されたバンドルまたはカタログイメージの参照が存在し、カタログイメージがクラスターで正常に実行され、そのパッケージの Operator が正常にインストールされることを確認します。
- 以前のチェックに合格した bmcs を自動的にマージします。
- カタログイメージを自動的にもう一度ビルドして公開します。