この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Amazon EC2 Container Service (ECS): ECSエージェントの動作を確認するを書いている中で、scratchイメージの存在を知りました。
This image is most useful in the context of building base images or super minimal images
とのことで、超最小化されたベースイメージのようです。超最小というだけあってshさえ入っておらず、コンテナの中にシェルログインしようとしても入れません。
$ sudo docker run -it scratch /bin/sh
exec: "/bin/sh": stat /bin/sh: no such file or directoryFATA[0000] Error response from daemon: Cannot start container f7eb41a5e71f6c9357267ae572f3e990698c2ee54854dd362fefec88a29f2108: exec: "/bin/sh": stat /bin/sh: no such file or directory
ということで、このscrachイメージの中にログインできるようにして、中身を確認してみました。
やってみた
実行した環境はAmazon Linuxです。
要は、scrachイメージにshコマンドを追加したイメージを作って、コンテナ起動すれば良い訳です。ただ単純shコマンドをコピーしても、依存している共有ライブラリが無いと動きません。なので/bin/shが依存している共有ライブラリをlddコマンドで確認します。
$ ldd /bin/sh
linux-vdso.so.1 => (0x00007fff3bffe000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f934d17f000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f934cf7a000)
libc.so.6 => /lib64/libc.so.6 (0x00007f934cbd5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f934d3a9000)
作業用ディレクトリを作り、shコマンドとその依存している共有ライブラリをコピーします。
$ mkdir work;cd work
$ cp /bin/sh ./
$ cp /lib64/libtinfo.so.5 ./
$ cp /lib64/libdl.so.2 ./
$ cp /lib64/libc.so.6 ./
$ cp /lib64/ld-linux-x86-64.so.2 ./
$ ls
ld-linux-x86-64.so.2 libc.so.6 libdl.so.2 libtinfo.so.5 sh
scratchイメージにshコマンドを追加するためのDockerfileを作成します。
$ vi Dockerfile
FROM scratch
COPY ./sh /bin/sh
COPY ./libtinfo.so.5 /lib64/libtinfo.so.5
COPY ./libdl.so.2 /lib64/libdl.so.2
COPY ./libc.so.6 /lib64/libc.so.6
COPY ./ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
CMD ["/bin/sh"]
docker buildします。
$ sudo docker build -t local/sh .
Sending build context to Docker daemon 3.212 MB
Sending build context to Docker daemon
Step 0 : FROM scratch
---> 511136ea3c5a
Step 1 : COPY ./sh /bin/sh
---> Using cache
---> d888ba3ab54c
Step 2 : COPY ./libtinfo.so.5 /lib64/libtinfo.so.5
---> Using cache
---> 391272660fd9
Step 3 : COPY ./libdl.so.2 /lib64/libdl.so.2
---> Using cache
---> e612a1cd98af
Step 4 : COPY ./libc.so.6 /lib64/libc.so.6
---> Using cache
---> 1197f1569133
Step 5 : COPY ./ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
---> Using cache
---> b8b023b3f1dd
Step 6 : CMD /bin/sh
---> Using cache
---> d64311c33f95
Successfully built d64311c33f95
これでshコマンドを含めたscratchイメージが出来ました。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
local/sh latest d64311c33f95 33 seconds ago 3.206 MB
ではコンテナ起動します!
$ sudo docker run -it local/sh /bin/sh
sh-4.1#
はい、ログイン出来ましたね!
しかしlsコマンドもありません...
sh-4.1# ls
sh: ls: command not found
仕方がないのでechoで代用します。
sh-4.1# echo *
bin dev etc lib64 proc sys
sh-4.1# cd /sys
sh-4.1# echo *
block bus class dev devices firmware fs hypervisor kernel module power
sh-4.1# cd /etc
sh-4.1# echo *
hostname hosts mtab resolv.conf
本当に最小限のものしか入っていないようですね。そんなわけで、scratchイメージの内容が見えるようになりました!
さいごに
Docker関連はやってもやっても新しい発見ばかりです。本当はもっとECSに特化して勉強するつもりだったのですが、すっかり横道に逸れました。でも楽しいです!