OpenShift Advent Calendar 2025 19日目の記事です。
前日に引き続き、志田が担当させていただきます。よろしくお願いします。
はじめに
昨日の記事では OpenShift で使用するコンテナレジストリについて触れましたが、今回はそのレジストリに対してコンテナイメージをミラーリングする際に使用される oc-mirror v2 について書いていきたいと思います。
特に、エアギャップ(非インターネット接続)環境における oc-mirror v2 の重要なユースケースとして、ミラーするオペレータイメージのバージョンを固定する方法をご紹介します。
なぜオペレーターのバージョン固定が必要なのか?
通常、インターネット接続環境では Operator Lifecycle Manager (OLM) がカタログ内の最新更新を自動検知します。しかし、ミラーするオペレーターのバージョンを明示的に固定しないと、以下のような課題が発生します。
- 予期せぬアップデート: チャンネル指定のみの場合、ミラーリングのたびに「最新バージョン」が取得されます。検証前のバージョンが本番レジストリに入り、意図せず適用されるリスクがあります。
- ストレージの圧迫: 全バージョンをミラーリングし続けると、レジストリの容量を激しく消費します。
- 再現性の欠如: 実行タイミングによって取得バージョンが異なるため、環境間の構成管理が困難になります。
しかし、通常の oc-mirror v2 では minVersion の指定はできても maxVersion の指定(範囲の絞り込み)は、カタログの更新グラフを分断してしまう可能性があるため、慎重に行う必要があります [1]。
Red Hat 公式の KCS(7112219) では、この問題を回避しつつ確実にバージョンを固定するためのベストプラクティスが紹介されています。本記事ではこの KCS の手法をベースとした手順をご紹介します。
[1]
minVersionとmaxVersionで範囲を絞ると、「複数のチャンネルヘッド(終点)が存在する」というエラー(multiple channel heads error)が発生することがあります。これは既知の問題として OpenShiftドキュメント でも言及されています。
オペレーターのバージョンを固定する手順
以下のエアギャップ構成を想定して手順を進めます。

準備:ツールのインストール
- oc および oc-mirror v2 plugin: Red Hat Hybrid Cloud Console から取得。
- opm: OpenShift mirror site から取得。
- podman: イメージビルドに使用。
① カタログインデックスイメージのビルド
Red Hat 標準カタログは全データが含まれ肥大化しているため、必要なオペレーターのみを抽出した 「カスタム・カタログインデックス」 を自作し、ミラーリングのソースにします。
- ミラーしたいオペレーターとバージョンを定義した
imageset-config.yamlを用意します。
kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v2alpha1 mirror: operators: - catalog: registry.redhat.io/redhat/community-operator-index:v4.20 packages: - name: grafana-operator defaultChannel: v5 channels: - name: v5 minVersion: '5.14.0' maxVersion: '5.14.0'
- フィルタリングされたカタログ定義を抽出します。
mkdir $HOME/mirror-work-dir oc-mirror --v2 -c imageset-config.yaml --dry-run file://$HOME/mirror-work-dir
- 抽出されたファイルからカタログインデックスイメージをbuildするためのdockerfileを作成します。
export VERSION=v4.20 # 実際のパスを確認して設定 export CATALOGDIR=$(find $HOME/mirror-work-dir/working-dir/operator-catalogs -name "filtered-catalogs" | head -n 1)/$(ls $(find $HOME/mirror-work-dir/working-dir/operator-catalogs -name "filtered-catalogs" | head -n 1)) opm render $CATALOGDIR/catalog-config -o json > $CATALOGDIR/fbc.json opm alpha convert-template basic $CATALOGDIR/fbc.json > $CATALOGDIR/community-operator-index-basic-template.json mkdir -p $CATALOGDIR/expanded-catalog opm alpha render-template basic $CATALOGDIR/community-operator-index-basic-template.json > $CATALOGDIR/expanded-catalog/catalog.json mkdir -p $CATALOGDIR/migrated-catalog opm migrate $CATALOGDIR/expanded-catalog $CATALOGDIR/migrated-catalog cd $CATALOGDIR opm generate dockerfile migrated-catalog -i registry.redhat.io/openshift4/ose-operator-registry-rhel9:$VERSION
- カタログインデックスイメージをビルドして外部レジストリに push します。
※
oc-mirrorは実行時にソースとなるカタログをレジストリから pull する仕様のため、一度 push が必要です。
podman build -f migrated-catalog.Dockerfile -t quay.external/redhat/community-operator-index:$VERSION-filtered . podman push quay.external/redhat/community-operator-index:$VERSION-filtered
② カスタムカタログを使ったイメージのミラーリング (Mirror to Disk)
imageset-config.yamlのcatalogを、作成したカスタムイメージに書き換えます。
# imageset-config.yaml (抜粋) mirror: operators: - catalog: quay.external/redhat/community-operator-index:v4.20-filtered packages: - name: grafana-operator # ... 以下略
- イメージをローカルに tar アーカイブとして保存します。(Mirror to Disk)
oc-mirror --v2 -c imageset-config.yaml file://mirror_images
- 完了後、
mirror_images/mirror_000001.tarをインターナル環境へ転送します。同時に、ビルドしたカスタムカタログインデックスイメージもpodman save等で抽出し、インターナル環境の内部レジストリに push しておきます。
③ インターナルレジストリへのミラーリング (Disk to Mirror)
imageset-config.yamlのcatalogを内部レジストリのパスに書き換えます。
# imageset-config.yaml (抜粋) mirror: operators: - catalog: quay.internal/redhat/community-operator-index:v4.20-filtered # ... 以下略
- 以下のようにカレントディレクトリに、 imageset-config.yaml とオペレータイメージが格納された mirror_images/mirror_000001.tar があることを確認します。
imageset-config.yaml mirror_images/mirror_000001.tar
- 内部レジストリへ push を実行します。(Disk to Mirror)
oc-mirror --v2 -c imageset-config.yaml --from file://mirror_images docker://quay.internal/mirror # push先レジストリのプロジェクトやネームスペースは環境に合わせて変更してください。
ミラーが完了すると、ImageDigestMirrorSet(IDMS)とImageTagMirrorSetg(ITMS)などのOpenShiftリソースのマニフェストが生成されるので適用します。これらのマニフェストは、OpenShiftからミラーしたカタログを使用するために必要となりますので毎回適用してください。
注意)マニフェストを適用するとOpenShiftノードのローリングアップデートが開始されますのでご注意ください。
cd mirror_images/working-dir/cluster-resources/ oc apply -f idms-oc-mirror.yaml oc apply -f itms-oc-mirror.yaml oc apply -f cs-redhat-operator-index-v4-20-filter.yaml oc apply -f cc-redhat-operator-index-v4-20-filter.yaml oc apply -f cs-community-operator-index-v4-20-filter.yaml oc apply -f cc-community-operator-index-v4-20-filter.yaml
これで、エアギャップ環境におけるオペレータバージョンを固定したコンテナイメージのミラーリングが完了です。
まとめ
エアギャップ環境での運用は「変化をコントロールすること」が重要です。oc-mirror v2 と opm を組み合わせたカスタムカタログ手法を活用して、「検証済みのバージョンだけを現場に持ち込む」フローが確立できます。
これにより、レジストリのストレージ節約とインフラの安定稼働を同時に実現できます。
oc-mirror v2 は 2024 年に GA となった比較的新しいツールであり、現在も活発に改善が行われています。将来的にはよりシンプルな手順でバージョン固定ができるようになることを期待しつつ、現時点ではこの「カタログ自作」が最も確実なベストプラクティスと言えます。