LXD 2.0: 最初のLXDコンテナ [3/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/19/lxd-2-0-your-first-lxd-container-312/

この文書のライセンスは原文と同じく、[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コンテナを管理するための数多くのコマンドを紹介しているため、この投稿はかなり長くなっています。より短い手順のガイドツアーが必要な場合は、[オンラインのデモページ](https://linuxcontainers.org/ja/lxd/try-it/)を参照してください！


## 新しいコンテナの作成と起動

以前の投稿でも言及したように、LXDのコマンドラインツールには最初からいくつかのイメージソースが設定されています。Ubuntuはそのすべてのリリースとアーキテクチャーの公式イメージを網羅していますし、他のディストリビューションもいくつもの非公式イメージがあります。LXCのアップストリームコントリビューターによって、コミュニティが作成・維持しています。

### Ubuntu

Ubuntuのサポート期間にある最新のリリースが欲しい場合は、次のように実行するだけです：

```
lxc launch ubuntu:
```

これはUbuntuの新しいLTSがリリースされたら、起動するものも変わってしまいます。スクリプトで使う場合は、（後述するように）明示的にリリースを指定するようにしましょう。


### Ubuntu 14.04 LTS

Ubuntu 14.04 LTSの最新かつテスト済みの安定版イメージが欲しい場合は、次のように実行します：

```
lxc launch ubuntu:14.04
```

この場合、ランダムなコンテナ名が設定されます。コンテナ名を指定したい場合は、次のように実行してください：

```
lxc launch ubuntu:14.04 c1
```

アーキテクチャを指定したい場合は、たとえばIntelの32bitイメージを起動したい場合は、次のように実行します：

```
lxc launch ubuntu:14.04/i386 c2
```

### Ubuntuの開発版イメージ

「`ubuntu:`」リモートサーバーは、公式の試験済みUbuntuイメージのみを提供します。開発版リリースのように、試験されていないデイリービルドが欲しい場合は、「`ubuntu-daily:`」リモートサーバーを使用してください。

```
lxc launch ubuntu-daily:devel c3
```

この場合、Ubuntuの開発版の最新リリースを自動的に取得します。

明示的に指定したいなら、たとえばコードネームを使うことができます：

```
lxc launch ubuntu-daily:xenial c4
```

### 最新のAlpine Linux

「`images:`」リモートサーバーでは、Alpineイメージを指定できます：

```
lxc launch images:alpine/3.3/amd64 c5
```

### その他のイメージ

取得可能なすべてのUbuntuイメージを表示したい場合は、次のコマンドを実行してください：

```
lxc image list ubuntu:
lxc image list ubuntu-daily:
```

非公式のイメージであれば、次のコマンドでリストアップします：

```
lxc image list images:
```

リモートサーバーが提供するエイリアス（よりわかりやすい名前）のリストは、（たとえば「`ubuntu:`」リモートサーバーであれば）次のように取得できます：

```
lxc image alias list ubuntu:
```


## コンテナを開始することなく作成するには

単一ないし複数のコンテナをただ作成し、すぐには起動したくない場合、「`lxc lauhch`」の代わりに「`lxc init`」を使用します。オプションはすべて同じで、コンテナを作成したあとに起動するかどうかのみ異なります。

```
lxc init ubuntu:
```

## コンテナの情報を取得する

### コンテナのリスト

すべてのコンテナをリストアップするには、次のコマンドを実行します：

```
lxc list
```

表示される情報に関して、いくつもオプションが存在します。システム上に数多くのコンテナが存在する場合、標準のフォーマットだと（個々のコンテナからネットワーク情報を取得するため）若干遅いかもしれません。その場合は、次のオプションを指定してください：

```
lxc list --fast
```

これによりサーバーサイドで必要な処理を減らすように表示する項目が変更されます。

名前やプロパティによってフィルタリングもできます：

```
stgraber@dakara:~$ lxc list security.privileged=true
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| NAME |  STATE  |        IPV4         |                       IPV6                    |    TYPE    | SNAPSHOTS |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| suse | RUNNING | 172.17.0.105 (eth0) | 2607:f2c0:f00f:2700:216:3eff:fef2:aff4 (eth0) | PERSISTENT | 0         |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
```

上記の場合、特権コンテナ（ユーザー名前空間を無効化したコンテナ）のみをリストアップします。

```
stgraber@dakara:~$ lxc list --fast alpine
+-------------+---------+--------------+----------------------+----------+------------+
|    NAME     |  STATE  | ARCHITECTURE |      CREATED AT      | PROFILES |    TYPE    |
+-------------+---------+--------------+----------------------+----------+------------+
| alpine      | RUNNING | x86_64       | 2016/03/20 02:11 UTC | default  | PERSISTENT |
+-------------+---------+--------------+----------------------+----------+------------+
| alpine-edge | RUNNING | x86_64       | 2016/03/20 02:19 UTC | default  | PERSISTENT |
+-------------+---------+--------------+----------------------+----------+------------+
```

上記の場合、名前に「`alpine`」があるコンテナのみを表示します（複雑な正規表現もサポートしています）。


### コンテナの詳細情報を取得するには

`list`コマンドは可読性を高めるため、コンテナのすべての情報を表示するわけではありません。個々のコンテナに関しては、次のように実行すると情報を取得できます：

```
lxc info <container>
```

たとえば次のような結果になります：

```
stgraber@dakara:~$ lxc info zerotier
Name: zerotier
Architecture: x86_64
Created: 2016/02/20 20:01 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 31715
Processes: 32
Ips:
 eth0: inet 172.17.0.101
 eth0: inet6 2607:f2c0:f00f:2700:216:3eff:feec:65a8
 eth0: inet6 fe80::216:3eff:feec:65a8
 lo: inet 127.0.0.1
 lo: inet6 ::1
 lxcbr0: inet 10.0.3.1
 lxcbr0: inet6 fe80::c0a4:ceff:fe52:4d51
 zt0: inet 29.17.181.59
 zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
 zt0: inet6 fe80::79:e7ff:fe0d:5123
Snapshots:
 zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)
```

## 管理コマンドのライフサイクル

ここで紹介するコマンドは、どんなコンテナや仮想マシンの管理システムでも当たり前のコマンドではありますが、それでも紹介しておく必要があるでしょう。

あと、これらのコマンドはすべて、バッチ操作のために複数のコンテナ名を指定できます。

### start

コンテナを起動するには次のように実行するだけです：

```
lxc start <container>
```

### stop

次のコマンドでコンテナを停止できます：

```
lxc stop <container>
```

コンテナを操作できないとき（SIGPWRに反応がないとき）は、強制的に終了します：

```
lxc stop <container> --force
```

### restart

コンテナの再起動は次のように実行します：

```
lxc restart <container>
```

コンテナを操作できないとき（SIGPWRに反応がないとき）は、強制的に再起動します：

```
lxc restart <container> --force
```

### pause

コンテナを一時停止（pause）できます。この場合、コンテナのすべてのタスクはSIGSTOPが送られたのと同じ状態になり、タスクは存在し、メモリーは消費するものの、スケジューラーによってCPU時間を割り当てられることはないという状態になります。

これはCPUを消費し、起動にも時間がかかるものの、常に使うわけではないコンテナを使用する際に便利です。とりあえず起動し、一時停止しておき、必要になれば再度起動すればいいだけです。

```
lxc pause <container>
```

### delete

最後に、コンテナが不要になったら次のコマンドで削除できます：

```
lxc delete <container>
```

コンテナが動作中の場合は「`--force`」オプションを渡す必要があります。


## コンテナの設定

LXDにはリソースの制限やコンテナ起動の操作、デバイスのパススルーなどいくつかのコンテナ設定が存在します。すべての設定はこの投稿ではカバーしきれないほど多いので、[こちらのドキュメント](https://github.com/lxc/lxd/blob/master/doc/configuration.md)を参照してください。

デバイスに限定して言うと、LXDは現在、以下のデバイスタイプをサポートしています：

<dl>
<dt>disk</dt>
<dd>コンテナにマウントされる物理的なディスクやパーティション、バインドマウントされるホスト上のパスを表します。</dd>
<dt>nic</dt>
<dd>ネットワークインターフェースです。ブリッジされた仮想イーサネットインターフェースやPPPデバイス、イーサネットのMAC VLAN、コンテナにパススルーされた実際の物理インターフェースなどを表します。</dd>
<dt>unix-block</dt>
<dd><samp>/dev/sda</samp>などのunixブロックデバイスを表します。</dd>
<dt>unix-char</dt>
<dd><samp>/dev/kvm</samp>などのunixキャラクターデバイスを表します。</dd>
<dt>none</dt>
<dd>プロファイルから継承したものの、隠したいデバイスに指定する特別なデバイスタイプです。</dd>
</dl>

### 設定プロファイル

すべての利用可能なプロファイルを取得するには次のように実行します：

```
lxc profile list
```

特定のプロファイルの内容を確認したい場合は次のように実行します：

```
lxc profile show <profile>
```

プロファイルの内容を変更したい場合は、次のコマンドを使います：

```
lxc profile edit <profile>
```

指定したコンテナにプロファイルのセットを一度に適用できます：

```
lxc profile apply <container> <profile1>,<profile2>,<profile3>,...
```

### ローカルな設定

あるコンテナ特有の設定で、プロファイルに記述したくないような設定については、コンテナに対して直接変更を行えます：

```
lxc config edit <container>
```

これは前述の「`profile edit`」と同じ振る舞いをします。

テキストエディターで全体を編集する代わりに、特定のキーのみを編集することも可能です：

```
lxc config set <container> <key> <value>
```

たとえばデバイスを追加するなら次のように記述します：

```
lxc config device add my-container kvm unix-char path=/dev/kvm
```

これは「`my-container`」という名前のコンテナに`/dev/kvm`エントリを追加します。

「`lxc profile set`」や「`lxc profile device add`」を使ったプロファイルでも同様の設定ができます。


### 設定の読み込み

コンテナローカルの設定は次のように確認できます：

```
lxc config show <container>
```

すべてのプロファイルキーを含む設定を展開する場合は次のように実行します：

```
lxc config show --expanded <container>
```

実行例は以下のとおりです：

```
stgraber@dakara:~$ lxc config show --expanded zerotier
name: zerotier
profiles:
- default
config:
 security.nesting: "true"
 user.a: b
 volatile.base_image: a49d26ce5808075f5175bf31f5cb90561f5023dcd408da8ac5e834096d46b2d8
 volatile.eth0.hwaddr: 00:16:3e:ec:65:a8
 volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
devices:
 eth0:
  name: eth0
  nictype: macvlan
  parent: eth0
  type: nic
  limits.ingress: 10Mbit
  limits.egress: 10Mbit
 root:
  path: /
  size: 30GB
  type: disk
 tun:
  path: /dev/net/tun
  type: unix-char
ephemeral: false
```

コンテナに何が適用されているかは、この方法で確認できます。


### 動的な設定の更新

このドキュメントではここまで説明していませんでしたが、すべての設定キーとデバイスエントリーは、動作中のコンテナにも適用できます。つまり、動作中のコンテナに対して再起動することなくデバイスを追加・削除したりセキュリティプロファイルを変更できるのです。


## シェルの実行

LXDは、直接コンテナに対して何かタスクを実行させることができます。よくあるのは、コンテナの中でシェルを起動したり、何か管理者権限が必要なタスクを実行させたい場合でしょう。

SSHログインする方法と比較すると、この方法はコンテナがネットワーク的に到達可能かどうかや、コンテナの中のソフトウェアや設定に依存せずに使えるということです。


### 実行環境

LXD経由でのコンテナに対するコマンドの実行が通常と異なる点の一つは、コマンド自身がコンテナの中で実行されるわけではないということです。つまりどのシェルを使うか、どんな環境変数が設定されているか、ホームディレクトリのパスはどこかということを知る術がないということです。

LXD経由で実行されるコマンドはすべて、環境変数`PATH`は最低限の値だけ設定し、`HOME`が`/root`に設定されたコンテナの管理者権限（UID 0、GID 0）で実行されます。

追加で環境変数を設定したい場合は、コマンドライン経由で渡すか、「`environment.<key>`」設定を用いてコンテナに恒久的に設定してください。

### コマンドの実行

コンテナの中でシェルを実行するには、次のように入力します：

```
lxc exec <container> bash
```

コンテナの中にはbashがインストールされていると仮定しています。

より複雑なコマンドを実行する場合、適切に引数を解釈させるために次のように実行する必要があります：

```
lxc exec <container> -- ls -lh /
```

環境変数を上書きする場合は、「`--env`」引数を使うことができます：

```
stgraber@dakara:~$ lxc exec zerotier --env mykey=myvalue env | grep mykey
mykey=myvalue
```

## ファイルの管理

LXDは直接コンテナのファイルシステムにアクセスするため、コンテナの中のあらゆるファイルを直接読み書きできます。これはコンテナのログを取り出したり、ファイルを変更する場合に便利です。

### コンテナからファイルを取り出す

コンテナからファイルを取り出す場合、次のように実行します：

```
lxc file pull <container>/<path> <dest>
```

`zerotier`コンテナの`/etc/hosts`を取り出している例です：

```
stgraber@dakara:~$ lxc file pull zerotier/etc/hosts hosts
```

標準出力に渡すこともできます：

```
stgraber@dakara:~$ lxc file pull zerotier/etc/hosts -
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
```

### コンテナにファイルを送る

ファイルの送信も単純です：

```
lxc file push <source> <container>/<path>
```

### ファイルを直接編集する

`edit`は、指定したパスのファイルを取り出し、既定のテキストエディターで開き、その編集結果をコンテナの中に反映する場合に便利な機能です：

```
lxc file edit <container>/<path>
```

## スナップショットの管理

LXDではコンテナのスナップショットの作成や復元ができます。スナップショットにはコンテナのすべての状態（「`--stateful`」を指定すれば起動している状態）、コンテナの設定やデバイス、ファイルシステムなどを保存できます。

### スナップショットの作成

コンテナのスナップショットは次のように作成します：

```
lxc snapshot <container>
```

ここでスナップショットは「snapX」という名前になります。Xは自動的に増加する番号です。

明示的に名前を指定したい場合は次のように実行します：

```
lxc snapshot <container> <snapshot name>
```

### スナップショットのリストアップ

あるコンテナのスナップショットの数は「`lxc list`」で表示されます。しかしながらスナップショットそのもののリストが必要な場合は「`lxc info`」を使う必要があります。

```
lxc info <container>
```

### スナップショットの復元

スナップショットから復元したい場合は、次のように実行します：

```
lxc restore <container> <snapshot name>
```

### スナップショットの名前変更

スナップショットを移動することで名前を変更できます：

```
lxc move <container>/<snapshot name> <container>/<new snapshot name>
```

### スナップショットから新しいコンテナの作成

あるコンテナのスナップショットと同一の新しいコンテナを作成できます。ただし一時的な情報（MACアドレスなど）はリセットされます：

```
lxc copy <source container>/<snapshot name> <destination container>
```

### スナップショットの削除：

最後にスナップショットを削除する方法です：

```
lxc delete <container>/<snapshot name>
```

## 複製と名前の変更

クリーンなディストリビューションイメージの取得は便利ですが、たまにコンテナに数多くのパッケージをインストールし、設定した上で、そのコンテナを別のコンテナへと複製したいこともあるでしょう。

### コンテナの複製

コンテナを別のコンテナにコピーすることで事実上の複製となります：

```
lxc copy <source container> <destination container>
```

コピー先のコンテナはコピー元のそれと基本的に同一ですが、スナップショットはなくなり、一時的な設定（MACアドレス）はリセットされます。

### コンテナの移動

LXDはホスト間でコンテナをコピーもしくは移動できます。これについては今度の投稿で紹介します。

今のところ、「`move`」コマンドによってコンテナの名前を変更できるということだけ紹介しておきましょう：

```
lxc move <old name> <new name>
```

必要なのはコンテナが停止しているということです。一時的な設定（MACアドレスなど）を含むすべての情報が維持されたまま移動します。


## まとめ

このちょっとばかり長い投稿では、日々の操作で使うであろうコマンドのほとんどを網羅しました。

これらのコマンドのほとんどは、LXDのコンテナをより効率的かつ細かく調整できるよう、追加のオプションを用意しています。それらすべての情報を学ぶなら、「`--help`」オプションで内容を把握することが一番でしょう。


## その他の情報

* 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とそのガイドツアーを体験できます。