Glide Note

glidenote's blog

Alpine LinuxなDockerイメージにServerspecを実行する環境を作った

TL;DR

  • Alpine LinuxなDockerイメージにServerspecを実行する環境をMacとCircleCI上に作った
  • CircleCI環境では lxc-attach コマンドが必要なので、spec_helper.rb で環境差を吸収するようにした
  • 今後よく利用しそうなので、流用しやすい形でGithubに置いておいた

前提

最近Kaizen Platform, Inc.で利用している一部Docker ImageをAmazon LinuxベースのものからAlpine Linuxベースのものに置き換え中。 Alpine Linuxについては@stormcat24さんのブログが一番参考になります。

今までDockerイメージにServerspecを実行するときには、コンテナ内でsshdを立てて、ssh経由でknife-soloでプロビジョニングを実行し、その後同じくssh経由でServerspecを流していた。

Alpine Linuxベースに切り替えてから、出来るだけイメージサイズを小さくするためにknife-soloは利用せずに、Dockerfile だけで構築している。(Dockerfileだけが良いかは現在検証中) knife-soloのためにコンテナ内でsshdを立てる必要はなくなったので、同じくssh経由で実行していたServerspecdocker-api 経由で実行するようにした。

実行環境

  • Mac OS X
    • ProductVersion: 10.11.6
    • Ruby 2.3.0
    • Docker 1.12.0
  • CircleCI
    • Ruby 2.3.0
    • Docker 1.9.1-circleci-cp-workaround
  • serverspec 2.36.0
  • docker-api 1.31.0

実際の作業

ファイル構成

先に作業後のファイル構成を書いておくと下記のような感じになります。

1
2
3
4
5
6
7
8
9
10
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── circle.yml
└── spec
    ├── docker
    │   └── package_spec.rb
    └── spec_helper.rb

Gemfile

Gemfileを用意して bundle install

1
2
3
4
5
source 'https://rubygems.org'

gem 'rake'
gem 'serverspec'
gem 'docker-api'

Dockerfile

Dockerfileを用意。debugしやすいようにbashだけ導入

1
2
3
FROM alpine:3.4

RUN apk add --no-cache bash

tagは docker-alpine-serverspec-sample としてbuild。

1
docker build -t docker-alpine-serverspec-sample .

Serverspec各種ファイル

serverspec-init で各種ファイルを作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
⇒  serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 2

 + spec/
 + spec/localhost/
 + spec/localhost/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

生成されるsampleのテストは利用しないので削除

1
rm -rf spec/localhost

ローカル用の spec_helper.rb

1
2
3
4
5
6
7
8
9
require 'serverspec'
require 'docker'

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
image = Docker::Image.build_from_dir('.')
set :docker_image, image.id

Excon.defaults[:ssl_verify_peer] = false

テストファイルの追加

ディレクトリの作成し、Dockerfileのパッケージインストールに対応するテスト spec/docker/package_spec.rb を追加

1
mkdir -p spec/docker/
1
2
3
4
5
require 'spec_helper'

describe package('bash') do
  it { should be_installed }
end

Serverspecの実行

テストの準備が整ったので、Serverspecを流してみる。

1
bundle exec rake spec

問題がなければ下記のようになる。

1
2
3
4
5
Package "bash"
  should be installed

Finished in 1.61 seconds (files took 0.67509 seconds to load)
1 example, 0 failures

CircleCI上での実行

ローカルに続いて、CircleCI環境でも動くようにする。

circle.yml の用意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
machine:
  timezone: UTC
  ruby:
    version: 2.3.0
  services:
    - docker

dependencies:
  pre:
    - bundle install

test:
  pre:
    - docker version
    - docker info
    - docker build -t ${CIRCLE_PROJECT_REPONAME} . :
        timeout: 1200
    - docker run ${CIRCLE_PROJECT_REPONAME} &
    - sleep 5
  override:
    - bundle exec rspec
    - docker ps -a
    - docker images

CircleCI でも動くようにspec_helper.rbの修正

公式ドキュメント に記載されているようにCircleCIのDockerでは docker exec が利用できず、 lxc-attach コマンドを利用しないといけないので、spec_helper.rb でMacとの環境差を吸収し、同じコマンドでServerspecが流せるようにする。

元同僚の@ngs自身のブログに書いていたのでそれを利用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'serverspec'
require 'docker'

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
image = Docker::Image.build_from_dir('.')
set :docker_image, image.id

Excon.defaults[:ssl_verify_peer] = false

# https://circleci.com/docs/docker#docker-exec
if ENV['CIRCLECI']
  module Docker
    class Container
      def exec(command, opts = {}, &block)
        command[2] = command[2].inspect # ['/bin/sh', '-c', 'YOUR COMMAND']
        cmd = %Q{sudo lxc-attach -n #{self.id} -- #{command.join(' ')}}
        stdin, stdout, stderr, wait_thread = Open3.popen3 cmd
        [stdout.read, [stderr.read], wait_thread.value.exitstatus]
      end
      def remove(options={})
        # do not delete container
      end
      alias_method :delete, :remove
      alias_method :kill, :remove
    end
  end
end

これで、Mac上でもCircleCI上でも同じ

1
bundle exec rake spec

でテストが実行できるようになった。

↑の画像のように、イメージのサイズが非常に小さいAlpine Linuxに切り替えてからbuildもtestもすぐに完了するので生産性が高くなった。

参考

Mackerelのページを瞬時に開くAlfred Workflowを作った

Mackerelを利用していて、

  • 特定のホストのメトリクス
  • 特定のサービスのメトリクス
  • 特定のダッシュボード

などを見るときにページにアクセスして探すのに若干手間がかかるので、Alfredから瞬時に開けるようにWorkflowを作った。

導入方法や使い方はREADMEを参照ください。 動作は下記のような感じになります。(サービスとダッシュボードを開く動作はキャプチャに秘匿情報が含まれているので割愛してます bow )

関連

最近導入した開発に役立つ便利なステータスバー通知系アプリ3選

最近追加したステータスバーの通知系アプリで便利なやつを共有。

GitHub Notifications

GitHubのNotifications通知については、Gitifyを利用。 それまでは自分宛の通知はZapier使ってSlackに通知したり、Chrome Extensionとか使って検知してたんですが、 ステータスバーに通知するやつが自分にはあっていたので、半年くらい前から利用してます。

CircleCI Notifications

CircleCIの通知にはSeaEyeを利用。特定プロジェクトや、自分のビルドだけ通知などが設定ができるのが大変便利。

BitBar & Sensu Notifications

rebuild.fm a132で話題に出ていたBitBarで、KAIZENで利用している監視システムSensuのPluginがあったので導入。 Sensuがアラートを検知した場合、Pagerduty経由で、Slack、メール、電話、スマホアプリへの通知などをしてくれるので、無くても良いんですが、ちょっとBitBarを利用してみたかったので導入。

これを機にメールとSlackでの通知も減らしたので作業に集中する時間が増えた(気がする)

参考

CircleCIのProjectページの移動が簡単になるAlfred Workflowを作った

実はCircleCI Advent Calendar 2015 - Qiitaにエントリするために、 結構前にAlfred Workflowを作っていたんですが、当時多忙でブログに書くのを忘れていました sweat

CircleCIで利用するProject数が増えると、それぞれのページに移動するのが めちゃくちゃ面倒なので、CircleCIのProject移動が簡単になるAlfred Workflowを作りました。

インストール方法、使い方はREADMEを見ていただくことにして、 どんな感じで動作するのかgif animationにしてみました。

Projectページを開く

URL情報をcacheしているので、サクサク動作します。

各Projectのmasterブランチのstatusを確認する

その都度APIを叩いて確認しているので、レスポンスが遅めです。

CircleCIとAlfredを利用している方は是非ご活用ください。

「サーバ/インフラエンジニア養成読本 DevOps編」にて[CircleCIによる継続的インテグレーション入門]を執筆しました

サーバ/インフラエンジニア養成読本 DevOps編 [Infrastructure as Code を実践するノウハウが満載! ] (Software Design plus)

2016/02/26 に出版される「サーバ/インフラエンジニア養成読本 DevOps編」というムック本にて、特集「CircleCIによる継続的インテグレーション入門」を執筆しました。

CircleCIによる継続的インテグレーション入門

私が現在所属するKaizen Platform, Inc.でもCircleCIをヘビーユーズしており、サーバ/インフラ部分においても、

  1. インフラCI
  2. 稼働中サーバへのプロビジョニング
  3. DNSレコードの管理
  4. Terraformを用いたAWSリソースの管理
  5. Packerを用いたAMI作成
  6. 稼働中サーバのセキュリティアップデート
  7. メトリクスグラフの取得&slackへの投稿

などにCircleCIを利用しており、今回はその中のインフラCI稼働中サーバへのプロビジョニング 部分を入門用に噛み砕いて書いてます。

Kaizen Platform, Inc.におけるインフラの継続的デリバリー、インテグレーションについては技術顧問である伊藤直也[email protected][email protected]理解が深まるかと思います。

既存環境に組み込みやすいように

本特集では下記のサービス、ツールを利用しています。

ツール名 役割
VirtualBox ローカル環境にテスト用VMを起動
Vagrant テスト用VMの管理とssh接続情報の生成
knife-solo プロビジョニングの実行
Serverspec テスト用VMのプロビジョン結果のテスト
Terraform DigitalOcean上へのテスト用VM作成
CircleCI GitHubと連携しビルド/CIを実行
GitHub インフラコードの管理
DigitalOcean インフラCIのテスト用VMの作成環境


特集内でも説明をしていますがそれぞれを疎な状態を保つように利用しているので、組み替えやすく、別のサービス、ツールを利用していても取り入れやすいのでは無いかと思います。

HashiCorp tools

今回VagrantTerraformを利用し、ローカルでのテスト環境、インフラCIを実現しています。Vagrantはすでに定番ツールとなっておりますが、Terraformについてはまだまだの印象がありますので、インフラCI用の使い捨てVM管理を通じ、Terraformの感触を掴んでいただければ幸いです。

目次

それぞれの特集が独立しており、好きなところから読んで、手を動かして試せる内容となっています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
巻頭企画 DevOpsとInfrastructure as Codeの概要
吉羽 龍太郎
第1章 DevOpsとは?
第2章 Infrastructure as Codeとは?

特集1 最速攻略!Ansible 2によるサーバ構築
新原 雅司
第1章 Ansibleの基本
第2章 Playbookの基本
第3章 Ansible[実践]
第4章 Playbookベストプラクティス

特集2 CircleCIによる継続的インテグレーション入門
前田 章
第1章 インフラのテスト入門
第2章 ローカル上でのテスト駆動インフラ
第3章 インフラCIの準備
第4章 CircleCIを利用した継続的インテグレーション
第5章 継続的インテグレーションから継続的デリバリーへ

特集3 Dockerによる仮想環境構築とKubernetesによるDockerクラスタ管理
馬場俊彰
第1章 Dockerの基本
第2章 Dockerを使ってみよう[基礎編]
第3章 Dockerを使ってみよう[応用編]
第4章 クラスタ管理ツールとは
第5章 Kubernetesの基本
第6章 Kubernetesクイックスタート
第7章 Kubernetesを詳しく見てみよう

正誤表

TerraformのDownload URLが発売直前のこのタイミングで変更になってしまい(泣)、一部コードがそのままでは動かなくなっております。詳しくは技術評論社様のサイトでご確認ください

最後に

担当した特集で利用しているServerspecの作者であるmizzyさんの紹介で特集が実現し感謝です。 担当した特集部分のレビューにご協力頂いた @tnmtさん、@kenjiskywalkerさん、@satoryuさん、ありがとうございました。

余談ですが今回の執筆にあたり、CircleCIにいろいろと問い合わせをしていたところステッカーとTシャツが送られてきて、CircleCIにも感謝です! / Thanks CircleCI !!

A photo posted by Akira Maeda (@glidenote) on


本書がビジネスに貢献するITインフラの役に立つ1冊になれば幸いです。

追記 2月26日追記

本日2016年2月26日(金)発売で、今現在カテゴリー別1位になっているようで、ありがとうございます!