OpenShift エアギャップ環境におけるオペレーターバージョン固定のベストプラクティス(oc-mirror v2 編)

OpenShift Advent Calendar 2025 19日目の記事です。

前日に引き続き、志田が担当させていただきます。よろしくお願いします。

qiita.com

はじめに

昨日の記事では OpenShift で使用するコンテナレジストリについて触れましたが、今回はそのレジストリに対してコンテナイメージをミラーリングする際に使用される oc-mirror v2 について書いていきたいと思います。

特に、エアギャップ(非インターネット接続)環境における oc-mirror v2 の重要なユースケースとして、ミラーするオペレータイメージのバージョンを固定する方法をご紹介します。

なぜオペレーターのバージョン固定が必要なのか?

通常、インターネット接続環境では Operator Lifecycle Manager (OLM) がカタログ内の最新更新を自動検知します。しかし、ミラーするオペレーターのバージョンを明示的に固定しないと、以下のような課題が発生します。

  1. 予期せぬアップデート: チャンネル指定のみの場合、ミラーリングのたびに「最新バージョン」が取得されます。検証前のバージョンが本番レジストリに入り、意図せず適用されるリスクがあります。
  2. ストレージの圧迫: 全バージョンをミラーリングし続けると、レジストリの容量を激しく消費します。
  3. 再現性の欠如: 実行タイミングによって取得バージョンが異なるため、環境間の構成管理が困難になります。

しかし、通常の oc-mirror v2 では minVersion の指定はできても maxVersion の指定(範囲の絞り込み)は、カタログの更新グラフを分断してしまう可能性があるため、慎重に行う必要があります [1]。

Red Hat 公式の KCS(7112219) では、この問題を回避しつつ確実にバージョンを固定するためのベストプラクティスが紹介されています。本記事ではこの KCS の手法をベースとした手順をご紹介します。

[1] minVersionmaxVersion で範囲を絞ると、「複数のチャンネルヘッド(終点)が存在する」というエラー(multiple channel heads error)が発生することがあります。これは既知の問題として OpenShiftドキュメント でも言及されています。


オペレーターのバージョンを固定する手順

以下のエアギャップ構成を想定して手順を進めます。

準備:ツールのインストール

① カタログインデックスイメージのビルド

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.yamlcatalog を、作成したカスタムイメージに書き換えます。
# 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.yamlcatalog を内部レジストリのパスに書き換えます。
# 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 v2opm を組み合わせたカスタムカタログ手法を活用して、「検証済みのバージョンだけを現場に持ち込む」フローが確立できます。

これにより、レジストリのストレージ節約とインフラの安定稼働を同時に実現できます。

oc-mirror v2 は 2024 年に GA となった比較的新しいツールであり、現在も活発に改善が行われています。将来的にはよりシンプルな手順でバージョン固定ができるようになることを期待しつつ、現時点ではこの「カタログ自作」が最も確実なベストプラクティスと言えます。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。