CodeCrafters の "Build Your Own Docker" コースを Ruby で取り組んだ。
完成品は以下。
開発中に考えたことや新しく知ったことを雑にメモる。
1. コンテナ内でのプロセスをホストマシンのそれから分離 (ref)
Linuxの unshare
コマンドにより、プロセスの名前空間を使い分離している。深掘って調べようとしたが断念。
例えば、$ unshare --pid --fork --mount-pro program_commandc
コマンドの引数として与えられたコマンドが実行されるプロセスの中では、自らのプロセスを参照すると 1 となる。オプションの詳細は、こちら
この機能は OS X (Darwin) では提供されていないっぽい。
2. コンテナ内でのファイルシステムをホストマシンのそれから分離 (ref)
ホストマシンでコンテナがルートディレクトリとして使用するディレクトリを作る。そして、Linuxのchroot
コマンドの引数として、コンテナのエントリポイントとなるコマンドを実行することにより、ファイルシステム内でアクセス可能な範囲をホストマシンのルートディレクトリの内部に制限できる。
例えば、$ chroot /app/root_dir program_command
を走らせた場合、プログラムのルートディレクトリは/root_dir
になる。
3. Dockerベースイメージの pull (ref)
ホストマシンで、コンテナ内に置いておきたいコマンド(/bin/ls
とか)の集合をtar.gz圧縮したファイルをDocker レジストリからダウンロードしてくる。そして、それを展開して、コンテナがルートディレクトリとして使用するディレクトリ内に置いている。
ダウンロードと展開の実装詳細は、こちらを参照。
4. コンテナ内で走るプロセスのexit status, stdout, stderrをdockerコマンドの出力として吐き出す (ref)
dockerコマンドのプロセスで、コンテナ内で走るプロセスを走らせて得られたexit status, stdout, stderrのそれぞれを、dockerrプロセスのそれとして書き出している。愚直だ。