LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログ

Hubot + Jenkins + Mackerelを利用したデプロイの見える化

弊社では最近、今更ながらHubotを利用したデプロイを行うようにしました。

なぜ今更ながら取り組んだのかも踏まえて、構成などを簡単に紹介いたします。

導入の背景

Hubot導入前は、以下のような流れでデプロイを行っていました。

  1. デプロイ担当者が、Google Analyticsのアクティブユーザを確認
  2. アクティブユーザが規定の数より少なければ、Jenkinsのビルドを手動で実行

この方法でも手間はそれほどかからないのですが、チーム・サービスの拡大によっていくつか問題が見えてきました。

ミスが起こりやすい

運営するサービス数の増加に伴い、Jenkinsのデプロイビルドも増えてきました。そうすると、弊社サービス「夜行バス比較なび」のデプロイをする際に、別サービス「格安移動」のデプロイビルドを実行してしまうなど単純なミスが発生するようになりました。

状況が見えない

最近リモートワークを行うメンバーが増え、Chatworkがコミュニケーションの主体となっています。そのため、前述のようなミスが発生したとき、以下のような状態になってました。

デプロイ担当: 夜行バス比較なびのデプロイします。
私: お願いします。
・・・
私: 格安移動のデプロイビルドが実行されているみたいですけど、間違ってないですか?
・・・
・・・
私: 大丈夫でしょうか?
・・・
デプロイ担当: 間違って実行してしまったので確認してましたが、特に悪影響ありませんでした。

この場合、リモートのメンバーは特に状況が見えづらく、不安になることが定期的に有りました。 このような問題から、ミスが発生しづらく・状況が見えるデプロイの仕組みへ変える必要があるとの考えに至りました。

デプロイ構成

f:id:lcl-engineer:20161024003432p:plain

  1. Chatworkでデプロイを命令を行う。
  2. Hubotがmackerelから現在のサイトのリクエスト数を取得する。
  3. HubotがJenkinsのデプロイビルドを実行する。
  4. Jenkinsが各サーバに対してデプロイを実行する。

各サイトのNginxのログは、エラー数の監視のためmackerelに随時送信しており、mackerel APIを利用してデプロイ時点でのリクエスト数を取得しています。リクエスト数が規定より多い場合は、デプロイを控えるようにしています

Chatworkでのやりとりは、以下のようになってます。

f:id:lcl-engineer:20161030172757p:plain

構築手順

Hubotのインストールや、基本的な利用法は割愛します。

ChatworkとHubotの連携

Chatwork APIを利用するためには申請が必要です。かれこれ2年以上プレビュー版ですが、問題なく使えます。以下のサイトから申請して、APIトークンを取得します。

チャットワークAPIドキュメント

ChatworkとHubotの連携は、adapterが用意されているのでそれを利用します。

npm install hubot-chatwork --save

環境変数にChatwork APIの情報を設定します。

# 取得したAPI TOKEN
export HUBOT_CHATWORK_TOKEN="XXXXXXXXXXXXXXXXX" 
# 監視するルームID。カンマ区切りで複数指定、botユーザをルームに所属させる必要あり。
export HUBOT_CHATWORK_ROOMS="111111,22222" 
# 1時間当たりのリクエスト数。APIは、5分間100回までの制限あり。
export HUBOT_CHATWORK_API_RATE="500"

以下のコマンドで実行。引数 -n でbot名称を設定

bin/hubot -a chatwork -n hubot

正しく設定が行われていれば、ping に応答があります。

f:id:lcl-engineer:20161030183455p:plain

mackerelとHubotの連携

事前に、Nginxのアクセスログをmackerelに投稿しておきます。

fluentdでサービスメトリックを投稿する - Mackerel ヘルプ

投稿したメトリクスは、APIで取得できます。

curl -X GET -H "X-Api-Key: <API_KEY>" "https://mackerel.io/api/v0/services/xxxxx/metrics?name=nginx_access_num.2xx_count&from=1476325055&to=1476325055"

サービスメトリック - Mackerel API ドキュメント (v0)

Hubotから直近の時刻を指定して上記APIを実行すれば、デプロイ時点でのアクセス数が取得できます。

JenkinsとHubotの連携

Jenkinsの認証を有効にしている場合は、以下の記事などを参考に外部からAPIを実行できるようにしておきます。弊社では、Hubot専用のユーザを作成し、限定されたビルドのみ実行を許可しています。

Jenkins のジョブを外部からビルドするには API Token を利用する - @kyanny's blog

HubotからJenkinsビルド実行は、以下のコードが利用できます。JOBのURLなど必要に応じて適宜修正します。

hubot-scripts/jenkins.coffee at master · github/hubot-scripts · GitHub

Jenkinsの情報は、Chatwork同様に環境変数に設定しておきます。

export HUBOT_JENKINS_URL="[JENKINS_URL]"
export HUBOT_JENKINS_AUTH="[ユーザID]:[パスワード or API TOKEN]"

以上でHubotと各サービスの連携は完了です。Hubotへの命令コマンドに応じて、適切な処理を組み合わせれば、デプロイまでの一連の流れが行えます。

導入の効果

見える化は、各自の行動にたよらず「強制的に見えるようにする」という仕組みづくりが重要ですが、以前までは、デプロイ担当者がチャットに状況を流していたので、結局は個々人による行動に依存していました。 今回、デプロイの全ての状況が"強制的に"チャット上に流れるようになったため、確実に見える仕組みが実現できました。

全ての流れが見えるようになったおかげで、まずデプロイが圧倒的にスムーズになりました。さらに、新しいメンバーでもどのようにデプロイが行われているかが、容易に把握できるようになりました。実際にやってみると、他にも応用したい案が多くでてきたので、今後もHubotを育てていきたいと考えています。

弊社では、エンジニアがより働きやすく・成長できる環境を日々検討していますので、ご興味がある方は是非採用ページからご応募お待ちしております。

株式会社LCL(エルシーエル)