ここのサイトで紹介されているOverlayFS
の理解に時間がかかったので解説します。
OverlayFSとは?
一言で言うとファイルシステムです。特徴としてはCopy on Write(COW)機能を持っています。
COWとは、ベースとなるファイルシステムを読み取り専用とし、ここに含まれるファイルに対する書き込みが発生したときに該当のファイルをコピーして書き込みを行う、という仕組みを持ったファイルシステムです。
OverlayFSは2つのディレクトリを重ね合わせて1つのディレクトリとして見せるファイルシステムです。
・ lowerdir: 下位に位置するディレクトリでファイルシステムのベースとなるディレクトリです。このディレクトリは読み取り専用です。
・upperdir: 上位に位置するディレクトリで、lowerdirに対して新規作成、変更、削除されたファイルが書き出されるディレクトリです。
・merged: lowerdirとupperdirが結合されたディレクトリです。OverlayFSをマウントしたプロセスでは、作業者が閲覧するのはこのディレクトリとなります。
・work: OverlayFSの内部で使用される作業用ディレクトリです。
試してみる
※記事より転載しております
まずはLAYER1ディレクトリにてalpineを展開します。
$ LAYER1=$(mktemp -d) $ mkdir $LAYER1/diff $ CID=$(sudo docker container create alpine:latest) $ sudo docker export $CID | tar -x -C $LAYER1/diff $ sudo docker rm $CID
つづいてcurlパッケージをLAYER2ディレクトリに展開します。このときLAYER1をlowerdir
として設定することでalpne+curl
を作ることができます。
$ LAYER2=$(mktemp -d) $ mkdir $LAYER2/{diff,work,merged} $ sudo mount \ -t overlay \ -o lowerdir=$LAYER1/diff,upperdir=$LAYER2/diff,workdir=$LAYER2/work \ overlay \ $LAYER2/merged $ sudo mount --bind /etc/resolv.conf $LAYER2/merged/etc/resolv.conf $ unshare -r chroot $LAYER2/merged apk add --no-cache curl $ sudo umount -R $LAYER2/merged $ rm -rf $LAYER2/{work,merged}
図にするとこんな感じです。
最後にこれまで作ったLAYER1と2をlowerdir
としてexec curl $ARGS
を実行するプロセスを起動します。
CONTAINER=$(mktemp -d) $ mkdir $CONTAINER/{diff,work,merged} $ ROOTFS=$CONTAINER/merged $ sudo mount -t overlay \ -o lowerdir=$LAYER2/diff:$LAYER1/diff,upperdir=$CONTAINER/diff,workdir=$CONTAINER/work \ overlay \ $ROOTFS $ sudo mount --bind /etc/resolv.conf $ROOTFS/etc/resolv.conf $ ARGS="http://httpbin.org/uuid" $ unshare \ -uipr \ --mount-proc \ --fork \ chroot $ROOTFS /bin/sh -c "mount -t proc proc /proc && exec curl $ARGS"
コンテナで考えてみよう
ここではDockerで考えてみましょう。Dockerfile
を使ってcentosにapacheをインストールし、起動するコンテナを作るとします。
FROM centos RUN yum -y install httpd RUN mkdir /var/run/httpd COPY httpd.conf /etc/httpd/httpd.conf CMD [‘apachectl start’]
この時OverlayFSを使っているとLayerはこのようになります。
Dockerfile
は上から順に評価されますが、Layerは下から積み上がっていきます。そしてコマンドが増えれば増えるほどLayerも増えていきます。Layerはあくまでlowerdir
となりReadOnlyとなります。
このようにしてコンテナは成立しています。