「初老丸の独り Advent calendar 2015」の二十四日目の記事です。
tl;dr
test-kitchen で Cookbook や Playbook を適用する仮想マシンとして LXC が利用出来る kitchen-lxc が手元の環境で動作しなくなっていたので、LXD なら...と思って、まずは LXD を試してみることにした。
以下のドキュメントを参考に進める。
続いて、test-kitchen と kitchen-lxd_cli + Shell-Verifier を組み合わせて Ansible の Playbook を Serverspec でやってみることにした。
LXD とは
参考
- https://linuxcontainers.org/ja/lxd/introduction/
- http://d.hatena.ne.jp/defiant/
- http://hnakamur.github.io/blog/2014/12/01/lxd-the-linux-container-daemon/
まずはうんちくから
こちら のドキュメントを抜粋。
コンテナのハイパーバイザ
以下の三つのコンポーネント。
lxd デーモンは Rest API を提供する。
主な機能
以下のような機能を提供する
- セキュアなデザイン (非特権コンテナ、リソース制限、その他)
- 拡張性 (あなたのラップトップ機から数千のコンピュートノードまで)
- 直感的 (シンプルでクリアな API、きびきびしたコマンドライン体験)
- イメージをベースにしている (ディストリビューションテンプレートは不要で、良い信頼できるイメージのみ使用)
- ライブマイグレーション
完全にドキュメントのパクリで恐縮だが...
- 非特権コンテナを動かすことが出来る
- 信頼出来るイメージのみを使用する
- ライブマイグレーション
等が個人的には興味あり〼。
試す
試す環境
Virtualbox + Vagrant で用意した。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
LXD のインストール
Ubuntu14.04 の場合には PPA でインストールする必要がある。
$ sudo add-apt-repository ppa:ubuntu-lxc/lxd-git-master && sudo apt-get update
$ sudo apt-get install lxd
一般ユーザーでも lxd にアクセス出来るようにする
以下のように一般ユーザーを lxd グループに追加する。
$ sudo usermod -aG lxd vagrant
一旦、ログアウトを忘れずに...。
利用可能なイメージ一覧を確認
$ lxc image list images: +--------------------------------+--------------+--------+-------------------------+---------+----------+-------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------------------------------+--------------+--------+-------------------------+---------+----------+-------------------------------+ | centos/6/amd64 (1 more) | 5d673faf89bd | yes | Centos 6 (amd64) | x86_64 | 49.93MB | Dec 22, 2015 at 12:17pm (JST) | | centos/6/i386 (1 more) | 7f3f871f1900 | yes | Centos 6 (i386) | i686 | 49.85MB | Dec 22, 2015 at 12:19pm (JST) | | centos/7/amd64 (1 more) | c9856d99aa27 | yes | Centos 7 (amd64) | x86_64 | 58.94MB | Dec 22, 2015 at 12:22pm (JST) | (snip) | | 57b38724e1c6 | yes | Oracle 6.5 (i386) | i686 | 141.56MB | Dec 21, 2015 at 9:23pm (JST) | | | c5a7845ec81e | yes | Plamo 5.x (amd64) | x86_64 | 243.76MB | Dec 21, 2015 at 7:24am (JST) | | | 164c45e79912 | yes | Plamo 5.x (amd64) | x86_64 | 248.15MB | Dec 22, 2015 at 7:24am (JST) | | | 228b34412c4a | yes | Plamo 5.x amd64 (mini) | x86_64 | 495.06MB | Dec 21, 2015 at 7:51am (JST) | +--------------------------------+--------------+--------+-------------------------+---------+----------+-------------------------------+
リモートのイメージサーバーを登録する
lxc remote add images images.linuxcontainers.org
images.linuxcontainers.org からコンテナイメージを取得するように指定する。
コンテナの起動
$ lxc launch images:ubuntu/trusty/amd64 oreno-ubuntu
images
オプションを付けるとリモートのイメージサーバーから取得するように設定される。
尚、lxc launch
オプションは以下の通り。
lxc launch [remote:]<image> [remote:][<name>] [--ephemeral|-e] [--profile|-p <profile>...] [--config|-c <key=value>...]
コンテナの一覧を確認
$ lxc list +------------------+---------+-------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +------------------+---------+-------------------+------+-----------+-----------+ | default-ubuntu01 | RUNNING | 10.x.x.249 (eth0) | | NO | 0 | +------------------+---------+-------------------+------+-----------+-----------+ | oreno-ubuntu | RUNNING | 10.x.x.250 (eth0) | | NO | 0 | +------------------+---------+-------------------+------+-----------+-----------+
コンテナにアクセスする
コンテナを起動後、以下のように lxc exec
コマンドを利用してコンテナにアクセスする。
$ lxc exec oreno-ubuntu -- /bin/bash
あらかじめ SSH をインストールしたコンテナイメージから起動すれば SSH でアクセスすることも可能。
コンテナを停止
コンテナの停止は以下のように。
$ lxc stop oreno-ubuntu
コンテナの停止を確認。
$ lxc list +------------------+---------+-------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +------------------+---------+-------------------+------+-----------+-----------+ | default-ubuntu01 | RUNNING | 10.x.x.249 (eth0) | | NO | 0 | +------------------+---------+-------------------+------+-----------+-----------+ | oreno-ubuntu | STOPPED | | | NO | 0 | +------------------+---------+-------------------+------+-----------+-----------+
コンテナを任意の名前でイメージとして保存する
こちらを参考にした。
# # oreno-ubuntu コンテナで openssh-serve をインストール # $ lxc exec oreno-ubuntu -- apt-get -y install openssh-server # # oreno-ubuntu コンテナを停止 # $ lxc stop oreno-ubuntu # # lxc publish コマンドを利用してイメージを保存 # $ lxc publish oreno-ubuntu --alias=oreno-ubuntu-image # # lxc image list コマンドでイメージ一覧を確認 # $ lxc image list +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+ | oreno-ubuntu-image | b04af838736b | no | | x86_64 | 126.77MB | Dec 23, 2015 at 1:03pm (JST) | | | 13a58482578d | no | | x86_64 | 126.74MB | Dec 23, 2015 at 12:44pm (JST) | | | 5a477c368646 | no | Ubuntu trusty (amd64) | x86_64 | 64.46MB | Dec 23, 2015 at 12:03pm (JST) | +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+
おお。
test-kitchen + kitchen-lxd_cli + Shell-Verifier で Ansible の Playbook を Serverspec でテストする
こんな感じで
※上図、うっかり vagrant って書いてあるけど Virtualbox のことデス。
kitchen-lxd_cli
あてにしていた kitchen-lxc が動かなくて、代替を探していたら kitchen-lxd_cli というツールを発見したのでこちらを利用させていただく。
ざっくり拝見すると、その名の通り lxc
コマンドを叩いてイメージからコンテナを作成したりしていて、ソースコードを追えばどんな事をしているのか把握しやすかったりする。
尚、現時点では kitchen-lxd_cli で利用できるコンテナイメージの OS は Ubuntu か Debian 系の OS に限定されているので注意が必要。
インストールは Gemfile に追加するか、gem install
で。
$ cat Gemfile source "https://rubygems.org" gem 'test-kitchen' gem 'kitchen-ansible' gem "serverspec" gem "kitchen-vagrant" gem "kitchen-verifier-shell" gem 'kitchen-lxc' gem 'kitchen-lxd_cli'
教材
教材は引き続き、以下の教材を利用。
コンテナイメージを作成する
事前にコンテナイメージを作成する。
$ lxc exec oreno-ubuntu -- apt-get -y install openssh-server && mkdir /root/.ssh $ lxc stop oreno-ubuntu $ lxc publish oreno-ubuntu --alias=oreno-ubuntu-image
作成されたイメージを確認。
$ lxc image list +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+ | oreno-ubuntu-image | b04af838736b | no | | x86_64 | 126.77MB | Dec 23, 2015 at 1:03pm (JST) | | | 13a58482578d | no | | x86_64 | 126.74MB | Dec 23, 2015 at 12:44pm (JST) | | | 5a477c368646 | no | Ubuntu trusty (amd64) | x86_64 | 64.46MB | Dec 23, 2015 at 12:03pm (JST) | +--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+
.kitchen.local.yal
以下のように .kitchen.local.yml を作成する。
--- driver: name: lxd_cli image_name: oreno-ubuntu-image enable_wait_for_ssh_login: true provisioner: name: ansible_playbook roles_path: roles platforms: - name: ubuntu01 suites: - name: default provisioner: playbook: default.yml hosts: default verifier: name: shell command: export KITCHEN_USERNAME=root && rspec -c -f d -I serverspec serverspec/common_spec.rb
verifier
の command
で KITCHEN_USERNAME=root
を指定しているのは苦肉の策(root
ユーザーで create
や converge
が実施される前提になっている為...→一応、ユーザー指定が出来るようにプルリクエストを送らせて頂いた。)
調理、試食
- kitchen create
$ kitchen create -----> Starting Kitchen (v1.4.2) -----> Creating <default-ubuntu01>... Initializing container default-ubuntu01 Starting container default-ubuntu01 Waiting for network to become ready Setting up public key /home/vagrant/.ssh/id_rsa.pub on default-ubuntu01 Check /root/.ssh on default-ubuntu01 Finished creating <default-ubuntu01> (0m8.14s). -----> Kitchen is finished. (0m8.16s)
この時点で LXD コンテナを確認してみる。
$ lxc list +------------------+---------+-------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +------------------+---------+-------------------+------+-----------+-----------+ | default-ubuntu01 | RUNNING | 10.x.x.249 (eth0) | | NO | 0 | +------------------+---------+-------------------+------+-----------+-----------+
コンテナが作成されている。
- kitchen converge
Ansible の Playbook を流してみる。
$ kitchen converge (snip) PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [localhost] TASK: [common | file path=/tmp/sample.txt state=touch mode=0644] ************** changed: [localhost] PLAY RECAP ******************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 Finished converging <default-ubuntu01> (2m26.22s). -----> Kitchen is finished. (2m26.30s) zlib(finalizer): the stream was freed prematurely.
- kitchen verify
Shell-Verifier に Serverspec のテストを叩かせる。Shell-Verifier に Serverspec を実行させるのが快適なので手放せなくなりそう。
$ kitchen verify -----> Starting Kitchen (v1.4.2) -----> Setting up <default-ubuntu01>... Finished setting up <default-ubuntu01> (0m0.00s). -----> Verifying <default-ubuntu01>... [Shell] Verify on instance=#<Kitchen::Instance:0x007f3d0802d4c8> with state={:hostname=>"10.x.x.249", :username=>"root", :last_action=>"setup"} File "/tmp/sample.txt" should be file Finished in 0.4627 seconds (files took 0.71709 seconds to load) 1 example, 0 failures Finished verifying <default-ubuntu01> (0m1.31s). -----> Kitchen is finished. (0m1.37s)
ひとまず調理、試食までは滞りなく。
ということで...
LXD について
入門レベルでどうこう言える身分では無いけど、Docker のように起動が速いし、一般ユーザーでも手軽にコンテナ環境を利用出来るのは嬉しい。仮想マシン上でも動くというのも嬉しい。API も提供されているとのことで引き続き触っていきたい。
kitchen-lxd_cli について
作者のモチベーションが github の README に記載されていたので転載。
I started the project because I really like the idea of developing containers, but kitchen-lxc wouldn't work with my version. I also tried docker but preferred how lxd is closer to a hypervisor virtual machine. For instance kitchen-docker my recipes that had worked on virtual machies for mongodb, the service would not start when using docker. I was able to get the service to start but liked the concept of system containers more than application containers. Ultimately I was interested in LXD and there wasn't anything out there. I was quickly able to get my mongodb recipe working. I figured I'd clean things up, and some features and publish it. Since then I've added numerous features, mainly with a focus on speeding up development of cookbooks, and exploring LXD.
超ざっくり意訳。
- 俺(作者)が作った Mongodb の Chef レシピをテストしようとしたよ
- kitchen-lxc が動かなかったぜ
- kitchen-docker でも思ったような結果が得られなかった
- 俺(作者)は LXD に興味があったので Mongodb のレシピを LXD で試してみた
- 満足出来るような結果が得られたのでこのツールを公開しようと考えた
なるほど。
先述の通り、現時点では Ubuntu と Debian のコンテナのみ対応していたり、開発途上ではあるものの kitchen-lxc の代わりとして引き続き注目していきたい。
以上
LXD は Docker 周辺のエコシステムが充実している訳でも無さそうだけど、Docker のようにサクッとコンテナ環境が起動するし、従来の lxc と遜色の無い操作で扱えるので、Docker 以上 Vagrant 未満な仮想環境を求める(意外に多いのでは...)方々は是非、試したいツールだと思う。