LXD

LXD

LXD は次世代のシステムコンテナーおよび仮想マシンのマネージャーです。 コンテナーあるいは仮想マシンの内部で稼働する完全な Linux システムに対して統一されたユーザーエクスペリエンスを提供します。

いろいろな Linux ディストリビューション のあらかじめビルドされたイメージを使ったイメージベースのマネージャーであり、非常に強力でありながら、非常にシンプルに、REST API を使って構築されます。

LXD がどういうものであり、何をするのかをよく理解するために、オンラインで試用 できます。
そして、ローカルで実行してみたい場合は、はじめに という文書をご覧ください。

リリースアナウンスはこちらでご覧になれます: https://linuxcontainers.org/lxd/news/
リリース tarball はこちらから取得できます: https://linuxcontainers.org/lxd/downloads/

ステータス

Type Service Status
CI (Linux) Jenkins Build Status
CI (macOS) Travis Build Status
CI (Windows) AppVeyor Build Status
LXD documentation ReadTheDocs Read the Docs
Go documentation Godoc GoDoc
Static analysis GoReport Go Report Card
Translations Weblate Translation status
Project status CII Best Practices CII Best Practices

LXD のパッケージからのインストール

LXD デーモンは Linux でしか動きませんが、クライアントツール (lxc) はほとんどのプラットフォームで動作します。

OS 形式 コマンド
Linux Snap snap install lxd
Windows Chocolatey choco install lxc
MacOS Homebrew brew install lxc

さまざまな Linux ディストリビューションとオペレーティングシステムで LXD をインストールするためのより詳細な方法は、公式サイト をご覧ください。

LXD のソースからのインストール

LXD の開発には liblxc の最新バージョン(3.0.0 以上が必要)を使用することをおすすめします。 さらに LXD が動作するためには Golang 1.13 以上が必要です。 Ubuntu では次のようにインストールできます:

sudo apt update
sudo apt install acl autoconf dnsmasq-base git golang libacl1-dev libcap-dev liblxc1 liblxc-dev libtool libudev-dev libuv1-dev make pkg-config rsync squashfs-tools tar tcl xz-utils ebtables

LXC を自分でビルドする場合は、テストスイートがテストする、関連する適切なセキュリティ関連のライブラリーがインストールされていることを確認してください。 Ubuntu であれば次のようにインストールできます:

sudo apt install libapparmor-dev libseccomp-dev libcap-dev

デフォルトのストレージバックエンドである "directory" に加えて、LXD ではいくつかのストレージバックエンドが使えます。 これらのツールをインストールすると、initramfs への追加が行われ、ホストのブートが少しだけ遅くなるかもしれませんが、特定のバックエンドを使いたい場合には必要です:

sudo apt install lvm2 thin-provisioning-tools
sudo apt install btrfs-tools

テストスイートを実行するには、次のパッケージも必要です:

sudo apt install curl gettext jq sqlite3 uuid-runtime bzr socat

ソースからの最新版のビルド

この方法は LXD の最新版をビルドしたい開発者や Linux ディストリビューションで提供されない LXD の特定のリリースをビルドするためのものです。 Linux ディストリビューションへ統合するためのソースからのビルドはここでは説明しません。それは将来別のドキュメントで取り扱うかもしれません。

ソースからビルドする際は、ビルド対象のソースコードを含む GOPATH をカスタムで設定します。ソースをビルドしたら lxclxd の実行ファイルが $GOPATH/bin に生成され、あとは LD_LIBRARY_PATH を設定(後述)するだけで、これらの実行ファイルがビルドされたソースツリーから直接実行できます。

以下に GitHub の LXD のソースの最新版に対して GOPATH を設定する手順を示します。

mkdir -p ~/go
export GOPATH=~/go
go get -d -v github.com/lxc/lxd/lxd
cd $GOPATH/src/github.com/lxc/lxd

ビルドプロセスが開始したら、 Makefile は go getgit clean を使ってビルドに必要な全ての依存ライブラリーを取得します。

ソースからのリリース版のビルド

LXD の公式リリースをビルドするには、リリース版の tarball をダウンロード、解凍し、その中の _dist ディレクトリを指すように GOPATH を設定してください。 _dist ディレクトリは GOPATH として使用できるように構成されており必要なソース全てのスナップショットを含んでいます。 LXD は live なソースを go getgit clone で取得する代わりにこれらのスナップショットを使ってビルドします。リリース版の tarball をダウンロード、解凍したら以下のように GOPATH を設定してください。

cd lxd-3.18
export GOPATH=$(pwd)/_dist

ビルドの開始

GOPATH を設定したら、以下の手順で GitHub の最新版あるいは公式リリース版の LXD をビルド出来ます。

実際のビルドは Makefile の 2 回の別々の実行により行われます。 1 つは make deps でこれは LXD に必要とされるライブラリーをビルドします。もう 1 つは make で LXD 自体をビルドします。 make deps の最後に make の実行に必要な環境変数を設定するための手順が表示されます。新しいバージョンの LXD がリリースされたらこれらの環境変数の設定は変わるかもしれませんので、 make deps の最後に表示された手順を使うようにしてください。下記の手順(例示のために表示します)はあなたがビルドする LXD のバージョンのものとは一致しないかもしれません。

make deps
# `make deps` が出力した export のコマンド列を使ってください。下記はあくまで例です。
export CGO_CFLAGS="${CGO_CFLAGS} -I${GOPATH}/deps/sqlite/ -I${GOPATH}/deps/dqlite/include/ -I${GOPATH}/deps/raft/include/ -I${GOPATH}/deps/libco/"
export CGO_LDFLAGS="${CGO_LDFLAGS} -L${GOPATH}/deps/sqlite/.libs/ -L${GOPATH}/deps/dqlite/.libs/ -L${GOPATH}/deps/raft/.libs -L${GOPATH}/deps/libco/"
export LD_LIBRARY_PATH="${GOPATH}/deps/sqlite/.libs/:${GOPATH}/deps/dqlite/.libs/:${GOPATH}/deps/raft/.libs:${GOPATH}/deps/libco/:${LD_LIBRARY_PATH}"
export CGO_LDFLAGS_ALLOW="-Wl,-wrap,pthread_create"
make

ソースからのビルド結果のインストール

ビルドが完了したら、ソースツリーを維持したまま、あなたのお使いのシェルのパスに $GOPATH/bin を追加し LD_LIBRARY_PATH 環境変数を make deps で表示された値に設定すれば、 LXD が利用できます。 ~/.bashrc ファイルの場合は以下のようになります。

# GOPATH は export する必要はありません。
GOPATH=~/go
# But we need to export these:
export PATH="$PATH:$GOPATH/bin"
export LD_LIBRARY_PATH="${GOPATH}/deps/sqlite/.libs/:${GOPATH}/deps/dqlite/.libs/:${GOPATH}/deps/raft/.libs:${GOPATH}/deps/libco/:${LD_LIBRARY_PATH}"

これで lxdlxc コマンドの実行ファイルが利用可能になり LXD をセットアップするのに使用できます。 LD_LIBRARY_PATH 環境変数のおかげで実行ファイルは $GOPATH/deps にビルドされた依存ライブラリーを自動的に見つけて使用します。

マシンセットアップ

LXD が非特権コンテナーを作成できるように、root ユーザーに対する sub{u,g}id の設定が必要です:

echo "root:1000000:65536" | sudo tee -a /etc/subuid /etc/subgid

これでデーモンを実行できます(sudo グループに属する全員が LXD とやりとりできるように --group sudo を指定します。別に指定したいグループを作ることもできます):

sudo -E PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH $GOPATH/bin/lxd --group sudo

セキュリティ

LXD は他のコンテナーおよびVMの管理システムと同様にローカル通信用に UNIX ソケットを提供します。

警告: このソケットにアクセスできる人は LXD を完全に制御できます。 これはホストのデバイスやファイルシステムにアタッチする能力も含みます。 ですので、ホストに root 権限でアクセスを許可するほどに信頼できる ユーザーだけにこのソケットを与えるようにすべきです。

ネットワークでリッスンする時、同じ API が TLS ソケット (HTTPS) 上で 利用可能です。リモート API の特定のアクセスは Canonical RBAC 経由で 制限することができます。

より詳細はこちらを参照してください.

LXD を使い始める

ここまでで、システム上で LXD が実行されているでしょうから、はじめに という文書を読んだり、ドキュメント日本語訳)の例や設定を見たりできます。

バグレポート

バグ報告はこちらから行えます: https://github.com/lxc/lxd/issues/new

コントリビュート

修正や新機能の追加は歓迎です。最初に contributing guidelines を読んでください。

サポートとディスカッション

フォーラム

ディスカッションフォーラムを使えます: https://discuss.linuxcontainers.org

メーリングリスト

開発者向けとユーザー向けのディスカッションに LXC のメーリングリストを使っています。次の URL から見つけられますし、購読もできます: https://lists.linuxcontainers.org

IRC

ライブのディスカッションがお好みなら、irc.freenode.net の #lxcontainers に参加している開発者もいます:

FAQ

LXD サーバにリモートからアクセスできるようにするには?

デフォルトでは、LXD サーバーはネットワークからのアクセスを許可せず、ローカルの unix ソケットのみで待ち受けます。 待ち受ける追加のアドレスを指定して、ネットワーク経由で利用できるように設定できます。 これには core.https_address を使用します。

現在のサーバーの設定を確認するには次のように実行します:

lxc config show

待ち受けるアドレスを設定するには、どのアドレスが使用できるかを調べ、config set コマンドをサーバー上で実行します:

ip addr
lxc config set core.https_address 192.168.1.15

https 越しに lxc remote add を実行したとき、パスワードを聞かれますか?

デフォルトではセキュリティー上の理由から、LXD にはパスワードはありません。 ですのでこの方法でリモートから追加できません。パスワードを設定するには、LXD を実行中のホスト上で次のコマンドを実行します:

lxc config set core.trust_password SECRET

これで、lxc remote add を使えるように、リモートのパスワードを設定します。

クライアント上の .config/lxc/client.crt にある証明書を次のコマンドでサーバにコピーすることで、パスワードを設定しなくてもサーバにアクセスできます。

lxc config trust add client.crt

どのように LXD のストレージを設定するのですか?

LXD は btrfs、ceph、ディレクトリ、lvm、zfs を使ったストーレジをサポートします。

まず、選択したファイルシステムを扱うツールをマシンにインストールしてください(btrfs-progs, lvm2, zfsutils-linux)。

デフォルトでは、LXD ではネットワークとストレージが設定されていません。 基本的な設定は次のコマンドで設定できます:

    lxd init

lxd init はディレクトリと ZFS ベースのストレージの両方をサポートします。 他のファイルシステムを使いたい場合は、lxc storage コマンドを使う必要があります:

lxc storage create default BACKEND [OPTIONS...]
lxc profile device add default root disk path=/ pool=default

BACKENDbtrfscephdirlvmzfs のどれかです。

特に指定しないと、LXD はデフォルトサイズの loop ベースのストレージをセットアップします。

プロダクション環境では、パフォーマンスと信頼性を確保するために、loop ベースではなく、ブロックストレージを使うべきです。

LXD を使ってコンテナーのライブマイグレーションはできますか?

ライブマイグレーションには、送受信それぞれのホスト上に CRIU というツールが必要です。 Ubuntu では次のようにインストールできます:

sudo apt install criu

そして、次のようにコンテナーを起動します。

lxc launch ubuntu $somename
sleep 5s # let the container get to an interesting state
lxc move host1:$somename host2:$somename

運が良ければ、コンテナーがマイグレーションされるでしょう :) マイグレーションはまだ実験段階のステージで、すべてのケースで動作しないかもしれません。 そういう場合は lxc-devel にバグレポートをしてください。必要であれば CRIU にもエスカレーションします。

私のホームディレクトリをコンテナー内にバインドマウントできますか?

はい。ディスクデバイスを使用して以下のように出来ます。

lxc config device add container-name home disk source=/home/$USER path=/home/ubuntu

非特権コンテナーの場合は、さらに以下のいずれかが必要です。

これらのいずれかにより、コンテナー内のユーザーが実際に効果のある read/write パーミッションを持てるようになります。 これらの 1 つも設定しないときは、すべてが uid/gid がオーバーフロー (65536:65536) ように見えて、 world リーダブルでないものへのアクセスは全て失敗します。

特権コンテナーではコンテナー内の全ての uid/gid が外部と同じためこの問題はありません。 しかし、このことは特権コンテナーに関するセキュリティーの問題の主な原因でもあります。

LXD コンテナー内で docker を実行できますか?

LXD コンテナー内で Docker を実行するには、コンテナーの security.nesting プロパティを true に設定します。

lxc config set <container> security.nesting true

LXD コンテナー内ではカーネルモジュールはロードできませんので、Docker の設定に従って、ホスト側で必要なカーネルモジュールをロードしておく必要があることに注意してください。

コンテナーで必要なカーネルモジュールをカンマ区切りのリストで次のように設定しておけます:

lxc config set <container> linux.kernel_modules <modules>

コンテナー内に /.dockerenv ファイルを作ることで、ネストされた環境内で実行することによりおこるエラーのいくつかを Docker に無視させることができるというレポートをいくつか受け取っています。

LXD のハック

直接 REST API を使って

LXD の REST API は、認証不要なローカルの Unix ソケット経由でも、SSL で暗号化された TCP 経由でも使えます。

UNIX ソケット経由

curl --unix-socket /var/lib/lxd/unix.socket \
    -H "Content-Type: application/json" \
    -X POST \
    -d @hello-ubuntu.json \
    lxd/1.0/containers

TCP 経由

TCP 経由では、デフォルトでは有効ではない追加の設定が必要です。

lxc config set core.https_address "[::]:8443"
curl -k -L \
    --cert ~/.config/lxc/client.crt \
    --key ~/.config/lxc/client.key \
    -H "Content-Type: application/json" \
    -X POST \
    -d @hello-ubuntu.json \
    "https://127.0.0.1:8443/1.0/containers"

事前に用意する JSON ファイル

上記の hello-ubuntu.json ファイルは以下のような内容です。

{
    "name":"some-ubuntu",
    "ephemeral":true,
    "config":{
        "limits.cpu":"2"
    },
    "source": {
        "type":"image",
        "mode":"pull",
        "protocol":"simplestreams",
        "server":"https://cloud-images.ubuntu.com/releases",
        "alias":"18.04"
    }
}