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_architecture.png

LXC、Docker 使用的内核功能和角色

内核名称空间 (命名空间)

将系统资源进行隔离,使其互不干扰。

名前空間>= バージョン隔離対象Mount2.4.19ファイルシステムUTS2.6.19ホスト名, NIS ドメイン名IPC2.6.19プロセス間通信, POSIX メッセージキューPID2.6.24プロセスID, コンテナが違えば同一 ID 可Network(2.6.24) 2.6.29ネットワークデバイス, IP アドレス, IP テーブル等User(2.6.23) 3.8ユーザ (uid), グループ (group)
Linux_kernel_map.png

参考: 操作中的命名空间,第1部分: 命名空间概述

控制组(cgroups)

    • cgroups は LXC の一部として開発されている

 

    • 前提知識

Linux のプロセスモデル
階層型. 子は親の環境 (PATH 変数とか), 属性 (オープンファイル記述子とか) を継承
単一のルートプロセス (init), init プロセスはブート時にカーネルが起動

タスク (プロセス) 毎にサブシステム (CPU, メモリ, ハードディスク等のリソース) の利用を制限する
異なる名前空間に cgroup を分離し、他のタスクからサブシステムを不可視にする

主要子系统

サブシステム機能blkioブロックデバイスの入出力アクセスを制御 (Read <= N bytes/sec)cpuスケジューラにより CPU のアクセスを制御cpusetマルチコアの場合に利用する CPU, メモリノードを制御devicesデバイスへのアクセス制御freezer処理の一時停止, 再開memoryメモリリソースの制御hugetlbN byteまでとかの制限net_clsLinux トラフィックコントローラ (tc) がパケットを識別できるよう, クラス識別子 (classid) によりネットワークパケットにタグをつけるnet_prioNIC 別にトラフィックのプライオリティを設定するns名前空間を制御 (Linux 3.0 で廃止)@tenforward さんご指摘ありがとうございます。

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)
docker-execdriver-diagram.png

libcontainer がデフォ、lxc を使う場合は -e lxc とオプションで指定する

追加信息

    はてブで “自動ビルド” について言及されていますが、これは Dockerfile に make, apt 等のコマンドが書けて docker build さえすればエンジンが勝手にビルド実行してくれますよって話だと解釈しました
广告
将在 10 秒后关闭
bannerAds