この記事は、skopeoでコンテナイメージをコピーしたときに同時にイメージdigestも一緒に出力できるからKubernetesのマニフェストへの埋め込みに便利だぞという話です。
skopeoはレジストリ間のコンテナイメージのコピーやタグ一覧の参照など、コンテナイメージのちょっとした操作を便利に実行できるユーティリティです。実践的な例としては、CIパイプラインでビルドしたイメージを検証環境や本番環境に昇格するといった使い方ができます。 この使い方をTektonから実行する解説記事がRed Hatさんのブログで紹介されています。
なぜdigestが必要か
Kubernetesなどのコンテナオーケストレーションツールでコンテナイメージを使うためには、イメージの識別子(タグなど)をマニフェストファイルに埋め込む必要があります。 識別子の埋め込むタイミングとしては、ビルド時やイメージの昇格時などが考えられるので、skopeoのイメージコピー操作と一緒に実行してあげると都合が良さそうです。
ここで問題になるのが、イメージの識別子として何を使うかです。 最も簡単なのはタグ名です。しかし、イメージを一意にかつ不変なものを指定するのであれば、digestの指定が確実です。 イメージの再プッシュが発生しうる場面では、同一のタグ名でも昨日と今日では別のイメージである可能性があります。 一方で同じタグ名でも内容が別のコンテナイメージであればdigestは別の値になります。
イメージの再プッシュが発生しない場面であればdigestではなくタグ名を識別子としても良いでしょう。 例えばAmazon ECRではレジストリのリポジトリ単位にイミュータブルタグを設定することでタグの再プッシュを防止できます。
digestを出力してみる
それではskopeoのコピー時にdigestを出力してみます。
開発用のレジストリ dev.registry.local/sample-app
から 検証環境のレジストリ staging.registry.local/sample-app
にイメージをコピーすると仮定します。
以下のサンプルでは digest.txt ファイルにdigestを出力しています。
ここでポイントは、 skopeoの copy
コマンド実行時にdigestを出力するファイル名と一緒に --digestfile
を指定します。
--digestfile
オプションはskopeo 1.3.0から使えるようです。
$ skopeo copy --digestfile digest.txt \ docker://dev.registry.local/sample-app:20220313 \ docker://staging.registry.local/sample-app:20220313 Getting image source signatures Copying blob sha256:8d66994d054da0091fad11fb497b2a23c0cfd350d897d78d57f78b3200b90fd6 Copying blob sha256:52355207fda65c2219b38c373cef4a25e868a97641e484f1393e632843705bff Copying blob sha256:c934f4d5f4297067be69f40f99b06c810790e6ecf5d54e30bba34a2dfa4b7684 (...中略...) Writing manifest to image destination Storing signatures $ cat digest.txt sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
これでイメージを一意に特定するdigestを得られたので、マニフェストを sed
などで置換すればコピーしたイメージを昇格先の環境にデプロイすることができそうです。
補足
ちなみにdigestをファイルに書き込むのはskopeo以外のツール/ユーティリティでも可能です。
例えばイメージビルドツールの kaniko だと --digest-file
オプションをつけて実行することで同じことを実現できます。
以上。