LXD 2.0: LXDについて [1/12]

## この文書について

この文書は、連載記事「[LXD 2.0: Blog post series](https://www.stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/)」（[日本語版目次](http://qiita.com/m-shibata/items/029b19d90af2a79116c2)）の一つである以下の記事を翻訳したものです。

* https://www.stgraber.org/2016/03/11/lxd-2-0-introduction-to-lxd-112/

この文書のライセンスは原文と同じく、[Creative Commons BY-NC-SA 2.5](http://creativecommons.org/licenses/by-nc-sa/2.5/)のもとに提供されています。

![CC-BY-NC-SA 2.5](http://i.creativecommons.org/l/by-nc-sa/2.5/88x31.png)

---------


## LXDについてよくあるいくつかの質問

### LXDとは？

簡単に言うと、LXDはLXCコンテナを操作するためのREST APIを提供するデーモンです。

その主な目的は、Linuxコンテナ使用時にもハードウェア仮想化における仮想マシンの利用と同等のユーザー体験をもたらすことです。


### Docker/RktとLXDの関係は？

これは最も問われる質問ですので、今すぐ説明することにしましょう！

LXDはシステムコンテナに注力しています。これはインフラストラクチャーコンテナとも呼ばれます。つまりLXDコンテナは、物理マシンやVM上で起動するのと同様に完全なLinuxシステムを起動するのです。

これらのコンテナはクリーンなディストリビューションイメージをベースに、長時間動作しつづけるという特徴を持っています。VMやクラウドインスタンス、物理マシンで使っていた伝統的な構成管理ツールやデプロイツールを、まさにそのままLXDコンテナでも利用できます。

それに対して、Dockerは一時的でステートレスで小さなコンテナに注力しています。とりわけアップグレードや再設定を行わず、単純にすべてを置き換えるようなコンテナです。このためDockerやそれに類似するプロジェクトは、マシン管理ツールというよりはソフトウェア配布メカニズムにより近いものになっています。

この二つのモデルは相互に排他的なものではありません。ユーザーに完全なLinuxシステムを提供するためにLXDを使用し、ユーザーはそのLXDコンテナの中で必要なソフトウェアを実行するためにDockerを利用することもできるのです。

### なぜLXDなのか？

私たちは数年の間LXCで作業を行ってきました。LXCは、コンテナを作成・管理する低レベルのツールやライブラリとして十分な機能を提供していました。

しかしながら、低レベルのツールは必ずしもユーザーフレンドリーであるとは限りません。それが何を行い、どのように動作するかをあらかじめ理解しておくべき知識がたくさん存在します。古いコンテナやデプロイ方法との後方互換性を維持するために、いくつかのセキュリティ機能を初期状態では無効にし、ユーザーの手動設定が必要になることもありました。

LXDはこれらの問題点を解決する可能性があると考えています。長く動作するデーモンが、動的なリソース制約、コンテナのマイグレーション、効率的なライブマイグレーションといったLXCの制約を解決してくれます。より安全でユーザー重視の新しい初期設定ももたらすことでしょう。


## LXDの主な要素

LXDを形成する主要な要素が存在し、これらはLXDのディレクトリ構造やクライアントのコマンドライン、API構造の中に現れます。


### コンテナ

LXDのコンテナは以下の要素から成り立っています：

* ファイルシステム（rootfs）
* リソース制限や環境、セキュリティオプションなどの設定オプション
* ディスク、キャラクタデバイス、ブロックデバイス、ネットワークインターフェースのようなデバイス一式
* 設定を継承するコンテナのプロファイルセット（後述します）
* いくつかのプロパティ（コンテナアーキテクチャ、一時的か恒久か、コンテナ名）
* いくつかの実行時の状態（チェックポイント・リストアのCRIUで使用します）


### スナップショット

コンテナのスナップショットは、それが不変であり、名前の変更や破棄、リストアが可能であること以外は普通のコンテナと意味的には同じです。しかしながら、内容を変更することはできません。

注目すべきはコンテナの実行時の状態を保存できることでしょう。これは「ステートフル」なスナップショットの概念を提供します。つまり、スナップショット作成時のCPUやメモリの状態も含めてコンテナのロールバックを行えるということです。


### イメージ

LXDはイメージベースで、すべてのLXDコンテナはイメージから作成します。イメージは仮想マシンやクラウドインスタンスで利用しているものに似た、Linuxディストリビューションのイメージファイルのようなものです。

コンテナを「公開」することも可能です。そのコンテナからイメージを、作成しローカルないしリモートのLXDホストで使用できるのです。

イメージには、sha256ハッシュで生成した一意の識別子を持っており、その識別子やその一部を使って参照できます。長いハッシュを入力することはユーザーフレンドリーではないので、イメージはいくつものプロパティを付与することができ、これによりイメージストアで簡単にイメージを検索できます。ユーザーが識別しやすい文字列とイメージハッシュの1対1の対応をもったエイリアスを設定する異も可能です。

LXDは以下の三つのリモートイメージサーバー（後述の「リモート」を参照してください）をあらかじめ設定しています：

* 「ubuntu:」はUbuntuの安定版イメージを提供します
* 「ubuntu-daily:」はUbuntuのデイリービルドを提供します
* 「images:」はアップストリームのLXCテンプレートを用いて作成したその他のLinuxディストリビューションイメージを提供するコミュニティベースのイメージサーバーです

リモートイメージはLXDデーモンによって自動的にキャッシュされ、最後に取得してから数日（初期値は10日）の間は保持しています。

さらにLXDは、ローカルマシンに最新のイメージを保持するように、自動的にリモートのイメージを更新しています。


### プロファイル

プロファイルはコンテナの設定やデバイスをまとめて定義し、複数のコンテナに適用するための方法です。

一つのコンテナには複数のプロファイルを適用できます。最後のコンテナ設定を構築する時（設定の展開）、そのプロファイルは定義された順番に適用され、同じ設定項目やデバイスがあらわれた時は、上書きされます。ローカルのコンテナ設定が最後に適用され、プロファイルの値を上書きします。

LXDには最初から二つのプロファイルが用意されています：

* 「default」プロファイルは、ユーザーによって別のプロファイルリストが提供されない限りは、すべてのコンテナに自動的に適用されるプロファイルです。このプロファイルは現在のところ、コンテナの「eth0」ネットワークデバイスを定義するだけです。
* 「docker」プロファイルはDockerコンテナを許可したいコンテナに適用するためのプロファイルです。LXDはコンテナのネストのために、いくつかの必要なカーネルモジュールをロードし、いくつかのデバイスエントリをセットアップします。


### リモート

前にも説明したように、LXDはネットワークデーモンです。コマンドラインクライアントは、イメージサーバーと同じように複数のリモートのLXDサーバーと通信できます。

コマンドラインクライアントには以下のリモートサーバーがあらかじめ設定されています：

* 「local:」はunixソケット越しにローカルのLXDデーモンと通信する、既定のリモートサーバーです
* 「ubuntu:」はUbuntuの安定版イメージを提供するイメージサーバーです
* 「ubuntu-daily:」はUbuntuのデイリービルドイメージを提供するイメージサーバーです
* 「images:」はイメージサーバーであるimages.linuxcontainers.orgを指しています

コマンドラインクライアントでは、上記のリモートのあらゆる組み合わせを利用できます。

さらに外部ネットワークから待ち受けている他のリモートLXDホストも追加できます。パブリックイメージサーバーのように誰でも接続できるようなサーバーでも、リモートコンテナを管理するための認証が必要なサーバーでも追加できます。

このリモート機能により、リモートイメージサーバーとの通信と同じように、複数のホスト間でコンテナをコピーや移動を行えるのです。


## セキュリティ

LXDのデザインの重要な側面の一つは、特に修正することなくモダンなLinuxディストリビューションをなるべく安全に実行できるようにすることです。

LXDやLXCライブラリで使われている、主要なセキュリティ機能は次のとおりです：

* カーネルの「名前空間（namespace）」：特にユーザー名前空間は、システムの他の部分からコンテナのすべてを分離するために使われています。LXDでは（LXCとは逆に）標準でユーザー名前空間を使うようになっています。また不要な場合はコンテナ単位で無効化する（コンテナを「privileged」にする）ことも可能です。
* 「Seccomp」：いくつかの危険性のあるシステムコールをフィルタリングしています。
* 「AppAromr」：マウントやソケット、ptraceやファイルアクセスに関して、追加の制約を設けるために使用しています。特にコンテナ間の通信の制約に使っています。
* 「Capabilities」：コンテナによるカーネルモジュールのロードやホストシステムの時間変更などを防いでいます。
* 「CGroups」：リソースの使用を制限し、ホストに対するDoS攻撃を防いでいます。

LXCではこれらの機能をユーザーが直接設定できるようにしていたのに対して、LXDではよりユーザーフレンドリーになるようにこれらの設定を抽象化できる新しい設定言語を構築しました。例えば、LXDではあるホスト上のデバイスをコンテナからアクセスできるようにするために、そのデバイスのmajor/minor番号を検索し、cgroupポリシーを手動で更新する必要はありません。

LXD自身との通信には、利用できる暗号アルゴリズムをより制約したTLS 1.2を使って暗号化しています。システムの認証局にはないホストと通信する際は、LXDはリモートホストのフィンガープリント（SSHスタイル）を確認するようユーザーに表示します。その後は証明書をキャッシュして利用します。


## REST API

LXDはすべてそのREST API経由で処理を行います。クライアントデーモンの間に他の通信チャンネルは存在しません。

このREST APIはローカルのunixソケットを使用してアクセスできます。この時はグループに所属しているかどうかで認証します。もしくはクライアント証明書を使ったHTTPソケット経由のアクセスも可能です。

REST APIの構造は、上記で説明したコンポーネントの違いに一致します。つまりとても単純で直感的に利用できるということです。

より複雑な通信機構が必要になった場合、LXDはWebSocketの通信を開始し、以降はそちらで通信します。これは対話的なコンソールセッションやコンテナのマイグレーション、イベント通知で使われます。

LXD 2.0では、/1.0 の安定版APIを使用しています。/1.0 APIのエンドポイントに対して後方互換性を壊すような変更は加えませんが、いくつかの機能を追加するかもしれません。追加のAPI拡張の定義に対して、クライアントが把握できるようなシグナルを送る予定です。


## コンテナのスケール

LXDのコマンドラインクライアントはよく出来ていますが、複数のホストの数千のコンテナを管理するには向いていません。そのように利用するためにOpenStackプラグインであるnova-lxdを用意しています。これは、VMを扱うのと同じ方法でLXDコンテナを利用できるOpenStack用のプラグインです。

これにより数多くのホストに対して、数多くのLXDをデプロイし、OpenStack API経由のネットワークやストレージ、ロードバランサーの管理を行えます。


## その他の情報

* LXDのウェブサイト：[https://linuxcontainers.org/ja/lxd/](https://linuxcontainers.org/ja/lxd/)
* 開発はGitHub上で行なっています：[https://github.com/lxc/lxd](https://github.com/lxc/lxd)
* メーリングリスト：[https://lists.linuxcontainers.org](https://lists.linuxcontainers.org)
* IRCチャンネル：#lxcontainers on irc.freenode.net

もし他の投稿を待ちきれず、LXDを試してみたいのであれば、[オンラインのデモページ](https://linuxcontainers.org/ja/lxd/try-it/)からLXDとそのガイドツアーを体験できます。