はじめに
このエントリーは,CyberAgent20新卒エンジニアAdvent Calendar 2019の2日目の記事です.
大学院の研究でLXDを取り扱っているので,LXDのビルドからコンテナのデプロイまでを紹介します.
興味があったら,ぜひやってみてください.
目次
- CRIUのビルドとインストール
- LXCのビルドとインストール
- LXDのビルドとインストール
- LXD起動の準備とコンテナのデプロイ
1. CRIUのビルドとインストール
LXDのコンテナライブマイグレーションを行うためには,LinuxのプロセスマイグレーションツールであるCRIUが必要です.そのため,CRIUのビルドとインストールを行います.
CRIUのビルド準備(必要なパッケージのインストールとソースコードの取得)
ここはほとんど,公式ページの「Installing build dependencies」情報とおりです.
何行かに分かれていたり,私の環境では足りなかったりするパッケージがあったりと面倒なので,全部インストールするコマンドを記載します
sudo apt install make gcc libprotobuf-dev libprotobuf-c0-dev \
protobuf-c-compiler protobuf-compiler python-protobuf \
pkg-config python-ipaddress libbsd-dev iproute2 libcap-dev libnl-3-dev \
libnet-dev libaio-dev asciidoc
続いて,ソースコードを取得します.GitHubからCloneするので,gitがない場合はインストールしてください.
ソースコードはこのリポジトリから取得できます.
ビルドとインストール
ビルドとインストールも公式ページの「Building the tool」,「Installing」のとおりです.
ただ,criuリポジトリのデフォルトブランチでは動作が不安なので,リリースを確認して直近のタグにチェックアウトしてからビルドすることをおすすめします.ここでは3.13とします.
make
sudo make install
正常にビルドされインストールも完了したことを確認するため,以下のコマンドを実行します.
CRIUのバージョンやgitのcommit id等の情報が表示されれば,ひとまず安心です.
sudo criu --version
2. LXCのビルドとインストール
LXDは内部でLXCをコンテナランタイムとして利用することで,コンテナの作成や削除を行っています.そのため,LXCのビルドとインストールを行います.
LXCのビルド準備(必要なパッケージのインストールとソースコードの取得)
LXCのビルドには,いくつかのビルドツールが必要なのでそれらをインストールします.それぞれのパッケージについては詳しく説明しません(私も理解していないため).
sudo apt install libtool automake docbook m4
続いて,ソースコードの取得です.
このリポジトリからソースコードをクローンします.CRIUと同様にデフォルトのブランチでは動作が不安なため,直近のリリースタグにチェックアウトしておくと安心です.ここでは,3.1.0とします.
ビルドとインストール
このリポジトリのREADMEにかかれているとおりです.以下のコマンドを実行しましょう.
./autogen.sh #configureの生成
./configure #Makefileの生成
make #ビルド
sudo make install #インストール
3. LXDのビルドとインストール
ようやくLXDのビルドとインストールを行います.
LXDのビルド準備(必要なパッケージのインストールとソースコードの取得)
必要なパッケージはこのリポジトリのREADMEに記述されていますが,lxcのライブラリに関してはビルドしたライブラリを利用するため,インストールしません.ここでGo言語もインストールされています.
sudo apt install acl autoconf dnsmasq-base \
git golang libacl1-dev libcap-dev \
libtool libuv1-dev make pkg-config rsync squashfs-tools \
tar tcl xz-utils ebtables
#liblxc1 liblxc-dev これらはインストールしない
セキュリティに係るパッケージをインストールします.
sudo apt install libapparmor-dev libseccomp-dev libcap-dev
LXDのストレージ用パッケージをインストールします
sudo apt install lvm2 thin-provisioning-tools btrfs-tools
テスト用パッケージをインストールします.(LXDの開発者でなければ必要ないでしょう)
sudo apt install curl gettext jq sqlite3 uuid-runtime bzr socat
続いて,ソースコードの取得を行います.LXDはGo言語で実装されているので,Goのお作法でソースコードを取得するのが良いです.
go get github.com/lxc/lxd
依存ライブラリのビルド
まずは,依存するライブラリのビルドです.
その前に,やはりデフォルトのブランチでは動作が不安なため,直近のリリースタグにチェックアウトします.ここでは,3.18とします.
go get
で取得したソースコードは${GOPATH}/src/github.com/lxc/lxd
にあります.
make deps
エラーなくライブラリのビルドが終了すると,以下のような情報が表示されるはずです.
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}"
ビルドしたライブラリをOSに共有ライブラリとして登録する
CGO_CFLAGSとCGO_LDFLAGSはそのまま,.bashrc
などに記述すればよいのですが,LD_LIBRARY_PATHに関しては少し工夫が必要です.
後の話なのですが,ビルドしたLXDのバイナリはsudoで実行する必要があります.そのため,そのままLD_LIBRARY_PATHを.bashrc
に記述するとsudoで実行する場合,ビルドしたライブラリが見えません.
この問題を解決するため,共有ライブラリとしてOSに登録する必要があります.
Ubuntu18.04の場合,/ld.so.conf.d/
配下にライブラリが配置されているパスが記述されている設定ファイルを配置することで,そのパスを見て共有ライブラリを登録してくれます.
そのため,以下のファイルを作成します.
${GOPATH}の部分は,環境に合わせて変更された内容が依存ライブラリビルド時に表示されているはずなので,その内容と読み替えてください.
${GOPATH}/deps/sqlite/.libs/
${GOPATH}/deps/dqlite/.libs/
${GOPATH}/deps/raft/.libs
${GOPATH}/deps/libco/
追加した設定ファイルの内容をOSに知らせるために,以下のコマンドを実行します.
sudo ldconfig
LXDのビルドとインストール
続いて,LXD本体のビルドを行います.ビルドはとっても簡単です.
make
ビルドが正常に終了した場合,${GOPATH}/bin配下にlxd
とlxc
というバイナリが配置されているはずです.
そのため,特にインストール操作はありません.
LXDビルドのトラブルシューティング(go-dqliteのエラー対処)
簡単なはずなのですが,私の環境ではLXDが利用するGo言語のパッケージであるgo-dqlite
でエラーが発生しました.そのエラーは以下です.
use of internal package not allowed
これは,LXDが利用しているパッケージがgithub.com/CanonicalLtd/go-dqlite
であるにも関わらず,そのgithub.com/CanonicalLtd/go-dqlite
はgithub.com/canonical/go-dqlite
というパッケージの複製なので,ソースコード内のimport分が以下の様になってしまっていることが原因です.
import (
github.com/canonical/go-dqlite/internal/bindings
//本当は github.com/CanonicalLtd/go-dqlite/internal/bindings であるべき
)
なので,この様な状態になってしまっているファイルをすべて修正します.
具体的には,github.com/canonical/go-dqlite
になっている部分をgithub.com/CanonicalLtd/go-dqlite
に変更します.
これで,上記のエラーは解消できました.
4. LXD起動の準備とコンテナのデプロイ
LXD起動の準備をします.
subuid/subgidの設定
ここに記述されている通り,LXDでコンテナのデプロイをするためには,以下の操作が必要です.
echo "root:1000000:65536" | sudo tee -a /etc/subuid /etc/subgid
lxdグループの作成と,ユーザの追加
sudoなしでコマンドを実行できるようにします.
まず,以下のコマンドでlxdグループを作成します.
sudo groupadd lxd
その後,以下のコマンドでlxdを操作したいユーザをlxdに追加します.
sudo usermod -aG lxd $USER
LXDの実行と初期化
まず以下のコマンドで,LXDを起動します.
--group オプションではsudoなしでlxcコマンドを実行できるようにするgroupを指定します.
logfileオプションは,ログを吐き出す場所を指定します.
sudo $GOPATH/bin/lxd --group lxd --logfile=/var/log/lxd/lxd.log
一度実行が確認できたら,systemdに自動起動してもらうようにします.
以下のserviceファイルを/lib/systemd/system
配下に作成します.
[Unit]
Description=LXD - main daemon
[Service]
ExecStart=/home/yota/go/bin/lxd --debug --group lxd --logfile=/var/log/lxd/lxd.log
[Install]
WantedBy=multi-user.target
続いて,以下のコマンドでLXDの設定を初期化します.
LXDをお好みに設定してください.
ただし,外部公開は必ずしてください.
sudo $GOPATH/bin/lxd init
参考までに,私はこの様な感じです
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=100GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]: yes
Address to bind LXD to (not including port) [default=all]:
Port to bind LXD to [default=8443]:
Trust password for new clients:
Again:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
コンテナのデプロイ
以下のコマンドで軽量なalpineイメージでコンテナをデプロイします.
sudo $GOPATH/bin/lxc launch images:alpine/3.9 hoge
# hogeはコンテナの名前
コマンドの実行
以下のコマンドで起動したコンテナのashに入って色々操作できます.
lxc exec hoge /bin/ash
おわりに
いかがでしょうか?
Docker以外のコンテナランタイム使ってみたいなと思った方はぜひLXD使ってみてください.
ところで...
CyberAgentで21卒の本選考がはじまりました!
選考についてはこちらを御覧ください!!
早期エントリーには就業型インターンシップの特典があるそうです.
このインターンではエンジニアとして個人で勉強していたり大学で勉強しているだけでは獲得できない経験が得られました!
それだけでなく,社内エンジニアの人の良さを知ることもでき会社の様子を知るのにも最適でした!
少しでも気になっている方は,ぜひエントリーを考えてみてください!!!!