LXD
LXD は次世代のシステムコンテナーおよび仮想マシンのマネージャーです。 コンテナーあるいは仮想マシンの内部で稼働する完全な Linux システムに対して統一されたユーザーエクスペリエンスを提供します。
いろいろな Linux ディストリビューション のあらかじめビルドされたイメージを使ったイメージベースのマネージャーであり、非常に強力でありながら、非常にシンプルに、REST API を使って構築されます。
LXD がどういうものであり、何をするのかをよく理解するために、オンラインで試用 できます。
そして、ローカルで実行してみたい場合は、はじめに という文書をご覧ください。
リリースアナウンスはこちらでご覧になれます: https://linuxcontainers.org/lxd/news/
リリース tarball はこちらから取得できます: https://linuxcontainers.org/lxd/downloads/
ステータス
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
をカスタムで設定します。ソースをビルドしたら lxc
と lxd
の実行ファイルが $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 get
と git clean
を使ってビルドに必要な全ての依存ライブラリーを取得します。
ソースからのリリース版のビルド
LXD の公式リリースをビルドするには、リリース版の tarball をダウンロード、解凍し、その中の _dist
ディレクトリを指すように GOPATH を設定してください。 _dist
ディレクトリは GOPATH として使用できるように構成されており必要なソース全てのスナップショットを含んでいます。 LXD は live
なソースを go get
と git 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}"
これで lxd
と lxc
コマンドの実行ファイルが利用可能になり 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
BACKEND
は btrfs
、ceph
、dir
、lvm
、zfs
のどれかです。
特に指定しないと、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
非特権コンテナーの場合は、さらに以下のいずれかが必要です。
lxc config device add
の実行時にshifted=true
を指定する。これはshiftfs
がサポートされている場合にのみ使えます(lxc info
参照)。- raw.idmap エントリー(ユーザー名前空間 (user namespace) 用の ID のマッピング 参照)
- ホームディレクトリーに配置した再帰的な POSIX ACL
これらのいずれかにより、コンテナー内のユーザーが実際に効果のある 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"
}
}