「初老丸の独り 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 とは
参考
まずはうんちくから
こちら のドキュメントを抜粋。
コンテナのハイパーバイザ
以下の三つのコンポーネント。
- システム全体のデーモン (lxd)
- コマンドラインクライアント (lxc)
- OpenStack Nova プラグイン (nova-compute-lxd)
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 |
+------------------+---------+-------------------+------+-----------+-----------+
コンテナを任意の名前でイメージとして保存する
こちらを参考にした。
$ lxc exec oreno-ubuntu -- apt-get -y install openssh-server
$ 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) |
+--------------------+--------------+--------+-----------------------+--------+----------+-------------------------------+
おお。
test-kitchen + kitchen-lxd_cli + Shell-Verifier で Ansible の Playbook を Serverspec でテストする
こんな感じで
※上図、うっかり vagrant って書いてあるけど Virtualbox のことデス。
kitchen-lxd_cli
あてにしていた kitchen-lxc が動かなくて、代替を探していたら kitchen-lxd_cli というツールを発見したのでこちらを利用させていただく。
github.com
ざっくり拝見すると、その名の通り 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'
教材
教材は引き続き、以下の教材を利用。
github.com
コンテナイメージを作成する
事前にコンテナイメージを作成する。
$ 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
-----> 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 |
+------------------+---------+-------------------+------+-----------+-----------+
コンテナが作成されている。
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.
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 未満な仮想環境を求める(意外に多いのでは...)方々は是非、試したいツールだと思う。