cookbookのテストにkitchen-lxcを使ってみた。

"test-kitchen + LXC でさくっと cookbook をテストする(為の環境を作る) - ようへいの日々精進XP"を見てchefのcookbookを簡単にテストできるtest-kitchenと、lxcを利用して高速にテストできるkitchen-lxcを知った。

面白そうなので試したところ、いくつか引っかかったのでメモしておく。

apache2のcookbookをcloneする。

$ git clone https://github.com/opscode-cookbooks/apache2.git

Gemfileを編集し追記する。

Gemfile:

source 'https://rubygems.org'

gem 'berkshelf',  '~> 2.0'
gem 'chefspec',   '~> 2.0'
gem 'foodcritic', '~> 3.0'
gem 'rubocop',    '~> 0.12'

group :integration do
  gem 'test-kitchen',    '~> 1.0.0.beta'
  gem 'kitchen-vagrant', '~> 0.11'
end

gem 'minitest-chef-handler'
gem 'chef'
gem 'chef-zero'
gem 'lxc-awesome-ephemeral', :git => 'https://github.com/portertech/lxc-awesome-ephemeral.git'
gem 'kitchen-lxc'
gem 'faraday_middleware'

bundle installを実行

bundle install
bundle exec kitchen init

その後、生成された.kitchen.ymlを以下の様に修正する。
.kitchen.yml

---
driver_plugin: lxc
driver_config:
  require_chef_omnibus: true

platforms:
- name: ubuntu-master
  driver_config:
    base_container: ubuntu-master # your base container name
    username: root # defaults to "root"
    password: root # defaults to "root"

suites:
- name: default
  run_list: ["recipe[apache2]"]
  attributes: {}

LXC Containerをセットアップする。

sudo lxc-create -t ubuntu -n ubuntu-master
sudo lxc-start -n ubuntu-master

ubuntu/ubuntuでloginし、"sudo apt-get install -y wget curl"の実行とrootのパスワード変更(.kitchen.ymlのpassword記述と合わせる)を実行し最後に"#poweroff"でContainerをシャットダウンする。
その後、"sudo bundle exe kitchen test"を実行するとテストが始まった。

$ sudo bundle exe kitchen test
-----> Starting Kitchen (v1.0.0)
-----> Cleaning up any prior instances of <default-ubuntu-master>
-----> Destroying <default-ubuntu-master>...
       Finished destroying <default-ubuntu-master> (0m0.00s).
-----> Testing <default-ubuntu-master>
-----> Creating <default-ubuntu-master>...
       Finished creating <default-ubuntu-master> (0m5.60s).
-----> Converging <default-ubuntu-master>...
       Preparing files for transfer
       Resolving cookbook dependencies with Berkshelf...
       Removing non-cookbook files before transfer
-----> Installing Chef Omnibus (true)       
downloading https://www.opscode.com/chef/install.sh       
  to file /tmp/install.sh       
trying wget...       
       Downloading Chef  for ubuntu...
       downloading https://www.opscode.com/chef/metadata?v=&prerelease=false&p=ubuntu&pv=12.04&m=x86_64
         to file /tmp/install.sh.304/metadata.txt
       trying wget...
url     https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.8.2-1.ubuntu.12.04_amd64.deb       
md5     3d3b3662830a44eeec71aadc098a4018       
sha256  a5b00a24e68e29a01c7ab9de5cdaf0cc9fd1c889599ad9af70293e5b4de8615c       
       downloaded metadata file looks valid...
       downloading https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.8.2-1.ubuntu.12.04_amd64.deb
         to file /tmp/install.sh.304/chef__amd64.deb
       trying wget...
(一部省略)
[2013-12-14T13:21:33+00:00] INFO: execute[a2dissite default] not queuing delayed action restart on service[apache2] (delayed), as it's already been queued       
         * service[apache2] action start[2013-12-14T13:21:33+00:00] INFO: Processing service[apache2] action start (apache2::default line 210)
 (up to date)       
[2013-12-14T13:21:33+00:00] INFO: template[apache2.conf] sending restart action to service[apache2] (delayed)       
  * service[apache2] action restart[2013-12-14T13:21:33+00:00] INFO: Processing service[apache2] action restart (apache2::default line 210)       
       [2013-12-14T13:21:36+00:00] INFO: service[apache2] restarted
       
           - restart service service[apache2]
       
       [2013-12-14T13:21:36+00:00] INFO: Chef Run complete in 16.52097521 seconds
       [2013-12-14T13:21:36+00:00] INFO: Running report handlers
       [2013-12-14T13:21:36+00:00] INFO: Report handlers complete
       Chef Client finished, 18 resources updated
       Finished converging <default-ubuntu-master> (0m41.19s).
-----> Setting up <default-ubuntu-master>...
       Finished setting up <default-ubuntu-master> (0m0.00s).
-----> Verifying <default-ubuntu-master>...
       Finished verifying <default-ubuntu-master> (0m0.00s).
-----> Destroying <default-ubuntu-master>...
       Finished destroying <default-ubuntu-master> (0m0.64s).
       Finished testing <default-ubuntu-master> (0m47.80s).
-----> Kitchen is finished. (0m47.83s)

"Kitchen is finished"と表示された、成功!

気づいた事

kitchen-lxcはベース環境(この場合はubuntu-master)をベースにunion filesystemの一種のoverlayfsを使ってテスト用のコンテナを作成していた。どおりでlxcの起動が速い筈だ。(最初はlxc-cloneを利用しているのかと思っていた)


Overlayfsを利用する事で、ベース環境のFSには追記せず、差分情報だけを別ディレクトリに保持するディスクの利用効率が非常に高い。

これはいい方法だと思う。そう言えばdockerはaufsを用いてにたような事をやってるなあ。

$ mount
/dev/vda1 on / type ext3 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
(一部省略)
none on /var/lib/lxc/ubuntu-master-1ZnqzdJYJ43l/rootfs type overlayfs (rw,upperdir=/tmp/lxc/ephemerals/virt-mnts/ubuntu-master-rD9ycFcJsoxP,lowerdir=/var/lib/lxc/ubuntu-master/rootfs)

このコンテナ作成の仕組みはどうやらlxc-awesome-ephemeralを利用しているみたい。以下の様に単独で動かす事ができた。

$ sudo lxc-awesome-ephemeral -o ubuntu-master
New ephemeral container started. (ubuntu-master-1ZnqzdJYJ43l)
    - Connect using: sudo ssh -i /opt/hw-lxc-config/id_rsa root@10.0.3.12

参照

LXC入門 - Osc2011 nagoya:lxc環境を商用で提供されている会社の方が作成された資料(ちょっと古め)
Linuxコンテナ最新情報:LXCに関して非常に詳しく書かれていた。