CircleCI + Docker による Itamaeレシピの継続的インテグレーション

  • 21
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

クービックではこれまで Vagrantで作成したVMを用いて、ローカルマシンで itamae のテストを実行していました。

管理すべきロールが増えるにつれ毎回テストを回すのがツラくなってきたため、CircleCI による継続的インテグレーションを検討することにしました。

利用環境は以下の通りです。

Env / Tool Version
OS Ubuntu 14.04
Provisioning itamae (1.3.6)
Test serverspec (2.19.0)

また、リポジトリの構成は以下の通りです。
cookbooks には Itamae のレシピが、spec にはテストが入っています。

$ tree -L 1
.
├── .ssh
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── circle.yml
├── cookbooks
└── spec

事例調査

CircleCI で Serverspecによるテストの事例をいくつか調査してみました。

Vagrant + EC2

Docker + Serverspec + Itamae

production ではコンテナを利用していないので、prodution と test 環境で乖離が発生するのがやや気になりますが、Docker なら特に追加費用が掛からず、起動も速いので Docker を使うこととしました。

Docker

何はともあれ、ローカルで Docker を動かすための環境を構築します。
Mac OS X であれば、Docker Toolbox を使うのが最もカンタンと思われます。

Docker に触れたことがなければ、Get Started with Docker for Mac OS X を一通り試すのがよいです。

backend

ローカル環境構築が済んだら、docker との I/O を検討します。

Itamae と Serverspec どちらも内部で Specinfra を利用しており、backend として ssh あるいは docker の指定が可能です。production では backend に ssh を利用してるので、docker にも ssh 経由でアクセスすることにします。

なお、Why you don't need to run SSHd in your Docker containers という議論もありますが、コンテナはCircleCIでしか利用しないので今回はよしとしました。

Dockerfile

ssh でアクセスできるようなイメージを準備します。

FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev language-pack-ja
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

RUN useradd -m docker && echo "docker:docker" | chpasswd && gpasswd -a docker sudo
RUN mkdir -p /home/docker/.ssh; chown docker /home/docker/.ssh; chmod 700 /home/docker/.ssh

ADD ./authorized_keys /home/docker/.ssh/authorized_keys
RUN chown docker /home/docker/.ssh/authorized_keys; chmod 600 /home/docker/.ssh/authorized_keys

CMD /usr/sbin/sshd -D && tail -f /dev/null

工夫したポイントをいくつか。

RUN useradd -m docker && echo "docker:docker" | chpasswd && gpasswd -a docker sudo

で docker ユーザを作成し、sudo グループに登録しています。

CMD /usr/sbin/sshd -D && tail -f /dev/null

/dev/null を tail -f するのは sshd を再起動した際に、コンテナが exit しないための工夫です。

CircleCI

circle.yml を準備します。

machine:
  services:
    - docker

dependencies:
  pre: 
    - ssh-keygen -t rsa -b 2048 -N "" -C "docker" -f  ~/.ssh/id_rsa.docker
    - cat ~/.ssh/id_rsa.docker.pub > authorized_keys
    - cat .ssh/config >> ~/.ssh/config
    - docker build -t kotaroito/ubuntu .
    - docker run --privileged -d -p 2222:22 kotaroito/ubuntu
test:
  pre:
    - env SUDO_PASSWORD=docker bundle exec itamae ssh -h example cookbooks/recipe.rb
  override:
    - env SUDO_PASSWORD=docker bundle exec rake spec

docker ユーザで ssh するために、ssh-keygen で 秘密鍵・公開鍵を生成して、docker build 時に authorized_keys を image に組み込んでいます。

また、.ssh/config ファイルを用意しておき、itamae ssh -h examle できるようにします。

Host example
  HostName localhost
  User docker
  Port 2222
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/ubuntu/.ssh/id_rsa.docker

なお、privileged オプションは itamae で ufw 等を実行する場合に指定する必要があります。

実行結果

circleci.png

無事 CircleCI + Docker で Itamae レシピの継続的インテグレーションをすることができました。

参考サイト

Dockerfile と circle.yml は、以下を参考にさせていただきました。