Docker イメージに基づいて Dockerfile をリバース エンジニアリングする方法

Docker イメージに基づいて Dockerfile をリバース エンジニアリングする方法

導入

使用したい Docker イメージを見つけたものの、特定のニーズに合わせて変更できなかったことはありませんか?あるいは、気に入った Docker イメージを見つけたものの、それがどのように構築されたかを理解したい場合もあります。どちらの場合も、いくつかのツールを使用して Docker イメージをリバースして Dockerfile を生成することができます。

Docker イメージを Dockerfile に変換するということは、既存の Docker イメージを取得し、それを使用して変更および制御できる Dockerfile を作成することを意味します。

このプロセスにより、Docker イメージの内部動作を理解し、変更を加えたり、さまざまなプラットフォームで実行できるようにイメージを更新したり、特定のニーズに合わせて最適化したりすることができます。

このブログ記事では、いくつかのオープンソース ツールを使用して Docker イメージを解釈し、Dockerfile に変換するプロセスについて説明します。

Dedockifyを使用して実装

写真

Docker イメージはブラック ボックスのようなもので、イメージ構築プロセス中に実行される一連の命令のレイヤーが含まれています。

現在、Dedockify という、イメージの作成に使用された Dockerfile のおおよそのバージョンを再構築するのに役立つ Python スクリプトを使用するツールがあります。

Dedockify は、各画像レイヤーの隣に保存されているメタデータを活用して機能します。これは、階層ツリーに沿って後方にトラバースし、各レイヤーに関連付けられたコマンドを収集することによって行われます。

このプロセスにより、イメージビルドプロセス中に実行されたコマンドのシーケンスを再構築できるようになります。

ただし、問題があります。COPY または ADD 命令を使用すると、Dedockify によって生成された出力は元の Dockerfile と完全に一致しません。これは、Dedockify が元の docker build コマンドが実行されたときに存在していたビルド コンテキストにアクセスできないためです。

Dedockify を使用するには、Docker コンテナとして実行します。

 docker run -v /var/run/docker.sock:/var/run/docker.sock dedockify <imageID>

パラメーター <imageID> はイメージ ID です (短縮または完全指定が可能)。

このスクリプトは、Docker API と対話して各イメージ レイヤーのメタデータを照会するため、Docker API ソケットにアクセスする必要があります。上記の -v フラグにより​​、スクリプトを実行するコンテナ内で Docker ソケットが使用できるようになります。

どのように機能しますか?

Dockerfile からイメージを構築する場合、Dockerfile 内の各命令によって新しいレイヤーが生成されます。すべてのイメージ レイヤーを表示するには、docker images コマンドを (現在は非推奨の) --tree フラグ付きで使用できます。

 $ docker images --tree Warning: '--tree' is deprecated, it will be removed soon. See usage. └─511136ea3c5a Virtual Size: 0 B Tags: scratch:latest └─1e8abad02296 Virtual Size: 121.8 MB └─f106b5d7508a Virtual Size: 121.8 MB └─0ae4b97648db Virtual Size: 690.2 MB └─a2df34bb17f4 Virtual Size: 808.3 MB Tags: buildpack-deps:latest └─86258af941f7 Virtual Size: 808.6 MB └─1dc22fbdefef Virtual Size: 846.7 MB └─00227c86ea87 Virtual Size: 863.7 MB └─564e6df9f1e2 Virtual Size: 1.009 GB └─55a2d383d743 Virtual Size: 1.009 GB └─367e535883e4 Virtual Size: 1.154 GB └─a47bb557ed2a Virtual Size: 1.154 GB └─0d4496202bc0 Virtual Size: 1.157 GB └─5db44b586412 Virtual Size: 1.446 GB └─bef6f00c8d6d Virtual Size: 1.451 GB └─5f9bee597a47 Virtual Size: 1.451 GB └─bb98b84e0658 Virtual Size: 1.452 GB └─6556c531b6c1 Virtual Size: 1.552 GB └─569e14fd7575 Virtual Size: 1.552 GB └─fc3a205ba3de Virtual Size: 1.555 GB └─5fd3b530d269 Virtual Size: 1.555 GB └─6bdb3289ca8b Virtual Size: 1.555 GB └─011aa33ba92b Virtual Size: 1.555 GB Tags: ruby:2, ruby:2.1, ruby:2.1.1, ruby:latest

これらの各レイヤーは、Dockerfile 内の命令を実行した結果です。実際、これらのレイヤーのいずれかに対して docker inspect を実行すると、そのレイヤーを生成するために使用された命令を確認できます。

 $ docker inspect 011aa33ba92b [{ . . . "ContainerConfig": { "Cmd": [ "/bin/sh", "-c", "#(nop) ONBUILD RUN [ ! -e Gemfile ] || bundle install --system" ], . . . }]

Docker の例:

以下は、公式の Docker Ruby イメージをプルし、そのイメージの Dockerfile を生成する方法を示した例です。

 $ docker pull mrhavens/dedockify Using default tag: latest latest: Pulling from dedockify $ alias dedockify="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm mrhavens/dedockify" $ dedockify <imageID> FROM buildpack-deps:latest RUN useradd -g users user RUN apt-get update && apt-get install -y bison procps RUN apt-get update && apt-get install -y ruby ADD dir:03090a5fdc5feb8b4f1d6a69214c37b5f6d653f5185cddb6bf7fd71e6ded561c in /usr/src/ruby WORKDIR /usr/src/ruby RUN chown -R user:users . USER user RUN autoconf && ./configure --disable-install-doc RUN make -j"$(nproc)" RUN make check USER root RUN apt-get purge -y ruby RUN make install RUN echo 'gem: --no-rdoc --no-ri' >> /.gemrc RUN gem install bundler ONBUILD ADD . /usr/src/app ONBUILD WORKDIR /usr/src/app ONBUILD RUN [ ! -e Gemfile ] || bundle install --system

ダイブツールを使って達成する

Dive は、Docker イメージ、レイヤーの内容を探索し、Docker/OCI イメージのサイズを縮小する方法を見つけるためのツールです。

写真

Dive は、Docker イメージやレイヤーの内容を探索し、イメージ サイズを縮小する方法を見つけるためのツールです。ファイル サイズ、権限など、各レイヤーの内容の詳細な内訳が提供されます。イメージのサイズを縮小するために削除できる不要なファイルや依存関係を識別するのに特に役立ちます。

特徴:

  • 詳細なレイヤー コンテンツの内訳: Dive は、Docker または OCI イメージ内の各レイヤーのコンテンツの詳細な内訳を提供します。各ファイルのサイズ、権限、その他のメタデータが表示されます。
  • 色分けされたインターフェース: Dive は色分けされたインターフェースを使用して、さまざまなファイル タイプを強調表示します。これにより、不要なファイルや依存関係を簡単に識別して削除できます。
  • インタラクティブな探索: Dive を使用すると、各レイヤーのコンテンツをインタラクティブに探索できます。レイヤーを参照したり、個々のファイルを表示したり、変更を加えて画像を最適化することができます。
  • 最適化の提案: Dive は画像を最適化するための提案を提供します。大きなファイル、不要な依存関係、その他の潜在的な最適化を識別します。

方向:

Dive を使用するには、システムにインストールし、Docker または OCI イメージに対して実行する必要があります。

 dive <imageID>

たとえば、公式の Alpine Linux イメージを分析するには、次のコマンドを実行します。

 dive alpine:latest

Dive は画像のレイヤーの詳細な内訳を表示し、各レイヤーの内容を調べて最適化の可能性を特定できるようにします。

Dive のようなサードパーティ製ツールに加えて、すぐに使用できるツールが docker history です。例 1 のイメージに対して docker history コマンドを使用すると、このイメージの作成に使用された Dockerfile 内のエントリを表示できます。

 docker history nginx

したがって、次の結果が得られるはずです。

 IMAGE CREATED CREATED BY SIZE COMMENT 374e0127c1bc 25 minutes ago /bin/sh -c #(nop) COPY file:aa717ff85b39d3ed… 0B 84acff3a5554 25 minutes ago /bin/sh -c #(nop) COPY file:2a949ad55eee33f6… 0B a9cc49948e40 25 minutes ago /bin/sh -c #(nop) COPY file:e3c862873fa89cbf… 0B

CREATED BY 列の内容はすべて切り捨てられることに注意してください。これらは、Bourne シェルを介して渡される Dockerfile 命令です。この情報は、ここでは省略されていますが、Dockerfile を再作成する際に役立つ可能性があります。--no-trunc オプションを使用すると、すべてを確認することもできます。

 $ docker history example1 --no-trunc IMAGE CREATED CREATED BY SIZE COMMENT sha256:374e0127c1bc51bca9330c01a9956be163850162f3c9f3be0340bb142bc57d81 29 minutes ago /bin/sh -c #(nop) COPY file:aa717ff85b39d3ed034eed42bc1186230cfca081010d9dde956468decdf8bf20 in / 0B sha256:84acff3a5554aea9a3a98549286347dd466d46db6aa7c2e13bb77f0012490cef 29 minutes ago /bin/sh -c #(nop) COPY file:2a949ad55eee33f6191c82c4554fe83e069d84e9d9d8802f5584c34e79e5622c in / 0B sha256:a9cc49948e40d15166b06dab42ea0e388f9905dfdddee7092f9f291d481467fc 29 minutes ago /bin/sh -c #(nop) COPY file:e3c862873fa89cbf2870e2afb7f411d5367d37a4aea01f2620f7314d3370edcc in / 0B

これには有用なデータが含まれていますが、コマンド ラインから解析するのは少し難しい場合があります。 docker inspect を使用することもできます。

イメージからの Dockerfile (dfimage)

docker history コマンドの動作と同様に、Python スクリプトは Docker が各イメージ レイヤーの横に保存するメタデータを使用して、イメージの構築に使用された Dockerfile を (おおよそ) 再作成できます。

https://github.com/LanikSJ/dfimage

Python スクリプト自体は Docker イメージとしてパッケージ化されているため、Docker run コマンドを使用して簡単に実行できます。

 docker run -v /var/run/docker.sock:/var/run/docker.sock dfimage ruby:latest

ruby:latest 引数はイメージ名とタグです (省略形または完全なイメージ名とタグを使用できます)。

このスクリプトは Docker API と対話してさまざまなイメージ レイヤーのメタデータを照会するため、Docker API ソケットへのアクセスが必要です。上記の -v フラグにより​​、スクリプトを実行しているコンテナー内で Docker ソケットが使用できるようになります。

このスクリプトは、ローカル レジストリに存在するイメージ (つまり、 docker images と入力したときに表示されるイメージ) でのみ機能することに注意してください。ローカル リポジトリに存在しないイメージの Dockerfile を生成する場合は、まず docker pull コマンドを使用してイメージをプルする必要があります。

要約する

Docker イメージを Dockerfile にリバース エンジニアリングすること、つまり「Docker イメージのバックトラック」は、イメージのビルド プロセスを理解して再作成するのに役立つ便利な手法です。 Dive や Dedockify などのツールは、イメージ レイヤーとメタデータを分析して対応する Dockerfile を生成するのに役立ちます。

<<:  Alibaba の調整システムの詳細な分析: 分散トランザクションの一貫性の課題!

>>:  クラウドエンジニアとクラウドアーキテクトが不可欠な理由

推薦する

検索エンジンに頼る以外に、最初のユーザー集団を獲得するにはどうすればよいでしょうか?

新しいウェブマスターは、最初のユーザー集団をどうやって獲得するかという主要な問題に直面します。最も一...

「MQ シリーズをマスターする」 - カフカの謎を解き明かす

[[390063]]みなさんこんにちは。私はウー兄弟です。これは「MQ マスタリー シリーズ」の第 ...

1年間の経験に基づいて、タオバオSEOをマスターするためのいくつかの重要な要素を共有します

タオバオに参入したばかりの多くの小規模な販売業者にとって、直通列車に費やすお金があったり、大量の商品...

旧正月中にウェブサイトのメンテナンスレベルに入り、ウェブサイトのランキングを安定させる方法

春節が近づくにつれ、ほとんどの個人ウェブマスターは、これまでの集中的な最適化を緩め、新年の雰囲気に溶...

#元旦# メガレイヤー: 香港/アメリカ/フィリピン/シンガポール、CN2/CUII回線、199元VPS-16Gメモリ/8コア/240gSSD/3IP、399元e3専用サーバー

クリスマスと元旦を祝うため、Megalayer は新しいプロモーションを開始しました。このプロモーシ...

分散アーキテクチャの過去と現在を10分で理解する

すべてのプログラマーにとって、分散アーキテクチャについて聞いたときの最初の反応は通常、それがハイエン...

VPSBlast [Banwagong] - $6.99/512m メモリ/256mvswap/10gSSD/500g トラフィック/6 データセンター

VPSBlast は IT7 のメイン VPS ブランドです。もちろん、ローエンド VPS ブランド...

ウェブサイト最適化の詳細処理プロセス1:ウェブサイトコード

ウェブサイトの最適化の過程で、多くのウェブマスターは盲目的に外部リンクの構築とランキングを追求し、ほ...

フレンドリーリンクの誤解を避け、フレンドリーリンクを最大化する方法を分析する

最近、フレンドリーリンクに関する議論は比較的少なくなっています。多くのSEO最適化担当者は基本的に、...

知りたいDevOpsの実践方法はすべてここにあります

[51CTO.comからのオリジナル記事] インターネット産業の急速な発展に伴い、IT研究開発の作業...

クラウド時代のインターネットジャンル

01シリコンバレーのインターネットの「先進的なアイデア」は、かつての主導的地位を失いつつある。 Pa...

SEO を活用して企業のウェブサイトを最適化する方法

始める前に、皆さんに質問したいと思います。エンタープライズ ウェブサイトとは何ですか? エンタープラ...

「Snowflake ID」のご紹介: 分散環境で大規模に一意の ID を生成するにはどうすればよいでしょうか?

[[334452]]画像ソース: unsplash一意の ID により、開発者はデータ オブジェクト...

マーケティングとは何かを理解するための5分

広告はユーザーの視点からのコミュニケーションであり、マーケティングは企業の視点からのマネジメントです...

SEOを「競争」の観点から見る

SEO に関して言えば、ホワイトハット SEO だけでも、ソフトな記事の書き方、ウェブサイトの構造化...