コンテナイメージ形式の仕組み
Agata Krajewska
2020年11月18日
0 分で読めますここ数年、Dockerのリリースを受けて、コンテナはソフトウェアを提供するための標準的な仕組みとして、ますます普及しています。
コンテナベースのソリューションは増え続けています。この分野のイノベーションは歓迎すべきものですが、形式とランタイムに関する一定の標準を確立する必要があります。
Dockerプロジェクトの急速な成長により、Dockerイメージは多くの用途で標準となりました。しかし、次のような単一のオープンなコンテナ仕様を求める声が広くあることは間違いありません。
特定のクライアントやオーケストレーションスタックなど、上位レベルの構成要素に依存しない
特定の商用ベンダーやプロジェクトと密接に結び付いていない
多様なオペレーティングシステム、ハードウェア、CPUアーキテクチャ、パブリッククラウドなどで移植可能である
OCI(Open Container Initiative)は、OSレベルの仮想化、特にLinuxコンテナに関するオープン標準を策定するLinux Foundationのプロジェクトです。
Dockerは、ベースとなる形式とランタイムの仕様ドラフト、およびその仕様のリファレンス実装に関連するコードをOCIに寄贈しました。
現在、OCIイメージ形式は次のようなさまざまなオープンソースのビルドツールでサポートされています。
BuildKit:Dockerのビルドエンジンを最適化して書き直したもの
Podman:Dockerのコマンドラインツールの代替実装
Buildah:Dockerfileを記述する代わりに使えるコマンドラインツール
Snykは一般的なコンテナイメージ形式をすべてサポートしているため、エコシステム全体にわたる幅広いツールと連携できます。このブログ記事ではその一部を取り上げ、Snykがどのように連携するのかをご紹介します。
Dockerアーカイブ
まず、Dockerアーカイブ形式を見てみましょう。これは廃止されたDockerイメージ仕様v1の一部で、仕様の全文はこちらで確認できます。docker saveを実行すると、Dockerクライアントはデフォルトでこの形式を出力します。これは他のツールとの後方互換性のために使われます。コンテナレジストリでは、イメージの保存に新しい形式が使われています
Dockerをローカルで実行し、Snyk CLIまたはコンテナ連携機能を使用している場合、ローカルのDockerインスタンスを使ってイメージを取得し、ファイルシステムに保存してから解析を開始します。
このアーカイブの中身と、Snykにとって興味深い情報を見ていきましょう。
この記事ではubuntu:bionicイメージを使用します。まず、アーカイブをローカルのファイルシステムに保存しましょう。
docker save --output ubuntu-docker.tar ubuntu:bionic
bionicディストリビューションには3つのイメージレイヤーがあり、詳しく見ていきます。
tarアーカイブを展開したら、中身を確認できます。
manifest.jsonを見てみましょう。
このファイルはコンテナ設定を示しており、アーキテクチャ、設定、ルートファイルシステムのレイヤーなど、非常に役立つ情報を確認できます。また、Snykの観点からおそらく最も興味深いのはLayersプロパティです。実際のイメージレイヤーを示しており、これらはアーカイブ内のディレクトリです。そのディレクトリの1つに移動すると、内容を確認できます。
さらに詳しく見て、layer.tarを展開してみましょう。
上でご覧のとおり、layer.tarはイメージレイヤーのファイルシステム変更セットで、イメージの内容に応じて、すべての依存関係やその他のバイナリが含まれています。内容を抽出して解析すると
、各レイヤーの脆弱なパスの一覧を表示できます。
次に、保存したDockerアーカイブイメージに対してsnyk testを実行します。docker-archive:プレフィックスを指定すると、ローカルアーカイブをテストできます。
snyk container test docker-archive:ubuntu-docker.tarを実行するか、ローカルのDockerリポジトリからイメージをスキャンします。
snyk container test ubuntu:bionic
どちらもまったく同じ結果が出力されます。
OCIイメージ
ここ数か月で、Snyk CLIの機能にOCIアーカイブのスキャンも追加しました。
仕様を確認して、アーカイブの中身を見てみましょう。このセクションでもubuntu:bionicを使用します。
OCIアーカイブのtarファイルを自分で確認したい場合は、次のコマンドを実行できます。
skopeo copy --override-os linux docker://ubuntu:bionic oci-archive:ubuntu.tar
ここではSkopeoを使ってイメージを保存します。これは、イメージに対するさまざまな操作を簡単に実行できるcliユーティリティです。
ubuntuイメージをOCI形式で保存するには、tar出力にoci-archive:プレフィックスを指定するだけです。
ご注意ください。--override-osフラグも使っています。使用している環境はmacOSで、公式のDocker Hub ubuntu imagesはLinux向けのみ提供されているためです。複数アーキテクチャのイメージについては、後ほど説明します。
tarアーカイブを展開したら、その内容を確認できます。
ルートディレクトリに興味深いindex.jsonがあります。中身を見てみましょう。
これは(任意の)上位レベルのマニフェストで、特定のイメージマニフェストを示します。さまざまなアーキテクチャやオペレーティングシステムにまたがるイメージ群の情報が含まれています。詳しく知りたい方は、仕様の全文はこちらをご覧ください。
次に、index.jsonが示していたイメージ固有のマニフェストを、blobs/sha256ディレクトリで確認しましょう。
コンテナ設定など、興味深い内容が見えてきました。ここでは、イメージのアーキテクチャ、ベースイメージのレイヤー、設定など、多くの役立つ情報を確認できます。また、ubuntu:bionicイメージで利用できるレイヤーを示す、イメージレイヤーの情報もあります。
以下から、最初のレイヤーの内容がDockerアーカイブの場合とまったく同じだとわかります。
次のコマンドを実行すると、ローカルのOCIアーカイブをスキャンできます。
snyk container test oci-archive:ubuntu.tar
さまざまなプラットフォームとアーキテクチャ
DockerアーカイブとOCIイメージのマニフェストを調べたところ、どちらにもアーキテクチャ情報が含まれていました。ubuntu-dockerディレクトリにあるコンテナ設定マニフェストの内容をもう一度確認しましょう。ここにはdocker archiveを保存しました。
ほかの情報とともに、アーキテクチャとOSも確認できます。この場合はamd64とlinuxです。イメージがarm64ベースの場合や、windowsプラットフォームを使っている場合はどうでしょうか。
幸い、Snyk CLIに-—platformフラグを渡せば、ほかのプラットフォームもサポートできます。
docker saveのアーカイブ形式を見てきました。次は、Docker Hubでイメージの保存に使われるv2スキーマを見てみましょう。内部の仕組みは非常に興味深いものです。これはv2スキーマの第2版で、主に2つの目的をサポートするために作られました。Dockerのドキュメントによると、次のとおりです。
1つ目は、プラットフォームごとのイメージマニフェストを参照する「ファットマニフェスト」によって、マルチアーキテクチャイメージを実現することです。2つ目は、イメージ設定をハッシュ化してイメージIDを生成できるイメージモデルをサポートし、Dockerエンジンをコンテンツアドレス可能なイメージへと移行させることです。
ローカルのDockerを使って、まず対象イメージの「ファットマニフェスト」を確認し、利用可能なプラットフォームのバリエーションを調べられます。前述のとおり、これにより1つのリポジトリで、異なるアーキテクチャ向けの複数のイメージを管理できます。
docker manifest inspect ubuntu:bionic
その結果、マニフェストの配列が表示されます。
ubuntuイメージがさまざまなプラットフォーム向けに提供されていることがわかったので、arm64プラットフォームのアーキテクチャ向けにubuntuイメージをスキャンする方法を見てみましょう。
ホストのDockerで実験的機能が有効になっていることを確認して、次のコマンドを実行します。
snyk container test --platform=linux/arm64 ubuntu:bionic
出力を見てみましょう。
スキャン結果には、検出されたすべての脆弱なパスに加えて、「Platform」情報も表示されています。
この記事では、DockerとOCIの主要な2つのコンテナイメージ形式を取り上げ、複数のアーキテクチャにまたがってSnykがどちらとも連携できることをご紹介しました。
最後に、Node.jsとJavaアプリケーション向けの最適なDockerイメージを構築するためのセキュリティのベストプラクティスを確認しましょう。
Dockerのセキュリティに関する10のベストプラクティス — Dockerのベースイメージを構築する際や取得する際に従うべきセキュリティ対策を詳しく解説し、Docker Content Trustについても紹介します。
Java開発者の方は、こちらの資料もぜひご覧ください。Java開発者のためのDocker:セキュリティで失敗しないために知っておくべき5つのこと
DockerでNode.jsウェブアプリケーションをコンテナ化するための10のベストプラクティス — Node.js開発者におすすめの、Node.jsアプリケーション向けに安全で高性能なDockerベースイメージを構築する手順を紹介するガイドです。
これらの機能はすべてSnykで無料でご利用いただけます。アカウントを登録してください。
Capture the Flagを始めよう
オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。



