継続的デリバリーと読み解く Web 開発あるあるとその対策
山邉 哲生
某外資系携帯メーカーの研究所 ↓
解散になったので大学に出戻り ↓
フィンランドで1年 ↓
渋谷で Web エンジニア(今ココ)
Web 開発の現場で起きている問題 と
カイゼンの取り組み
継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化 (アスキー・メディアワークス)
いつまで手動で デプロイしているんですか?
2年前の話
とあるサービス開発現場
Apache Tomcat
Struts / Java MySQL
開発用サーバー (dev)個人の開発環境 (local)
SVN リポジトリ
チェックアウト
開発&確認
コミット
アップデート
ビルド&確認
開発用サーバー (dev)
SVN リポジトリ
チェックアウト
ビルド&デプロイ (rsync)
本番用サーバー群 (live)
リリース
確認
何か問題でも?
ありすぎました
1. 君と僕の開発環境は違う
開発用サーバー個人の開発環境
SVN リポジトリ
チェックアウト
開発&確認
コミット
アップデート
ビルド&確認
Wiki に書かれた不完全な手順 誰もがはまるインストールエラー 構築するたびに変わるバージョン
『僕の環境なら動くんですけど』
© 地獄のミサワ (http://jigokuno.com/)
『僕の環境では動きません』
© 地獄のミサワ (http://jigokuno.com/)
君と僕の開発環境は違うし 開発用サーバーも違うし
なんなら本番だって違うかもしれない
止まらない不信感 終わらないデバッグ
あるプロジェクトで、本番環境へのデプロイメントが謎の失敗を起こすことがあった。デプロイメント用のスクリプトがハングしたのだ。原因を追跡した結果わかったのは、運用サーバーのログインシェルが sh に設定されているのに対してステージングサーバーでは bash になっているということだった …(中略)… 本当に微妙な違いを見つけるのは、これよりもずっと難しいことだ。総合的な構成管理は必須である。
コラム『構成管理がまずいとリリース当日にデバッグ作業をするはめになる』 (p351)
( ゚∀゚)・∵.グハッ!!
よくあることだが、開発者自身の作業端末はおろか開発チームの継続的インテグレーション環境でさえも職人芸になってしまっており、長期間にわたって粗雑な管理が続けられている。 これらの環境は、アプリケーションが実際に動作する環境と関連があるとはとても言えない状態だ。 非効率の根源にもなり得る。
11.4.1 サーバーのプロビジョニング (p349)
( ゚∀゚)・∵.グハッ!!
『構成管理』 『プロビジョニング』
2. 気まぐれなテスト
開発用サーバー (dev)個人の開発環境 (local)
SVN リポジトリ
チェックアウト
開発&確認
コミット
アップデート
ビルド&確認
勘と経験による打鍵テスト 既存機能を破壊する新機能
IE/Chrome/FF/iOS/Android … という多様な 機種をカバーする限界
trunk に混入し続ける動作しないコード
開発用サーバー (dev)
SVN リポジトリ
チェックアウト
ビルド&デプロイ (rsync)
本番用サーバー群 (live)
リリース
確認
リリースしてから気づいてバージョンを 戻して再デプロイ
機能が増える度に低下する サービス品質
機能が増える度に低下する コード品質
≒ 怖くてできないリファクタリング
明確でない受け入れ条件 (機能・品質)
『継続的に実行されるテスト』 『既存の振る舞いを保証する』
『不純物の混入を避けるプロセス』 『受け入れ条件』
3. オレオレデプロイ
開発用サーバー (dev)
SVN リポジトリ
チェックアウト
ビルド&デプロイ (rsync)
本番用サーバー群 (live)
リリース
確認
対象サーバーに入って rsync -> ビルド -> AP 再起動を行う独自スクリプト
似たような名前の様々なスクリプトが存在 (html_deploy.sh, app_deploy.sh, template_deploy.sh …)
作った人しかわからない 亜種スクリプトが量産される (e.g., html_deloy_bk_20140616.sh)
エラー検知が甘かったり rsync が同期しきれて
いなかったりする
各サービス・各サブシステムの デプロイがオレオレすぎてつらい
『手順どこでしたっけ?』
そこで取り組んでみたこと
個々人が、他者に影響されない 本番環境と同じ構成の開発環境を持つ
個々人が、他者に影響されない 本番環境と同じ構成の開発環境を持つ
開発用サーバー (dev)個人の開発環境 (local)
Web
AP DB
Web
AP
Web
APWeb/AP の動作環境を
揃えるのが大変
開発用サーバー (dev)個人のPC
Web
AP
DB
リモートログイン
何か障害や大きな負荷があると開発できなくなる
DB 共有するとスキーマの変更やテストがしづらい
開発用サーバー (dev)個人のPCWeb
AP
DB
Web
AP
DB
仮想環境
リポジトリ (git)
環境設定を手作業でやっているせいで個々の環境が微妙に異なってしまい、それが原因で問題が発生するということについてはすでに議論してきた。仮想化技術を使えば、本章で紹介してきたテクニック (サーバーや環境のプロビジョニングの自動化)の恩恵をさらに膨らませることができる。
11.7 仮想化 (p364)
http://www.vagrantup.com/
Vagrant
• VirtualBox や VMWare といった仮想化技術を開発用途に使いやすくするためのツール
vagrant init
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-6.5"
config.vm.network :private_network, ip: "192.168.33.10"
end
vagrant up/halt
vagrant destroy
おかしくなったら すぐ壊してやり直せる
個々人が、他者に影響されない 本番環境と同じ構成の開発環境を持つ
『構成管理』 『プロビジョニング』
http://www.getchef.com/chef/ | http://www.ansible.com/home
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-6.5"
config.vm.network :private_network, ip: "192.168.33.10"
config.vm.provision :ansible do |ansible|
ansible.playbook = "./roles/web/site.yml"
ansible.inventory_path = "./roles/web/hosts.local"
ansible.limit = 'all'
end
end
vagrant provision
• Ruby の DSL を利用
• opscode に登録された第三者のrecipe を再利用できる
• 結構タイトに構造化されている
Chef
• YAML でデータをいじるので Python を意識しないで良い
• ほぼ全部入でクライアントレス
• 柔軟なディレクトリ構造
Ansible
一元化された手順で 『自動的に』 環境構築する
ローカルで仮想マシンを立てて 何度もプロビジョニングして 最後まで通るようになったら
リポジトリに push する
環境のコーディング
Code as Infrastructure
http://serverspec.org/
Serverspec
• プロビジョニングコードをテストするためのツール
開発から本番まで一気通貫で 仮想マシンを活用した開発を
行うための試み
http://www.docker.com/
Docker• コンテナ型仮想化による軽量な仮想環境の提供
• 設計思想として1コンテナ1サービス
• 状態を保持しない ”使い捨て” イメージ (Immutable Infrastructure)
隔離 検査 破棄
再生成
これは、我々の知る限りで最も強力なリリース管理テクニックである。本番環境としてまったく同じ環境を2組用意するという考え方で、それぞれをブルーおよびグリーンと呼ぶ。
10.4.3 ブルーグリーン・デプロイメント (p319)
(キャッシュ目的とはいえ) ミドルやライブラリを構造化して
管理している Chef や Ansible とは 対象的にコマンドの羅列に なっている点が興味深い
定式化されたデリバリーフローを 定義する
trunk/master ブランチを守る
A successful Git branching model http://nvie.com/posts/a-successful-git-
branching-model/
x
GitLab x
コードレビュー
http://nvie.com/posts/a-successful-git-branching-model/
https://www.gitlab.com/
テスト・デプロイ自動化
Jenkins• 継続的インテグレーションを行うためのツール
• リモートマシン上でのテストを駆動したりメトリクスを可視化したりいろいろできる
Capistrano• デプロイ自動化のためのツール
• デプロイ対象のサーバーとそのロール、処理内容などを記述
• 過去履歴を保持してロールバックを行うこともできる
OS/MW => Chef/Ansible アプリ => Capistrano
http://capistranorb.com/
誰でも統一された手段でデプロイを 実行できる
誰でも安易にデプロイを 実行して既存環境を変更できてしまう
まだまだお話したいこと たくさんありますが
続きは Web で
たとえば 『アジャイル開発手法 (スクラム、
XP) の導入事例』 http://recruit.gmo.jp/engineer/jisedai/blog/20140509_agile/
まとめ• Web 開発の現場で活用されている技術についてご紹介しました
• Web サービスは作って終わりではなく、リリースしてからの開発・運用プロセスをいかに効率的・効果的に回すかが重要 (DevOps)
• 継続的デリバリーに興味を持った方は、ぜひアジャイル開発についても調べてみてください
ご清聴ありがとうございました