約100行のBashで実装されたDocker、Bocker (2015)
(github.com/p8952)- Bockerは、Dockerを約100行のBashで実装したプロジェクトで、イメージのpull、コンテナのrun、ログ確認、commit、削除といったDocker類似のワークフローを提供する
- 実行には btrfs-progs、curl、iproute2、iptables、libcgroup-tools、util-linux 2.25.2以上、coreutils 7.5以上が必要で、
/var/bocker配下のbtrfsファイルシステムとbridge0ネットワーク構成が必要 - READMEの例では、
centos:7イメージをpullした後にコンテナ内でコマンドを実行し、yum install -y wgetの結果を commit して、その後の実行で/usr/bin/wgetを確認する流れを示している - Bockerはrootで実行され、ネットワークインターフェース、ルーティングテーブル、ファイアウォールルールを変更するため、仮想マシンで実行することが推奨されており、システム損傷の可能性がない保証はない
- 現在は
docker pull、images、ps、run、exec、logs、commit、rm/rmi、ネットワーキング、CGroupsベースのクォータ を実装しているが、データボリューム、データボリュームコンテナ、ポートフォワーディングはまだ実装されていない
Bockerの目的と範囲
- Bockerは、Dockerを約100行のBashで実装したプロジェクト
- READMEでは、Dockerに似たコマンドの流れをBashベースで示しており、イメージ管理、コンテナ実行、ログ参照、変更のcommit、リソース制限といった機能を含む
実行要件
- 実行に必要なパッケージは次のとおり
-
btrfs-progs
- curl
- iproute2
- iptables
- libcgroup-tools
- util-linux 2.25.2以上
- coreutils 7.5以上
- 多くのディストリビューションには十分に新しいutil-linuxが含まれていないため、util-linux 2.25ソース を取得して自分でコンパイルする必要がある可能性がある
- システムには次の構成が必要
/var/bocker配下にマウントされた btrfsファイルシステムbridge0というネットワークブリッジと10.0.0.1/24IP/proc/sys/net/ipv4/ip_forwardでIPフォワーディングを有効化bridge0から物理インターフェースへトラフィックをルーティングするファイアウォール設定- 必要な環境を簡単に作れるよう Vagrantfile が含まれている
-
実行時の注意事項
- 要件を満たしていても、Bockerは仮想マシンで実行することが推奨される
- Bockerはrootで実行され、次の項目を変更する必要がある
- ネットワークインターフェース
- ルーティングテーブル
- ファイアウォールルール
- READMEでは、Bockerがシステムを壊さないことを保証できないと明記している
使用例の流れ
bocker pull centos 7でcentos:7イメージを取得すると、img_42150のようなイメージIDが生成されるbocker imagesはイメージIDとソースを表示する- 出力例:
img_42150,centos:7
- 出力例:
bocker run img_42150 cat /etc/centos-releaseは、コンテナ内でCentOSのリリース情報を出力する- 出力例:
CentOS Linux release 7.1.1503 (Core)
- 出力例:
bocker psは実行されたコンテナIDとコマンドを表示するbocker logs ps_42045はそのコンテナの出力ログを表示するbocker rm ps_42045はコンテナを削除するbocker run img_42150 which wgetを実行すると、最初はwgetが存在しないという結果になるbocker run img_42150 yum install -y wgetでwgetをインストールした後、bocker commit ps_42018 img_42150で変更内容をイメージに反映する- その後
bocker run img_42150 which wgetは/usr/bin/wgetを出力する
リソース制限とCGroups
- Bockerの実行例では、コンテナが CGroups 配下に配置されることが示されている
/proc/1/cgroupにmemory:/ps_42152、cpuacct,cpu:/ps_42152のような項目が現れる
- デフォルトのCPU shareとメモリ制限の例は次のとおり
/sys/fs/cgroup/cpu/ps_42152/cpu.shares:512/sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes:512000000
- 環境変数でリソース制限を変更できる
BOCKER_CPU_SHARE=1024BOCKER_MEM_LIMIT=1024
- 変更後の例では次の値が示されている
- CPU shares:
1024 - memory limit:
1024000000
- CPU shares:
実装済み機能と未実装機能
- 現在実装されている機能は次のとおり
docker build†docker pulldocker imagesdocker psdocker rundocker execdocker logsdocker commitdocker rm/docker rmi-
Networking
- Quota Support / CGroups
- †
bocker initはdocker buildの非常に限定的な実装を提供する - まだ実装されていない機能は次のとおり
- Data Volume Containers
- Data Volumes
- Port Forwarding
ライセンス
- Bockerは GNU General Public License の条件に従って再配布および改変できる自由ソフトウェア
- ライセンスのバージョンは、Free Software Foundationが公開したGPL v3またはそれ以降のバージョンを選択できる
- このプログラムは有用であることを期待して配布されるが、商品性や特定目的への適合性についての黙示的保証もない
1件のコメント
Hacker News のコメント
proot で似たようなものを作ったことがある。名前は Bag [1] で、Docker の代替だとは説明していなかったはず。
cgroups とは関係なく、コマンドラインインターフェースも Docker とは違う。背景としては、インターネット検閲とディープパケットインスペクションを回避するために、通常の HTML トラフィックのように見えるプロキシチェーンを作っていて、どこでも動かし続ける必要があったが、Android ネイティブアプリに移植したくはなかった、というもの。
Termux で動かしたかったが、当時の Termux には JDK/JRE がなく、proot で Arch Linux 環境を立ち上げれば JDK が使えた。Termux 内の Arch 環境は全般により便利で、設定の異なる使い捨て環境を作って削除し、その後 proot で入り単一のコマンドだけを実行することも、スクリプトで簡単に自動化できた。そこで、海上コンテナよりずっと小さい形という意味で bag.sh と名付けた。
面白いことに、bag.sh には 5年間触っていないロードマップ/TODO も残っている。モバイル画面で書いて、スクロールせずに見られるように、ほとんどが 40 桁で行揃えされている。
[1]: https://github.com/hkoosha/bag
/opt の中に必要なソフトウェアと MySQL のような依存関係を入れた小さな Debian を作ったところ、かなりうまく動き、これを作ってくれた会社が 2016年ごろ買収されるまで使っていた。より一般的には、大きなアプリケーションの粗いバージョンを自分で実装してみるのは、内部の仕組みを学ぶ最良の方法の1つだと思う。
mkdir -p $(dirname "$2")革ジャケットの内ポケットに楽に入る 10インチくらいの Bluetooth キーボードと組み合わせれば、バッグなしで家を出ても、近くのビアガーデンの隅に座ってコードを書ける。意外と生産的でもある。ノートPCより普段の気晴らしに切り替える摩擦が少し大きいせいか、ビールを一口飲みながらコードをにらみ続けることになる。
こういうものが好きだ。最小限の Bashで作られたものが昔から好きだった。
約10年前、Docker や Mesos のような分散インフラを広めるために主催したハッカソンで作った、40行の Bash によるクラスタ内部ロードバランサの概念実証もある: https://github.com/cell-os/metal-cell/blob/master/discovery/...
たぶん失くしてしまったが、冗長性と分散性を備えたリバース SSH トンネルベースの colo-to-cloud 転送ツールもあった。Shell Fu などにはこういうコレクションがよく整理されている: https://www.shell-fu.org/
Docker の大きな部分をこんなに簡単に再実装できるという事実こそ、Docker という会社が直面してきた、そして今も直面している最大の問題だ。根本的にはカーネル機能をつなぎ合わせる接着コードに近いからだ。
Docker が実際に価値を加えている場所は Docker Hub だけでなく、Docker for Windows と Macだ。開発マシンで Docker を動かすために VirtualBox と Vagrant を自分で触るより、統合された体験がはるかに良い点が大きい。
個人的には、Docker の本当の魔法はDocker/OCI イメージ形式だったと思う。キャッシュとコンテナイメージ配布を見事に扱う仕組みで、今でも「丸ごと」の VM とワークフローを分ける中核だ。
Windows では WSL で Docker を使え、とてもよく動く。なぜ Docker Desktop を使うのか理解しにくい。
その代わり、きちんと信頼性高く動かなかった中途半端な Docker Swarm を作り、Kubernetes にすぐ押しのけられた。
自分の使い方は、数年前にソフトウェアをビルドするために誰かの仮想ビルド環境を持ってくる用途だけだった。
リポジトリに「未実装」「TODO」「作業中」のような文言があるのに、最後のコミットが何年も前だと分かるといい気分になる
自分のコードに散らしてある TODO を見直しに行かないことについて、少し気が楽になる。作者をけなしたいわけではなく、ただ慰めになる
無償、ボランティア、趣味のコードで、公開されているという理由だけでやらなければならないという負担を感じると、コーディングの楽しさが減り、本来公開していたはずのコードも公開しなくなる可能性がある
常に次のアイデアがあるなら、定義上、終わっていない TODO も常に残るしかない。実際、すべてのプロジェクトの正常な状態はそうあるべきだ
スコープの境界を明確にしておくのはまったく問題なく、しばしば役に立つ。そうすれば脇道を追いかけて、プロジェクトが永遠に「完成」していないように感じる状態に陥らずに済む
lazydocker が Docker Desktop の優れた代替としてまだ挙がっていないのは驚き。Linux/macOS/Windows で使える [1]
かなり機能豊富なターミナル UIで、SSH 越しに実行できるという利点もある
[1] https://github.com/jesseduffield/lazydocker
少なくとも自分はこういうものを初めて見た。こうした広告が GitHub の利用規約や許容利用ポリシーで認められているのかも気になる
Bocker がなぜこんなに頻繁にトップページに来るのか気になる。2024年でも Docker はまだそんなに議論の的なのか?
Docker が実際に有用なもの、主にソフトウェア配布と「どこでも簡単に実行」をもたらしたことを、なぜ認めないのか分からない
Docker は、すでに存在していたカーネル技術の組み合わせ。名前空間、cgroups、ユニオンファイルシステム、そしておそらく他にもいくつかある
だから興味深く、事実上完璧な HN 的な話題になっている
何人かにデモした後で、彼らは単に
/を使うこともできたし、あるいは自分が Docker を持っていってもよかったのだと気づいた異母兄弟のような存在として https://bastillebsd.org/ がある
Bastille は Docker で見かけそうな多くの構造を shell で使い、FreeBSD jail を管理する。依存関係がとても少ないので、BSD の他の jail 管理ソフトウェアより気に入っている
ただし CLI/TUI ベースのツールでありながら、「最大限に過剰」な解決策に近い。最近は FreeBSD の基本構成だけで jail を作成・管理する手順を踏んでいるところだが、これはあくまで一時的な段階
全体がどう噛み合っているのかを頭の中に十分刻み込んで、デバッグに自信が持てるようになるまでそうして、その後は分別ある人間らしく石同士を打ちつけるようなことをやめ、より高レベルのツールに戻るつもり
ただ、なぜ Bastille という名前なのか理解するのに少し時間がかかった。ラ・バスティーユは百年戦争のとき、英国の攻撃から Paris を守るために建てられた城で、後に監獄に変わった
「ほとんどのディストリビューションは十分に新しい util-linux を提供していないので、ここからソースを入手して自分でコンパイルする必要があるだろう」という部分には注意が必要
デフォルトのインストールプレフィックスが
/usr/binなので、インストール過程で既存のmount コマンドを、存在しないライブラリを要求するバージョンで上書きしてしまう可能性がある。そうなると次回起動時に、カーネルがファイルシステムを読み取り専用でマウントすることになる/usr/local/binであるべき日常的に使うには向かないが、Docker が何で、どう動くのかの感覚を与えてくれる
Linux 上の Docker は基本的に派手な chroot
面白い事実: Docker は Bash で始まり、その後 Python に移り、最終的に Go に落ち着いた
また 2013年の Docker ミートアップでは、誰かが Bash でDocker クローンを書いていた。人々は学びたがっており、こうしたものが役に立つといい