Docker 和 LXC
Docker はただ LXC を再発明しているわけではないというお話。DotCloud のファウンダーによる stackoverflow の質問への回答。
LXC はネームスペースやコントロールグループ等の Linux カーネルケーパビリティ機能を利用し、プロセスを他のプロセスからサンドボックス化し、それらプロセスへのリソースの割当てをコントロールしている。Docker はこのローレベルのカーネル機能を軸に、以下のような機能を提供している。
Docker 对 LXC 提供的功能的支持
どんなマシンへもポータブルデプロイ可能 Docker はアプリケーションをビルドするためのフォーマットが定義されており、その全ての依存関係を (Docker がインストールされている全てのマシンで動作する) 単一のオブジェクトに入れ、それはどこで実行してもアプリケーション実行環境が同一になります。LXC が提供するプロセスのサンドボックスはポータブルデプロイメントにとって必要不可欠な機能ですが、それだけではポータブルではありません。もしあなたが LXC のコンフィグをカスタマイズしており、その LXC 上で動作しているアプリケーションを複製し私に送ったとしても、私の LXC のコンフィグをカスタマイズしたマシンにデプロイしても構成が違うので動作しないでしょう: ネットワーク、ストレージ、ロギング、ディストリビューション、など。Docker はこれらマシン特有の設定を抽象化しているため、どんなマシンへも、どんな構成でも実行できます。
アプリケーションが中心 Docker は仮想サーバではなくアプリケーションのデプロイに最適化されています。これは API, UI, デザイン哲学, ドキュメントに反映されています。対照的に LXC ヘルパースクリプトは軽量な仮想サーバにフォーカスしており、基本となるサーバはブートが高速で RAM 使用量もわずかです。私達はよりコンテナよりです。
自動ビルド Docker には開発者がアプリケーションの依存関係、ビルドツール、パッケージング等を利用し、ソースコードからコンテナを自動的にアセンブルするツールが含まれています。それにはマシンの構成に関係なく make, maven, chef, puppet, salt, debian パッケージ, rpm ファイル, ソースの tarball, その他便利なツールを使えます。
バージョニング Docker にはバージョン間の差異の確認、新しいバージョンのコミット、ロルバックなど、git のようなコンテナのバージョン管理機能が含まれています。また、コンテナが誰によってどのように変更されたか履歴が追えるため、プロダクションサーバからアップストリームの開発者までのすべての記録を辿れます。Docker は git pull のような差分アップロードやダウンロード機能があるので、新しいバージョンのコンテナは差分のみ転送すれば OK です。
コンポーネントの再利用 すべてのコンテナはよりカスタマイズするための “ベースイメージ” として利用可能です。これは手動でも実行できますが、自動ビルドの一部としても実行可能です。例えば究極の Python 実行環境を作成し、異なる 10 個の Python アプリケーションのベースとして利用できます。他にも究極の PostgreSQL 環境をセットアップしたら、それを将来のプロジェクトで再利用できます。
共有 Docker は便利なコンテナがアップロードされているパブリックリポジトリ (http://index.docker.io/) にアクセスできます。redis, couchdb, postgres, IRC Proxy, rails アプリケーションサーバ, hadoop, 各ディストリビューションなど多岐に渡ります。レジストリには Docker チームがメンテナンスしているオフィシャルのスタンダードライブラリーも含まれています。レジストリそのものはオープンソースとして公開されているため、オンプレミスでレジストリを作成し、プライベートなイメージを保存し、そこからデプロイ出来ます。
エコシステム Docker はコンテナの作成とデプロイを自動化し、カスタマイズするための API を提供しています。Docker の機能を拡張する多くのツールがあります。 PaaS ライクなデプロイメント ができる Dokku, Deis, Flynn, 複数ノードのオーケストレーション maestro, salt, mesos, openstack nova, 管理用ダッシュボード docker-ui, openstack horizon, shipyard, 構成管理 chef, puppet, CI jenkins, strider, travis などなど。
关于LXC
LXC = Linux Containers
簡単にいうと “単一の Linux カーネルをプロセス毎に隔離し、複数の仮想サーバを制御する仮想環境”
‘LXC は Linux カーネルの隔離機能に対するユーザ空間インターフェース。強力な API とシンプルなツールを用いて、簡単にシステムやアプリケーションのコンテナーを作成、管理できる。’ – LXC – Linux Containers
カーネル + パッチ + ユーザ空間ツール: OpenVZ, Linux VServer, etc
カーネル + ユーザ空間ツール: LXC, libvirt (LXC driver), systemd, etc

LXC、Docker 使用的内核功能和角色
内核名称空间 (命名空间)
将系统资源进行隔离,使其互不干扰。
uid
), グループ (group
)
参考: 操作中的命名空间,第1部分: 命名空间概述
控制组(cgroups)
-
- cgroups は LXC の一部として開発されている
-
- 前提知識
Linux のプロセスモデル
階層型. 子は親の環境 (PATH 変数とか), 属性 (オープンファイル記述子とか) を継承
単一のルートプロセス (init), init プロセスはブート時にカーネルが起動
タスク (プロセス) 毎にサブシステム (CPU, メモリ, ハードディスク等のリソース) の利用を制限する
異なる名前空間に cgroup を分離し、他のタスクからサブシステムを不可視にする
主要子系统
chroot(pivot_root)重命名当前根目录
-
- プロセスのルートディレクトリを変更する
移動すると、その範囲外のファイルへアクセスできなくなる
初期状態はルートファイルシステムのルート
pivot_root は root ファイルシステムを変更する
Apparmor 和 SELinux 配置文件
为了实现强制访问控制(MAC)的安全机制
-
- AppArmor: プログラム (プログラム名ベース) 毎に、アクセス可能なファイルパスやソケットへの操作を明示的に指定し、それ以外の操作は禁止する
- SELinux: ユーザ=ロール, 全てのプロセス=ドメイン, 全てのリソース (ファイル, ソケットなど) =タイプというラベルを付け、ユーザがアクセス可能なドメイン、ドメインが操作可能なリソースを指定する めんどい \(^o^)/
Seccomp政策
-
- Secure computing mode の略
-
- プロセスをサンドボックス化し、プロセスのシステムコールをフィルタリング
-
- Berkley Packet Filter (BPF) がベース
- JIT がサポートされている
内核功能
-
- プロセスに対し、必要最小限の特権を与える
-
- UNIX システムは一般ユーザ権限, 特権 (root) の 2 種類のみ
-
- プロセスには様々な特権の割当てが必要。プロセスの不具合、攻撃で乗っ取られたら終了
特権ポート (1024 番ポート以下) の割り当て
raw ソケットをオープン
システム時刻制御
特権をケーパビリティという単位で細分化し、必要最小限の特権をプロセスに割り当てる
ケーパビリティ一覧
LXC和Docker之间的关系
- Docker <= 0.8 は LXC (や libvirt, systemd-nspawn) 経由で名前空間, cgroups 等を利用していた Docker >= 0.9 は libcontainer ドライバ経由 (DOCKER 0.9: INTRODUCING EXECUTION DRIVERS AND LIBCONTAINER)

libcontainer がデフォ、lxc を使う場合は -e lxc とオプションで指定する
追加信息
- はてブで “自動ビルド” について言及されていますが、これは Dockerfile に make, apt 等のコマンドが書けて docker build さえすればエンジンが勝手にビルド実行してくれますよって話だと解釈しました