「初老丸の独り 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:] [remote:][] [--ephemeral|-e] [--profile|-p ...] [--config|-c ...]

コンテナの一覧を確認

$ 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 でテストする

こんな感じで

20151224000551

※上図、うっかり vagrant って書いてあるけど Virtualbox のことデス。

kitchen-lxd_cli

あてにしていた kitchen-lxc が動かなくて、代替を探していたら kitchen-lxd_cli というツールを発見したのでこちらを利用させていただく。

kitchen-lxd_cli - Test Kitchen driver for LXD

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'

教材

教材は引き続き、以下の教材を利用。

Contribute to oreno-ansible development by creating an account on GitHub.

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

verifiercommandKITCHEN_USERNAME=root を指定しているのは苦肉の策(root ユーザーで createconverge が実施される前提になっている為…→一応、ユーザー指定が出来るようにプルリクエストを送らせて頂いた。)

調理、試食

  • kitchen create
$ kitchen create
-----> Starting Kitchen (v1.4.2)
-----> Creating ...
       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  (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  (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 ...
       Finished setting up  (0m0.00s).
-----> Verifying ...
       [Shell] Verify on instance=# 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  (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 未満な仮想環境を求める(意外に多いのでは…)方々は是非、試したいツールだと思う。

元記事はこちら

(ショロカレ 24 日目)LXD を試した && test-kitchen + kitchen-lxd_cli + Shell-Verifier で Ansible の Playbook を Serverspec でテストする