前回記事で、Dockerイメージ内に含まれるmanifest.jsonがレイヤ構成を教えてくれることがわかりました。 このレイヤ構成の情報を使用して、OverlayFSでマウントしてみます。
今回やることの概要
OverlayFSでDockerイメージをマウントします。必要な作業としては、
- イメージのtarを展開する
- マウントするディレクトリ(lowerdir, upperdir, workdir, mergeddir)を準備する
- manifest.jsonからレイヤ情報を抜き出す
- 抜き出した情報をもとに、順番にレイヤをlowerdirへ展開する
- 2で作成したディレクトリをOverlayFSでマウントする
となるかと思います。
Dockerイメージに含まれていたレイヤは、lowerdirとしてマウントします。mergeddirが、実際に私たちが見て、ファイルの追加/変更/削除を行うことになるディレクトリです。upperdirはmergeddirに施した変更が反映されるディレクトリになります。workdirはシステムの内部作業用とのことで、ディレクトリの用意は必要ですが、基本的に気にする必要はなさそうです。
OverlayFSでのマウント
jsonの解析のため、jqを導入してみました。まだまだ使いこなせていないですが、慣れたら便利そう。
sudo apt install jq
イメージのtarをOverlayFSでマウントするシェルスクリプト(mount.sh)を書いてみました。lowerdirはレイヤごとに分けて作成するようにしています。 最後のmountコマンドのlowerdir引数には、上のレイヤから指定する必要があります。したがって、本スクリプトでも上のレイヤから順に展開しています。
#!/bin/bash #[Usage] ./mount.sh yourImageName.tar LOWERDIR="" # イメージのtarを展開 EXTRACT_DIR=${1%.*} mkdir -p $EXTRACT_DIR tar xvf $1 -C $EXTRACT_DIR # レイヤ数の取得 LOWER_LAYER_NUM=$(cat $EXTRACT_DIR/manifest.json | jq -r '.[].Layers | length') i=$(expr $LOWER_LAYER_NUM - 1) while [ $i -ge 0 ] do # 各レイヤのtarをlowerNディレクトリに展開 mkdir -p lower$i QUERY=".[].Layers | .[$i]" LOWER_LAYER_TAR=$(cat $EXTRACT_DIR/manifest.json | jq -r "$QUERY") tar xvf $EXTRACT_DIR/$LOWER_LAYER_TAR -C lower$i # マウント時の引数(lowerdir)を作成 LOWERDIR+="lower$i:" i=$(expr $i - 1) done # マウント用にディレクトリ作成 mkdir -p {upper,work,merged} # OverlayFSでマウント # (lowerdirは上のレイヤから指定することに注意) sudo mount \ -t overlay overlay \ -o lowerdir=${LOWERDIR/%?/},upperdir=upper,workdir=work merged
スクリプトを実行してmergedディレクトリの中身を見ると、前回作成したファイル(hello.txt, hoge.txt)が確認できます。
$ chmod +x mount.sh $ ./mount.sh testimage2.tar $ ls merged hello.txt hoge.txt # マウントを解除する場合は以下を実行 $ sudo umount merged
次回はマウント先をルートディレクトリとしてプロセス実行し、コンテナっぽいことをさせてみようと思います。