はじめに
この記事では、Flux v2.7で追加されたImageUpdateAutomationのGitSparseCheckoutオプションについて解説します。
Fluxは、CNCFの卒業プロジェクトであり、Kubernetes上でGitOpsを実現するためのツールキットです。Flux v2.7.0は2025年9月にリリースされ、Image Automation ControllersのAPIがGA(一般提供)となった重要なリリースです。
GitSparseCheckoutオプションは筆者がコントリビュートして追加したオプションです。この記事では、機能の概要から実装の背景、そして開発中に直面した課題について紹介します。
ImageUpdateAutomationとは
ImageUpdateAutomationは、FluxのImage Automation Controllersの一部であり、コンテナイメージの更新を自動化するためのコンポーネントです。Flux v2.7.0でImageUpdateAutomation APIは安定版v1に昇格しました。
Image Automation Controllersは以下の2つのコンポーネントで構成されています。
- Image Reflector Controller: コンテナレジストリをスキャンし、イメージのメタデータをKubernetesリソースに反映
- Image Automation Controller: スキャンされた最新イメージに基づいてGitリポジトリ内のYAMLファイルを自動更新し、変更をコミット
ImageUpdateAutomationリソースは、Image Automation Controllerがどのようにマニフェストを更新するかを定義します。具体的には、対象のGitリポジトリ、更新対象のパス、コミットメッセージのテンプレートなどを指定できます。
GitSparseCheckoutオプションとは
概要
GitSparseCheckoutは、ImageUpdateAutomationがGitリポジトリをクローンする際に、sparse checkoutを使用して必要なファイルのみをチェックアウトする機能です。
この機能を有効化すると、.spec.update.pathで指定されたディレクトリのみがチェックアウトされます。大規模なモノレポを使用している場合、リポジトリ全体をクローンする必要がなくなるため、パフォーマンスとリソース使用量の改善が期待できます。
有効化方法
この機能を有効化するには、image-automation-controllerの起動時に以下のフラグを指定します。
--feature-gates=GitSparseCheckout=true
効果
- パフォーマンス向上: 大規模リポジトリから必要なディレクトリのみを取得
- リソース使用量削減: ディスク容量とネットワーク帯域の節約
- 処理時間短縮: クローンとチェックアウトの時間が短縮
実装仕様
Feature Gateによる制御
GitSparseCheckoutはFeature Gateとして実装されており、デフォルトでは無効です。これは、sparse checkoutがGitプロトコルの仕様やgo-gitライブラリの対応状況に依存するexperimentalな機能であるためです。
段階的な導入を可能にすることで、既存のユーザーへの影響を最小限に抑えています。
パス処理
実装では以下のパス処理が行われます。
-
filepath.Clean()を使用してパスを正規化 - リポジトリルート(
.)の場合はsparse checkoutをスキップ -
./プレフィックスは自動的に削除(後述するgo-gitのバグ対応)
なぜoperatorの起動オプションとして実装されたのか
同様のsparse checkout機能は、source-controllerのGitRepositoryリソースでも実装されています。GitRepositoryでは.spec.sparseCheckoutとしてリソースのフィールドに定義されています。
一方、ImageUpdateAutomationではoperatorの起動オプション(Feature Gate)として実装されています。この違いには理由があります。
ImageUpdateAutomationには既に.spec.update.pathフィールドが存在しており、更新対象のパスを指定できます。sparse checkoutの対象ディレクトリは、この既存のパスと同じになります。つまり、sparse checkoutを有効にするかどうかの選択だけが必要であり、新たにディレクトリを指定するフィールドを追加する必要がありません。
また、sparse checkoutはexperimentalな機能であり、Feature Gateとして実装することで、機能の安定性が確認されるまでオプトイン方式で提供できます。
開発の経緯
pkgリポジトリへの先行コントリビュート
ImageUpdateAutomationでsparse checkoutを使用するためには、まずFluxプロジェクトで共通的に使用されるfluxcd/pkgリポジトリに機能を追加する必要がありました。
PR #850で、fluxcd/pkgリポジトリのgogitパッケージにsparse checkout機能を追加しました。この実装はgo-gitライブラリのsparse-checkoutの例を参考にしています。
go-gitのバグの発見
pkgリポジトリへのコントリビュート時のテストで、go-gitにバグがあることが判明しました。
具体的には、sparse checkoutを行ったブランチから別のブランチに切り替える際に、worktree contains unstaged changesというエラーが発生する問題です。これはgo-gitのworktree.Status()がsparse checkoutを考慮していないことが原因でした。
この問題により、sparse checkout後にブランチを切り替える操作が正常に動作しませんでした。
バグ修正の待機とバックポート
go-gitのバグ修正がリリースされるのを待つ必要がありました。修正が含まれたgo-git v5.16.1およびv5.16.2がリリースされた後、PR #939でfluxcd/pkgのgo-gitバージョンを更新しました。
これにより、ようやくImageUpdateAutomationへの機能追加PR #920をマージできる状態になりました。
まとめ
Flux v2.7で追加されたGitSparseCheckoutオプションは、大規模リポジトリを扱う際のパフォーマンス改善に役立つ機能です。
この機能の実装には、以下のステップが必要でした。
- fluxcd/pkgへのsparse checkout機能の追加
- go-gitのバグ発見と修正待ち
- go-gitの修正バージョンのバックポート
- image-automation-controllerへの機能追加
OSSへのコントリビュートは、上流のライブラリの問題に直面することも多く、時間がかかることもあります。しかし、コミュニティと協力しながら問題を解決していくプロセスは非常に有意義な経験でした。