すべての Docker イメージにはマニフェスト (タグ、デジタル署名、構成の詳細の JSON コレクション) がありますが、Docker イメージにはビルド時にいくつかの基本情報が不足している可能性があります。 これらの不足している詳細は、開発者に役立つ可能性があります。 では、どのように空白を埋めるのでしょうか。
このガイドでは、 BuildKit v0.10 の重要な要素である、ビルド メタデータからの新しいビルド情報構造の生成について説明します。 これにより、ビルドに渡されたすべてのソース (イメージ、Git リポジトリ、HTTP URL) と構成を確認できます。 この情報は、イメージ構成内に埋め込むこともできます。
このプロセスに取り組む方法について説明し、その過程でいくつかのベストプラクティスを共有します。
始める
この機能は BuildKit v0.10 にアップデートすると自動的に有効になりますが、元のイメージ名を確実にキャプチャするために BuildKit を使用することもお勧めします Dockerfile v1.4
。 これを行うには、次の構文を Dockerfile
: # syntax=docker/dockerfile:1.4
に追加します。
さらに、最新の安定バージョンの BuildKit を使用する Buildx を使用して、新しい ドッカーコンテナビルダー を作成することをお勧めします。 次の CLI コマンドを入力します。
$ docker buildx create --use --bootstrap --name mybuilder
注: デフォルトのビルダーに戻るには、コマンドを入力します $ docker buildx use default
。
次に、基本 Dockerfile
を作成しましょう。
# syntax=docker/dockerfile:1.4 FROM busybox AS base ARG foo=baz RUN echo bar > /foo FROM alpine:3.15 AS build COPY --from=base /foo / RUN echo baz > /bar FROM scratch COPY --from=build /bar / ADD https://raw.githubusercontent.com/moby/moby/master/README.md /
このイメージは、最新バージョンの Docker Desktop (v4.7) にパッケージ化されている Buildx v0.8.1 を使用してビルドします。 最新の Buildx バージョンでは、生成されたビルド情報を検査して使用できます。
$ docker buildx build --build-arg foo=bar --metadata-file metadata.json .
ビルド メタデータをファイルとして格納する
ファイル内に metadata.json
ビルド結果のメタデータを書き込む フラグを使用しています --metadata-file
。このフラグは、ビルド結果に関するメタデータ情報 (結果のイメージのダイジェストや新しい containerimage.buildinfo
キーなど) を取得するのに役立ちます。
このフラグは --metadata-file
、結果のイメージ ID のみをキャプチャする前の --iidfile
フラグを改善します。 Dockerfile
以下は、 containerimage.buildinfo
実際のキーを示しています。
{ "containerimage.buildinfo": { "frontend": "dockerfile.v0", "attrs": { "build-arg:foo": "bar", "filename": "Dockerfile", "source": "docker/dockerfile:1.4" }, "sources": [ { "type": "docker-image", "ref": "docker.io/library/alpine:3.15", "pin": "sha256:d6d0a0eb4d40ef96f2310ead734848b9c819bb97c9d846385c4aca1767186cd4" }, { "type": "docker-image", "ref": "docker.io/library/busybox:latest", "pin": "sha256:caa382c432891547782ce7140fb3b7304613d3b0438834dce1cad68896ab110a" }, { "type": "http", "ref": "https://raw.githubusercontent.com/moby/moby/master/README.md", "pin": "sha256:419455202b0ef97e480d7f8199b26a721a417818bc0e2d106975f74323f25e6c" } ] }, "containerimage.config.digest": "sha256:cd82085d327d4b41f86212fc372f75682f131b5ce5c0c918dabaa0fbf04ec53f", "containerimage.descriptor": { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "digest": "sha256:6afb8217371adb4b75bd7767d711da74ba226ed868fa5560e01a8961ab150ccb", "size": 732 }, "containerimage.digest": "sha256:6afb8217371adb4b75bd7767d711da74ba226ed868fa5560e01a8961ab150ccb", }
この結果の構造について注目すべきことは何ですか? これで、新しい containerimage.buildinfo
キーにビルド情報が含まれるようになりました。 また、重要なフィールド名も多数表示されます。
frontend
ビルドを担当するBuildKitフロントエンドを定義します(上記からDockerfile
ビルドしています)。attrs
ビルド構成パラメーターを包含します (例: 入力--build-arg
時)。sources
ビルド ソースを定義します。
さらに、各 sources
エントリは、結果の構築中に使用した外部ソース Dockerfile
を記述します。 ただし、他のJSONデータを強調する価値があります。
type
で参照されるFROM
すべてのコンテナー イメージに対して、またはgit
Git コンテキストを使用して adocker-image
を参照できます。最後に、type
コマンドで使用されるADD
HTTP URL コンテキストまたはリモート URL を参照できます。ref
は でDockerfile
定義されている参照です。pin
インストールされている依存関係のバージョンをいつでも知ることができます (ダイジェスト)。
ソースは、エクスポートされた最後のステージの基本イメージだけでなく、すべてのビルドステージでキャプチャされることに注意してください。
ビルド メタデータをイメージの一部として格納する
使用可能なトランスポートはメタデータ ファイルだけではありません。 また、BuildKit は、イメージがプッシュされると、イメージ構成内にビルド情報を埋め込みます。 これにより、ビルド情報が移植可能になります。 そのプッシュコマンドは次のようになります。
$ docker buildx build --build-arg foo=bar --tag crazymax/buildinfo:latest --push .
次のコマンド を使用して imagetools inspect
、既存のイメージのビルド情報を最新の Buildx バージョン で確認できます。
$ docker buildx imagetools inspect crazymax/buildinfo:latest --format "{{json .BuildInfo}}" { "frontend": "dockerfile.v0", "sources": [ { "type": "docker-image", "ref": "docker.io/library/alpine:3.15", "pin": "sha256:d6d0a0eb4d40ef96f2310ead734848b9c819bb97c9d846385c4aca1767186cd4" }, { "type": "docker-image", "ref": "docker.io/library/busybox:latest", "pin": "sha256:caa382c432891547782ce7140fb3b7304613d3b0438834dce1cad68896ab110a" }, { "type": "http", "ref": "https://raw.githubusercontent.com/moby/moby/master/README.md", "pin": "sha256:419455202b0ef97e480d7f8199b26a721a417818bc0e2d106975f74323f25e6c" } ] }
metadata-file
結果とは異なり、ビルド属性はイメージ構成内で自動的には使用できません。属性の包含は現在、面倒なリークを回避するためのオプトイン構成です。 開発者はこれらの属性をシークレットとして使用することがありますが、これはセキュリティの観点からは理想的ではありません。 代わりに使用 --mount=type=secret
することをお勧めします。
埋め込みイメージ構成にビルド属性を追加するには、 イメージ出力属性buildinfo-attrs
を使用します。
$ docker buildx build \ --build-arg foo=bar \ --output=type=image,name=crazymax/buildinfo:latest,push=true,buildinfo-attrs=true .
または、Buildx BUILDKIT_INLINE_BUILDINFO_ATTRS
ビルド引数を使用することもできます。
$ docker buildx build \ --build-arg BUILDKIT_INLINE_BUILDINFO_ATTRS=1 \ --build-arg foo=bar \ --tag crazymax/buildinfo:latest \ --push .
それです! これで、イメージ ビルドに起因する新しく生成されたビルドの依存関係を確認できます。
次は何ですか?
透明性は重要です。 Dockerイメージをより自己記述的で、解読可能で、再現可能で、目に見えるものにすることを常に目指してください。 この場合、イメージの構築中に使用された入力を簡単に発見できるようにしました。 さらに、セキュリティパッチで更新されたイメージを、ビルドソースの固定バージョンと比較することもできます。 これにより、画像が最新であるか安全に使用できるかどうかがわかります。
これは、セキュアソフトウェアサプライチェーン(SSSC)の旅における重要なステップの1つであり、ビルドの再現性を向上させます。 再現性の詳細については、 BuildKit リポジトリでも入手できます。
しかし、私たちはさらに進んでいきたいと思っています。 Docker は BuildKit を介してすべてのコンテナイメージに SBOM を導入しています。 私たちは、BuildKit を強化するために開発コミュニティをこの取り組みに参加させ、画像レベルの透明度を高めるための次の大きな一歩を踏み出したいと考えています。
BuildKit についてもっと知りたいですか? 最新のBuildKitリリースには、 Tonis Tiigiのブログ投稿で紹介されているような、他の便利な機能が付属しています。 リモートキャッシュのサポートの改善と迅速な画像リベースを求めている場合は、読む価値があります。