「車輪の再実装」って言葉が好き(実践はできてない)

コンテナランタイムなしでDockerHubのイメージをマウントする

この記事は、東京大学 品川研究室 Advent Calendar 2020及びDocker Advent Calendar 2020の2日目の記事として書かれました。

Docker Advent Calendar のネタですが、Dockerは使わないという若干本末転倒気味な小ネタです。 (あまり埋まってない様子だったので、これでも許されるはず...)

閑話休題、僕はコンテナイメージを研究対象としているとしているのですが、時々コンテナランタイムなしでコンテナイメージをマウントしたくなることがあります。

moby プロジェクトで公開されている download-frozen-image-v2.sh というシェルスクリプトを使うと、 docker image save で出力されるtarを展開した形で、コンテナイメージをDockerHubから取得する事ができますが、これだと若干不便です。

というのも、この形式でダウンロードできるのは、それぞれのレイヤーやコンフィグ、マニフェスト等をまとめたもで、直接ファイルを触ることができないのです。

マニフェストの中身を元に、各レイヤー(tarball)を展開し、mount コマンドを使って overlayfs としてマウントすればやりたいことはできるのですが、面倒です。

というわけで以下のようなpythonスクリプトを書いてみました。

gist.github.com

使い方はこんな感じです↓

$ wget https://raw.githubusercontent.com/moby/moby/master/contrib/download-frozen-image-v2.sh
$ chmod +x download-frozen-image-v2.sh
$ wget https://gist.githubusercontent.com/progrunner17/5337c83a799dc5baa9fd4bd6f5ce1170/raw/5e6dbddc2da32bf7136a13f29553f53e2f799625/stack_layers.py
$ chmod +x stack_layers.py

$ ./download-frozen-image-v2.sh nginx_dir nginx:latest
$ cd nginx_dir
$ ../stack_layers.py mnt
image nginx:latest was mounted on /path/to/workdir/nginx_dir/mnt
$ ls ./mnt/docker-entrypoint.d                                                                                                                                                                                             
10-listen-on-ipv6-by-default.sh*  20-envsubst-on-templates.sh*

スクリプトを読むと分かることですが、--workdir--upperdir を指定すると書き込み可能になったり、 -vオプションを付けると、内部で実行しているコマンドが表示されたりします。

mountコマンドかoverlayfsの仕様なのか?lowerdirが1つでかつupperdir等が設定されていないとマウントに失敗したり、 procfs等がマウントされていなかったりと不便はありますが、少ない依存で動くので重宝しています。

download-frozen-image-v2.sh なしで、pythonスクリプトだけで完結させたいなーとは思っていますが、 それもそれで若干の手間なので、しばらくこのままキメラ的に使う状況は続きそう...