コンテナイメージのタグ管理設計 — latest運用からの脱却判断

コンテナイメージのタグ管理で「latest運用」を続けるチームは、本番環境のロールバックが不可能な状態に陥るリスクを常に抱えています。セマンティックバージョン・コミットSHA・CalVerのどれを選ぶかは好みの問題ではなく、デプロイ頻度・チーム規模・サービス継続要件に基づく設計判断です。本記事では、latest依存を脱却するためのタグ戦略の選定基準と、レジストリ・CI・削除ポリシーを一貫した設計として組み立てる判断軸を解説します。

latestタグを本番で使い続けることの具体的リスク

ロールバック不能とデプロイ時の非決定性

latestタグはコンテナレジストリ上で常に上書きされる運用が前提となっており、同一タグで参照しても取得されるイメージが変わる可能性があります。KubernetesがimagePullPolicy: Alwaysの設定でデプロイを実行した場合、ノードごとに異なるタイミングでプルが走れば、同一Deployment内に異なるバージョンのコンテナが混在するケースが生じます。これをデプロイ時に検知するには各ノードのdaemonsetログを手動で照合する必要があり、10台以上のノード構成ではその確認作業だけで無視できない工数がかかります。

さらに問題なのは、latestが指すイメージは「今この瞬間のものであり、昨日のものではない」という非決定性です。ロールバック操作を実施しても、latestタグが別のイメージを指していれば前回デプロイ時のアーティファクトに戻れません。障害発生時に「前のバージョンに戻す」という最も基本的な復旧操作が機能しない状態は、本番運用として致命的な設計上の欠陥です。

セキュリティスキャンの空振りリスク

多くのレジストリやCI/CDツールはイメージのダイジェスト(SHA256)単位でスキャン結果をキャッシュします。latestタグが上書きされた場合、タグ名の変化がないためスキャンがスキップされるケースが生じます。一般的には、タグを上書きするたびにフルスキャンが再実行されない設定がデフォルトになっているツールが複数存在しており、スキャン済みの安全な状態だと誤認識されたまま脆弱性を含むイメージが本番に展開されるリスクがあります。

一方、コミットSHAや不変のセマンティックバージョンタグを用いれば、スキャン対象がダイジェスト単位で一意に特定されます。スキャン結果の追跡可能性が高まり、「このタグのイメージはいつ・どの脆弱性データベースでスキャンされたか」を監査ログとして保持できます。セキュリティ要件の厳しい環境ではこの追跡可能性が要件として求められることがあり、latest運用はその時点で選択肢から外れます。

複数環境での同一タグ衝突

開発・ステージング・本番の3環境を持つ構成では、各環境で「現在動いているイメージが何か」を把握することが運用の基本です。latestタグを全環境で共有している場合、ステージングへのデプロイが完了した直後に本番の調査を行うと、「latestは何を指しているのか」という混乱が生じます。環境ごとにlatestを持たせる設計にすると、タグの意味が完全に曖昧になり、命名規則として機能しなくなります。latest運用は実験的な単一環境に留め、複数環境を持つプロジェクトでは採用しないという線引きが判断の出発点です。

セマンティックバージョンとコミットSHAをどう組み合わせるか

単独運用の限界

セマンティックバージョン(semver)単独の運用では、v1.2.3というタグが誰によっていつ生成されたかを追跡するには、タグ生成時のCIジョブログを掘り起こす必要があります。リリース頻度が週に3〜5回を超えるチームでは、semverの採番作業がボトルネックになりやすく、自動採番の設計を組み込まないと採番漏れやバージョン重複が発生します。緊急時にホットフィックスのパッチバージョンを手動で採番する運用は、人的ミスを引き起こしやすい構造です。

コミットSHA単独の運用は、CIツール依存なしにビルドアーティファクトとソースコードを一対一で対応させる最もシンプルな方法です。ただしa3f9c12というタグを見ただけではどのリリースに相当するかが人間には分からず、デプロイ履歴を追う際に可読性が低下します。運用規模が大きくなるほど、人間が読めるバージョン識別子との組み合わせが必要になります。

二重タグ付けの設計パターン

実際の設計では、一つのイメージダイジェストに対して複数のタグを付与する二重タグ付けが有効です。想定例として、コミットSHAでapp:a3f9c12、semverでapp:v1.2.3という二つのタグを同一ダイジェストに紐付ける構成があります。CI側では不変のSHAタグで参照し、リリースノートや変更管理では人間が読めるsemverタグで管理するという役割分担が成立します。

この設計のポイントは、二つのタグが「同一ダイジェストを指している」点です。semverタグを誤って別のイメージに付け直した場合、SHAタグとダイジェストの不一致がレジストリのAPIで検出できます。後述するイミュータブルポリシーをsemverタグに適用することで、この誤操作を防ぐ構造にするのが望ましい設計です。

タグ命名規則の標準化

タグ命名規則はプロジェクト初期に決定しておくべき設計判断の一つです。よくある命名例として{semver}-{short-sha}(例:v1.2.3-a3f9c12)があります。この形式はsemverとSHAを一つのタグで表現できる利点がありますが、タグ文字列が長くなり一部のCIツールやUI上で表示が崩れる場合があります。チームのツールチェーンに合わせて、タグの最大長や文字種の制限を事前に確認することが重要です。命名規則を後から変更するとCIスクリプトや監視ダッシュボードの修正が広範に及ぶため、初期設計の段階で関係者と合意しておく価値があります。

タグの上書き禁止ポリシーをレジストリ側で強制する設計

レジストリ別の上書き禁止設定

主要なコンテナレジストリはいずれもイミュータブルタグの設定機能を持っています。Amazon ECRでは「イミュータビリティ設定」をリポジトリ単位で有効化でき、一度プッシュされたタグは同名での上書きが拒否されます。Google Artifact RegistryおよびGitHub Container Registryでも同等の制御が可能です。注意点として、latestタグもこのポリシーの対象にするかどうかは意図的に設計する必要があります。latestを意図的に更新し続けたい場合はlatestのみポリシー対象外にする構成も選択肢に入りますが、その場合はlatestを本番デプロイに使用しないルールをCI側で強制する仕組みを別途設けることになります。

CI側の多重防御

レジストリ側のポリシーだけに頼る設計は単一障害点を作ります。CI側でも「既存タグへのプッシュを行わない」チェックをパイプライン内に組み込むことで、ポリシー設定の変更ミスや異なるレジストリへの移行時の設定漏れに対応できます。具体的には、プッシュ前にレジストリAPIでタグの存在確認を行い、既存タグが検出された場合はパイプラインをfailさせるステップを挿入します。この二重防御は、インフラ側の設定変更が監査なしに行われる可能性のある組織規模や運用体制では特に有効です。

ポリシー違反の検知と通知

上書き禁止ポリシーによるプッシュ拒否が発生した場合、その事実をチームが即座に把握できる通知設計が必要です。拒否ログが埋もれていると、「なぜデプロイが失敗したのか」の原因調査に時間を要します。レジストリの監査ログをSIEMまたは通知チャネルに転送し、タグ上書き試行を検知した際にアラートを送る設計にしておくと、意図しない操作と意図した設定変更を区別しやすくなります。通知設計はレジストリ移行後にも引き継がれるよう、ログフォーマットへの依存を最小化しておくことが重要です。

マルチアーキテクチャイメージのmanifestリスト設計

manifest listとfat manifestの違い

マルチアーキテクチャ対応のイメージは、実際にはlinux/amd64やlinux/arm64といったアーキテクチャ別のイメージを束ねるmanifest list(OCI仕様ではimage indexと呼ばれます)として提供されます。クライアントがプルを実行すると、レジストリが実行環境のアーキテクチャを判別して適切なイメージを返す仕組みです。この仕組みを理解せずにタグ管理設計をすると、「arm64環境でプルしたところamd64用イメージが取得された」という問題の原因調査で行き詰まることがあります。

タグとアーキテクチャの命名設計

manifest listを活用する場合、各アーキテクチャ固有のイメージにはapp:v1.2.3-amd64のようにアーキテクチャサフィックスを付けたタグを使い、manifest listそのものにはapp:v1.2.3という簡潔なタグを付与する命名設計が一般的です。利用者はapp:v1.2.3を指定するだけで環境に合ったイメージが取得でき、アーキテクチャを意識した操作が不要になります。一方でCI/CDではアーキテクチャ別にビルドとプッシュを並列実行し、最後にmanifest listを作成してプッシュするという手順の設計が必要で、単一アーキテクチャ運用と比べてパイプライン構成が複雑になります。この複雑さを受け入れてまでマルチアーキテクチャ対応が必要かは、ARM環境(GravitonやApple Siliconで動かすCI)の実際の利用状況に基づいて判断してください。

既存パイプラインへの組み込み判断

既存のCI/CDパイプラインにマルチアーキテクチャ対応を後付けする場合、manifest list作成のステップを追加するだけでなく、イミュータブルタグポリシーとの整合性も確認が必要です。各アーキテクチャ固有タグとmanifest listタグのいずれにもイミュータブルポリシーを適用するのが理想ですが、manifest listの再作成(同一バージョンに新アーキテクチャを追加するケースなど)が必要な場合は、バージョン番号の採番設計を見直すかポリシーの適用範囲を調整することになります。後付け対応は設計変更の影響範囲が広くなるため、ARM対応の要件が見えた段階で早めに設計検討を始めることが推奨されます。

タグとGitブランチ/タグを対応させるCIパイプライン設計

ブランチ戦略とイメージタグの対応設計

GitHubフローやGitフローを採用しているチームでは、ブランチとイメージタグの対応関係を明示的に設計することで、「どの環境にどのイメージをデプロイすべきか」の判断基準が自明になります。一般的な対応例として、featureブランチへのプッシュではapp:{branch-name}-{short-sha}タグのイメージをビルドしてレビュー環境にデプロイ、mainブランチへのマージではapp:main-{short-sha}タグのイメージをステージング環境にデプロイ、Gitタグ付与時にapp:v{semver}タグのイメージを本番環境にデプロイするという設計が挙げられます。

この設計では、本番環境へのデプロイトリガーをGitタグに限定することで、誰がいつ本番用イメージを生成したかの追跡可能性が確保されます。Gitタグの付与権限をリリース担当者に限定するアクセス制御と組み合わせることで、本番デプロイの承認フローをコードベース上で表現できます。

Git tagトリガーによる本番イメージ生成

vプレフィックスを持つGitタグをCIのトリガーとして設定し、そのタグ名をそのままイメージタグに利用する設計はシンプルかつ追跡可能性が高い方法です。ただし、Gitタグはデフォルトでは削除・移動が可能なため、タグの移動をブロックするタグ保護ルールの設定が前提条件になります。GitHubではRulesetsで特定パターンのタグへの移動・削除を制限できます。CIパイプラインの設計と同時にタグ保護設定を検討することが重要で、片方だけ先行して設定すると想定外の動作を引き起こす場合があります。

タグの一貫性を保つパイプライン構成

CIパイプラインの各ジョブでイメージタグを独立して生成すると、ジョブ実行タイミングのズレによって同一コミットから異なるタグが生成される場合があります。タグ生成ロジックは最上流のジョブで一度だけ実行し、その結果をパイプライン変数として下流のジョブに引き渡す設計にすることで、タグの一貫性を保てます。この設計はパイプラインのデバッグ時にも役立ち、「どのジョブが何のタグを使ったか」を単一の変数定義から辿れます。タグ生成ロジックを分散させると、CI設定ファイルの変更が必要になった際の修正箇所が増えるため、一か所集約は保守性の観点でも有利です。

古いタグの削除ポリシーをいつどう設定するか

削除対象の選定基準

タグの削除ポリシーを設計する前に、削除してはならないタグを明確にしておく必要があります。保護すべきタグの基準として、(1)現在本番・ステージング・開発の各環境でアクティブに動作しているイメージのタグ、(2)過去30〜90日以内にデプロイされた本番用タグ(ロールバック候補)、(3)特定のリリースマイルストーンや監査要件に紐づく長期保持タグ、の三つを基本的な設計軸とすることが多いです。これらの基準を明文化した上で、それ以外のタグを削除対象とする設計にします。

削除実行のタイミングと猶予期間

削除ポリシーの実行タイミングはレジストリのストレージコストに直結します。想定例として、featureブランチ由来のイメージはブランチクローズから7日後、develop/mainブランチ由来のイメージはデプロイから30日後を削除基準とする設計があります。ただし削除実行前に、現在稼働中のコンテナが参照しているイメージを対象から除外するチェックを挟むことが必須です。稼働中のイメージを削除すると、ノード再起動時やスケールアウト時にコンテナ起動が失敗します。猶予期間の長さは、組織のロールバック運用実績(過去90日で何回ロールバックが発生したか)を参考に設定することで、必要以上にストレージを確保しすぎる設計を避けられます。

誤削除防止のためのタグ保護設計

自動削除ジョブが誤動作した場合の被害を最小化するため、削除実行前のドライランを設計に組み込みます。ドライラン結果をレビューするステップを自動削除フローに挟み、削除対象リストに保護すべきタグが含まれていた場合にジョブを停止する仕組みにします。Amazon ECRのライフサイクルポリシー、Google Artifact Registryのクリーンアップポリシーはドライラン相当の機能を持つため、各レジストリの設定詳細については公式ドキュメントや構築セミナーで確認することを推奨します。保護タグのリストを動的に生成する(デプロイ記録から現在稼働中のタグを自動抽出する)設計にしておくと、保護対象の更新漏れによる誤削除リスクを大幅に低減できます。

タグ戦略比較表(latest / semver / commit-SHA / calver)

以下に、代表的な4つのタグ戦略の特性を比較します。実際の選定は単一基準ではなく、デプロイ頻度・チームのツールチェーン・監査要件を組み合わせて判断してください。

戦略 不変性 可読性 追跡可能性 採番コスト 向いているケース
latest なし(上書き) 高(直感的) 低(ビルド特定不可) ゼロ ローカル開発・実験環境のみ
semver 設定次第 高(v1.2.3) 中(SHAと組み合わせで向上) 中(採番ルール設計が必要) 外部公開ライブラリ・API
commit-SHA 高(実質不変) 低(人間が読みにくい) 最高(ソースと一対一) ゼロ(CIが自動生成) CD自動化・内部サービス全般
calver 設定次第 中(2026.11.01) 中(日時でおおよそ特定可) 低(日付から自動生成) 日次リリース・データパイプライン

タグ戦略選定チェックリスト

タグ戦略を最終決定する前に、以下の項目を確認してください。すべてに「はい」と答えられる設計が、本番運用に耐えられる状態の目安です。

  • 本番デプロイ時に使用するタグは不変か(同一タグで常に同一ダイジェストを返すか)
  • ロールバック時に前回デプロイのイメージタグを即座に特定できるか
  • セキュリティスキャンの結果がタグ単位で追跡・監査可能か
  • タグとGitのコミット・ブランチ・タグが対応関係として記録されているか
  • レジストリ側でイミュータブルタグポリシーが有効化されているか
  • CI側にも既存タグへのプッシュを防ぐチェックが組み込まれているか
  • 削除ポリシーに「稼働中イメージの除外」チェックが含まれているか
  • マルチアーキテクチャ対応が必要な場合、manifest list設計が完了しているか
  • CIのタグ生成ロジックが一か所に集約され、ジョブ間で一貫性が保たれているか

▶ 手を動かして本番まで到達する

その設計判断を、RHEL10の本番環境で手を動かして固めませんか

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。

コンテナイメージのタグ管理設計を実装で確かめる上級Linuxハンズオンへ →

Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン