近況
3月から DevOps 関連の技術的負債の解消に取り組んでいて,動かなくなった Chef を直したり,秘伝のタレ(手動)で構築されたサーバ設定を Chef にリバースエンジニアリングしたり,Serverspec を導入して稼働中のサーバの差異を確認したりしている.
他にもウェブサーバのパフォーマンスチューニングをしたり,Zabbix / Kibana / CloudWatch で可視化したり,不要なアラートを消したりもした.あと Vagrant 環境を自動構築できるようにしたり,Packer を使って Vagrant Box を改善したり,デプロイ手順を正常化したり,テストの品質向上の目的で Capybara を導入したりもした.
最近はキャッシュサーバをリプレイスしたり,AWS のネットワーク構成を変更するなど,とにかく様々な施策を試しているけど,全然まだまだという感じで,圧倒的成長が求められている.
- Packer を使って Vagrant のディスク容量を拡張する - kakakakakku blog
- php-fpm のパラメータを調査した - kakakakakku blog
- 表参道.rb #10 で PHP + Capybara ネタの LT をしてきた - kakakakakku blog
- プロキシ設定をしてから chef-solo を実行する - kakakakakku blog
- Zabbix で Memcached のメトリクスを監視する - kakakakakku blog
Chef をテストする
今までローカル環境で Chef をテストする場合,Vagrant + Sahara Plugin で適用とロールバックを繰り返して,Serverspec を手動で流していた.ちなみに Vagrant 1.8 から公式で vagrant snapshot
コマンドが追加されたらしく,もしかしたら Sahara Plugin の役目は終わったのかも?(未検証)
$ vagrant -v
Vagrant 1.7.4
$ vagrant sandbox on
$ vagrant provision
$ vagrant sandbox rollback
Infrastructure CI
とは言え,モダンに Infrastructure CI をしたいなと思っていて,既に事例も多く出ている CircleCI + Docker を活用した環境を構築してみた.今回構築した構成図はザッとこんな感じ.基本的に CircleCI からコンテナに ssh をしたくないと考えていて,全てコンテナ内で完結するように工夫した.
Dockerfile
まず,コンテナイメージに関しては CentOS 6.x で,既に Ruby 2.x が入っている tcnksm/centos-ruby
をベースにした.今後カスタマイズしてもっと軽量なイメージに置き換えていきたいと思っている.
Chef を管理しているリポジトリをコンテナの /chef
にコピーして,circleci
ノードに対して Chef を実行している.上記の通り,コンテナ内で完結するため knife solo cook
ではなく chef-solo
にした.
今はまだ RUN
を呼び出しまくっているため,1回に抑えてイメージサイズを軽量化した方が良さそうだけど,そもそも Chef を実行した後のゴミファイルが残ってしまっていたり,イメージサイズに関してはもっと抜本的な策が必要だと思う.今回は実際に稼働させるわけではなく CI 専用だから多少は甘く考えている.
FROM tcnksm/centos-ruby ENV CHEF_HOME /chef # Docker で実行するときに Serverspec の backend を切り替えるため ENV IS_DOCKER 1 # リポジトリをコンテナに展開する # `solo.rb` だけはコンテナ用に上書きする ADD . ${CHEF_HOME} ADD ./solo_circleci.rb ${CHEF_HOME}/solo.rb # epel リポジトリを削除する RUN rm -f /etc/yum.repos.d/epel.repo # Chef をインストールして chef-solo を実行する RUN curl -L https://www.opscode.com/chef/install.sh | bash RUN cd ${CHEF_HOME} && bundle install RUN cd ${CHEF_HOME} && /usr/bin/chef-solo -c ${CHEF_HOME}/solo.rb -j ${CHEF_HOME}/nodes/circleci.json
circle.yml
circle.yml
はシンプルに書いた.事前に docker build
をして,最後に docker run
で Serverspec を実行している.
machine: services: - docker dependencies: override: - docker info - docker build -t xxxxx . test: override: - docker run -it xxxxx sh /chef/spec_scripts/spec.sh
spec_scripts/spec.sh
CircleCI から Serverspec を実行するスクリプトを呼び出している.ただし nginx を起動している点は微妙すぎると思っていて,コンテナは chkconfig
を設定しても docker run
で自動起動されるわけではないため,スクリプトで起動することにした.むむむむむー!微妙!
#!/bin/sh service nginx start cd ${CHEF_HOME} bundle exec rake spec:localhost
spec/spec_helper.rb
Serverspec で使っている spec_helper.rb
を一部修正した.具体的には backend の設定で,通常は ssh
で実行しているけど,CircleCI ではコンテナ内で実行するため,Dockerfile で環境変数 IS_DOCKER
を定義して,環境変数が存在する場合に exec
に切り替えるようにしている.
set :backend, :ssh # 通常の実行と CircleCI with Docker の実行で backend を切り替える set :backend, :exec if ENV['IS_DOCKER']
実行結果
イイ感じ!
巨大イメージ問題
実際に Dockerfile から docker build
したイメージサイズが 3GB を超えていて,ポータブルなコンテナと言えないのでは?と思えるほどのデカさになっている.ローカル環境で docker build
を何度も繰り返していたら Mac のディスク容量が無くなってワロタwww
まとめ
1日でサクッと Infrastructure CI を実践してみた.CircleCI の手軽さは驚きだし,プライベートリポジトリでも無料で使える点は最高だと思う.今回は実行できるようにすることに注力したため,まだまだ改善すべき点があるし,もはや Docker をうまく活用できてない気もするため,アドバイス求む!って感じではある.DevOps もアジャイルでリーンな開発をするべきだと思うし,今後も小さな成功を積み上げていこうと思う.
軽さは正義!(昨日 Alpine Linux Meetup Tokyo #1 に参加して意識高まってる)