LoginSignup
2
2

More than 5 years have passed since last update.

LXD 2.0: リモートホストとコンテナマイグレーション [6/12]

Last updated at Posted at 2016-04-17

この文書について

この文書は、連載記事「LXD 2.0: Blog post series」(日本語版目次)の一つである以下の記事を翻訳したものです。

この文書のライセンスは原文と同じく、Creative Commons BY-NC-SA 2.5のもとに提供されています。

CC-BY-NC-SA 2.5


リモートプロトコル

LXD 2.0は次のふたつのプロトコルをサポートしています:

  • LXD 1.0 API: クライアントとLXDデーモン間で使われるREST APIです。同様にLXDデーモン同士でもイメージやコンテナのコピーや移動にも使います。
  • Simplestreams: Simplestreamsプロトコルは読み込み専用、イメージ専用のプロトコルで、LXDクライアントとデーモンの双方が(Ubuntuイメージのような)パブリックなイメージサーバーからイメージ情報の取得やイメージのインポートを行う際に使用します。

以下の説明はすべて、これらのうち前者に関連します。

セキュリティ

LXD APIによる認証は、最新の暗号化技術を用いたTLS 1.2越しのクライアント証明書の認証によって行われます。二つのLXDデーモンが直接情報をやりとりする際は、最初にソースとなるデーモンが一時的なトークンを生成し、クライアント越しにターゲットのデーモンへ送られます。そのトークンはその場のストリームでのみ使われ、即座に破棄し、再利用はできません。

中間者攻撃を回避するために、クライアントツールはソースサーバーの証明書をターゲットにも送ります。つまり、特定のダウンロード操作においては、ターゲットサーバーに送信側サーバーのURL、そのリソースに必要なワンタイムのアクセストークン、そのサーバーが使うであろう証明書が提供されます。この方法は中間者攻撃を防ぎ、送信者のオブジェクトの一時的なアクセスのみを与えます。

必要なネットワーク

LXD 2.0は操作のターゲット側(データの受信側)が直に送信側に接続し、データを取得するモデルを採用しています。

これはターゲットサーバーが、ファイヤーウォールなどを越えて、直に送信サーバーに接続できなくてはならないことを意味します。

厳しいファイヤウォールによってホスト間の通信ができない時のために、逆方向の接続やプロキシ越しの接続のサポートも計画しています

リモートホストへの接続

リモートホストを使いたいユーザーが常にホストネームやIPアドレスを把握し、正しいリモートホストに接続しようとしているか検証する手間を省くために、LXDは「リモート」という概念を導入してます。

初期状態ではLXDは「local:」リモートのみが設定されています。これは常に規定の(名前を省略した時の)リモートとして使われます。このローカルリモートは、LXD REST APIを使ってunixソケット越しにローカルのデーモンと通信します。

リモートの追加

LXDがインストールされた二つのマシンがあるとします。一つはローカルのマシンで、リモートホストの方は「foo」と呼ぶことにしましょう。

最初に、「foo」をリッスン状態にし、パスワードを設定する必要があります。リモートのシェルで次のコマンドを実行してください:

lxc config set core.https_address [::]:8443
lxc config set core.trust_password 何かパスワード

次にローカルのLXDでも、そこからコンテナやイメージを送信できるように、ネットワークに対して見えるように設定する必要があります:

lxc config set core.https_address [::]:8443

両方のデーモンの設定が完了しました。これで「foo」をローカルのクライアントに追加できます:

lxc remote add foo 1.2.3.4

(ここで1.2.3.4は、IPアドレスかFQDNに変更してください)

次のような感じで表示されることでしょう:

stgraber@dakara:~$ lxc remote add foo 2607:f2c0:f00f:2770:216:3eff:fee1:bd67
Certificate fingerprint: fdb06d909b77a5311d7437cabb6c203374462b907f3923cefc91dd5fce8d7b60
ok (y/n)? y
Admin password for foo:
Client certificate stored at server: foo

リモートのリストを表示したら、「foo」が追加されていることでしょう:

stgraber@dakara:~$ lxc remote list
+-----------------+-------------------------------------------------------+---------------+--------+--------+
|      NAME       |                         URL                           |   PROTOCOL    | PUBLIC | STATIC |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| foo             | https://[2607:f2c0:f00f:2770:216:3eff:fee1:bd67]:8443 | lxd           | NO     | NO     |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| images          | https://images.linuxcontainers.org:8443               | lxd           | YES    | NO     |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| local (default) | unix://                                               | lxd           | NO     | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases              | simplestreams | YES    | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily                 | simplestreams | YES    | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+

リモートとの通信

さて、リモートサーバーを設定しました。これで何ができるようになるのでしょうか?

これまでの投稿で説明したことはすべてできます。唯一異なるのは、LXDに対してどのホストで実行するかを指定することです。

たとえば次のようなコマンドがあるとします:

lxc launch ubuntu:14.04 c1

上記は規定のリモート(lxc remote get-default)で実行されるので、ローカルのホストに対して適用されることでしょう。

lxc launch ubuntu:14.04 foo:c1

上記は、その代わりfoo上でコマンドを実行します。

リモートホスト上の実行中のコンテナを確認したい場合は、次のようになります:

stgraber@dakara:~$ lxc list foo:
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| NAME |  STATE  |         IPV4        |                     IPV6                      |    TYPE    | SNAPSHOTS |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| c1   | RUNNING | 10.245.81.95 (eth0) | 2607:f2c0:f00f:2770:216:3eff:fe43:7994 (eth0) | PERSISTENT | 0         |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+

一つ注意しなくてはならないのは、イメージとコンテナの双方にリモートを指定しなくてはならないということです。「foo」上に「my-image」という名前のローカルイメージが存在し、そのイメージから「c2」という名前のコンテナを作りたいときは、次のように指定しなくてはなりません:

lxc launch foo:my-image foo:c2

最後に、リモートコンテナへのシェルの実行も、期待通り動作します:

lxc exec foo:c1 bash

コンテナのコピー

ホスト間のコンテナのコピーはとても簡単です:

lxc copy foo:c1 c2

これによりリモートの「c1」コンテナのコピーがローカルの「c2」コンテナとして作成されます。「c1」コンテナはまず停止している必要があります。ただしスナップショットをコピーすることで、コピー元のコンテナを停止せず実行中のままコピーできます:

lxc snapshot foo:c1 current
lxc copy foo:c1/current c3

コンテナの移動

ライブマイグレーション(別の投稿で説明する予定です)をするのでなければ、コンテナを移動する前にそれを停止している必要があります。それ以外は、予想通りの動作になるはずです:

lxc stop foo:c1
lxc move foo:c1 local:

上記の例は以下と同じ動作です:

lxc stop foo:c1
lxc move foo:c1 c1

どのように操作しているのか

リモートコンテナの操作は、想像通りの動きをすることでしょう。LXDは、ローカルのunixソケットに対するREST APIを使うのではなく、同じAPIをHTTPS経由のリモートに対して呼び出しています。

コピーや移動など、二つのデーモン間でやり取りを行う場合、もう少し複雑な処理を行っています。

上記の場合は、次のような処理を行います:

  1. 利用者は「lxc move foo:c1 c1」を実行します。
  2. クライアントはlocal:リモートに「c1」コンテナが存在するかどうか確認します。
  3. クライアントは「foo」の情報を取得します。
  4. クライアントは移動元となる「foo」デーモンに対してマイグレーショントークンを要求します。
  5. クライアントは移動元のURLと「foo」の証明書と同じくマイグレーショントークン、コンテナとデバイスの設定一緒にローカルのLXDデーモンに送ります。
  6. ローカルのLXDデーモンは与えられたトークンを用いて直接「foo」に接続します。

    1. 最初にコントロールWebSocketに接続します。
    2. ファイルシステムの転送プロトコル(zfsのsend/receiveやbtrfsのsend/receive、もしくは単純なrsync)とネゴシエーションします。
    3. もしローカルに存在すれば、移動元のコンテナを作るために使われたイメージを展開します。これにより不要なデータ転送を抑制します。
    4. コンテナと、その差分のスナップショットなどを転送します。
  7. 成功したら、クライアントは移動元のコンテナの削除を「foo」に伝えます。

オンラインで試してみる

リモートの操作やコンテナの移動・コピーのための複数のマシンを持っていますでしょうか?

持っていないのなら、オンラインのデモサービスで、この機能を試すことができます。ここで説明している内容を手順に沿って説明しています!

その他の情報

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2