continuous delivery 6

37
大大大 Delivery #6 @ShinyaOzawa

Upload: shinyaozawa

Post on 26-May-2015

726 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Continuous delivery 6

大崎的 Delivery #6

@ShinyaOzawa

Page 2: Continuous delivery 6

6.1 導入• 目的• ビルド・デプロイメントツールに共通した原則の

概要や情報、コツや小技、更なる情報への参照• スクリプトによる環境管理• 11 章「基盤と環境を管理する」で扱う

• 使い続けるものだから注意深く設計、保守しなければいけない

• Rails なら、 Rake などを使えば動かすのは簡単

Page 3: Continuous delivery 6

6.2 ビルドツールの概要 (1/2)

• 共通– タスクが正しい順序で実行され、依存してい

る各タスクが正確に一度だけ実行される– 依存関係のネットワーク内にあるタスクをす

べて実行する• 本質的な性質

– 「実行内容」「依存する別のタスク」

• ツールによる相違点– タスク指向 or プロダクト指向

Page 4: Continuous delivery 6

6.2 ビルドツールの概要 (2/2)

• タスク指向– 依存関係をタスクの集まりとして記述– たとえば、 Ant• 記述したタスク ( テスト含 ) がすべて一度だけ実

行• プロダクト指向– プロダクト ( 最終形体 ) から依存関係を記述– たとえば、 make• 修正されたファイルが含まれるプロダクトをビル

Page 5: Continuous delivery 6

6.2.1 Make

• 強力なプロダクト指向ビルドツール• コンパイル時間削減に寄与• 欠点– 大規模だと Makefile の管理が大変– シェルに依存

• 今は Scons が好んで使われている– ただ、 Autotools を使った make install に当たる処理な

どは個別に書く必要がある– Autotools

• OS 依存性を吸収してくれるツール郡 (configure 作るときとか )

Page 6: Continuous delivery 6

6.2.2 Ant

• タスク指向のビルドツール• Java の呼び出しが簡単に書ける• 欠点– XML が難解– 定型処理を書くのに時間を要する?– antcall が混乱を引き起こす

• タスクからタスクを呼び出すタスク– ビルドプロセスの情報が取得できない– Import 、 macrodef が新人ユーザに理解されな

い?

Page 7: Continuous delivery 6

6.2.3 NAnt と MSBuild

• Java 開発者が NAnt を作成• Microsoft が NAnt の純正マイナー版を提

供– MSBuild になった

• 欠点は Ant と一緒

Page 8: Continuous delivery 6

6.2.4 Maven

• タスク指向のビルドツール• Convention over configuration の原則

– http://knowledge.sorich.jp/?Java%2FMaven%2FMaven%E3%81%AE%E7%89%B9%E5%BE%B4 ( 引用 )

• 依存を勝手に解消してくれる• Ivy を Ant のタスクに入れれば依存関係の解消は可能• 欠点

– 規約に従ってないことが困難– 拡張するのが大変だが、大概はプラグインがある– 依存ライブラリの自動更新

• 13 章「コンポーネントや依存関係を管理する」で詳細

Page 9: Continuous delivery 6

6.2.5 Rake

• プロダクト、タスク両指向なビルドツール

• Ruby でタスク拡張ができる• Ruby 以外でも使える?• 欠点– クロスプラットフォームではない• JRuby が急速?に人気を獲得してる理由

– RubyGems が必須

Page 10: Continuous delivery 6

6.2.6 Builder

• プロダクト指向フレームワーク&インクリメンタルなビルド

• Rake でできることはすべてできる• Maven と同じ規約• Ant タスクも使える• Maven より高速• 欠点– タスク拡張が極めて困難

Page 11: Continuous delivery 6

6.2.7 Psake ( 酒 )

• タスク指向ビルドツール• Windows ビルドツール– PowerShell で書かれている

• 依存関係は解消してくれる

Page 12: Continuous delivery 6

6.3 ビルドスクリプトとデプロイメントスクリプトの原則とプラクティス

• 一般的な原則とプラクティスの紹介• どのテクノロジーでも適用できる

Page 13: Continuous delivery 6

6.3.1 デプロメントパイプラインのステージそれぞれに対してスクリプトを

書け• ドメイン駆動設計で作れ?• 肥大化したら、ステージ毎に分ける

(p158)– コミットスクリプト– 受入テストスクリプト– 非機能要件スクリプト

• スクリプトはソース同じリポジトリにバージョン管理する

Page 14: Continuous delivery 6

6.3.2 アプリケーションをデプロイするのに適切なテクノロジーを使え

• 疑似本番環境へのデプロイも自動化されていることが重要

• 一般的なミドルウェアには付属しているツールがあるので、それを使用しなければいけない

• デプロイするのは関係者全員– デプロイツール設計は最初から全員で考える

• ツールは、アプリケーションのアップグレード、サービス停止、 DB の更新などもできなければいけない

Page 15: Continuous delivery 6

6.3.3 すべての環境にデプロイするのに、同じスクリプトを使え

• あらゆる環境にデプロイするのに、同一のスクリプトを使う (p159)

• 外部連携 URI などは設定情報としてスクリプトと別に管理する– デプロイメントスクリプトから検索できるこ

と• 「アプリケーションをローカルで実行で

きるようにするために投資しない理由をどう正当化するか?」?

Page 16: Continuous delivery 6

6.3.4 OS のパッケージングツールを使え

• OS のパッケージングテクノロジーを使うことを強く勧める– deb とか RPM

• パッケージングを使えば、 Puppet 、 CfEngine 、 Marimba に簡単に載せれる

• 多層アーキテクチャの場合も、各々でパッケージを作る• バイナリのパッケージングは自動化されていなければならない• Rails なら RubyGems だが、できるとこは OS の標準的なパッケージ管理に従った方がよい

• CPAN はプラットフォームの差異を自動で変換する– CPAN 最強– cpanm もあるし– perlbrew もあるし

Page 17: Continuous delivery 6

6.3.5 デプロメントプロセスが冪等であることを保証せよ

• 冪等– 何度やっても同じ結果

• 正しく動くとわかっているベースラインから開始する?– 適切なミドルウェア、アプリケーションが動作する設定などすべて含まれなけ

ればいけない• 差分デプロイではなく、スクラッチでデプロイしたほうがいい

– 例外 1) クラスタシステムの場合、全体を同時デプロイすることに常に意味があるわけれはない ( クラスタとか全く関係なくね? )• p321 「カナリアリリース」• 炭鉱のカナリア

– 例外 2) コンポーネント毎にアプリケーションが分かれてて、本番のコンポーネントと組み合わせテストが完了している場合

• rsync とか使ってもファイル単位で保証できる• Puppet は設定分析をし、望ましい状態と同期するために必要な変更だけ

を行う– 11 章「基盤と環境を管理する」

Page 18: Continuous delivery 6

6.3.6 デプロイメントシステムをインクリメンタルに進化させよ

• シンプルでインクリメンタルなステップの集まり

• すべてのステップを完了させなければいけないわけではない

• 開発環境から順序立てて、スクリプトを作っていき、運用担当者に共有したりフィードバック受けたりで、最後は本番環境にも同じスクリプトでデプロイできるようにする

Page 19: Continuous delivery 6

6.4 JVM を対象としたアプリケーションのためのプロジェクト構造

• Java プロジェクトの標準的なレイアウト説明

Page 20: Continuous delivery 6

6.4.1 プロジェクトのレイアウト

• Maven 標準ディレクトリ構成の紹介• 6.2.4 参照

Page 21: Continuous delivery 6

6.4.2 ソースコードを管理する• ファイルのパッケージ名と同じ名前のディレクト

リにファイルを格納?– あたりまえってか、それ以外でどうやんだ?

• 1 ファイル 1 クラス• 命名規則に従う• CheckStyle 、 FindBugs で上記規約をコミットス

テージで強制する• 生成される定義 (!= config) 、メタデータは src に

含めない– target において、 clean で削除できるようにする

Page 22: Continuous delivery 6

6.4.3 テストを管理する• テスト用はすべて test/[language] に置く• 単体テストコードはソースコードと同じ

パッケージ階層で作る• その他のテストは、別パッケージに置け

るが普通は同じディレクトリに置く– ビルドスクリプトでフィルタリングを行い、

テストを別々に実行できるようにすればいい

Page 23: Continuous delivery 6

6.4.4 ビルドの成果物を管理する

• Maven はビルド結果を target に格納する– バージョン管理にコミットしてはいけない

• ビルドプロセスは、最終的に JAR 、 WAR 、 EAR のかたちでバイナリを生成する

• 別コンポーネント用 ( 提供ライブラリ ) に別の JAR を提供してもよい– 13 章「コンポーネントや依存関係を管理する」

• JAR を複数生成するポイント– アプリケーションのデプロイメントをシンプルにする– ビルドプロセスを効率的にし、依存関係の複雑さを最小化する

• プロジェクトは一定のサイズに抑えれば、保守、管理がしやすくなる

Page 24: Continuous delivery 6

6.4.5 ライブラリを管理する• 管理するパターンは 2 つ– Maven や Ivy に完全に委譲– lib ディレクトリを作り、そこにコピーしとく

• より洗練されたアプローチ–組織内でリポジトリを作り、あらゆるプロジェク

トで必要となるライブラリを格納しておくこと• 13 章「コンポーネントや依存関係を管理する」

• Ivy や Maven は本番筐体に置くな– 本番でコンパイルすな!

Page 25: Continuous delivery 6

6.5 デプロイメントスクリプト (1/2)

• 原則「テスト環境や本番環境の変更は、必ず自動かされたプロセスを通じて行わなければならない」

• デプロメントをスクリプト化するやりかたは 3 つ– システムが単一の筐体で実行されるなら、その筐体でローカルに実施する必

要なものをすべて行うスクリプトを書く– 大抵は別々なので、コンポーネント毎に分ける

• データベースアップグレード• アプリケーションサーバにバイナリをデプロイ• アプリケーション依存のサービスをアップグレード

– rsync 、 scp を使ったバイナリをコピーし、 ssh を使ってコマンドを実行• リモートデプロイのやり方は 3 つ

– 各筐体にログインしてコマンドを実行– エージェントを使って各リモートで実行 (次ページ )– プラットフォーム毎に適切なパッケージング技術を使って配布? (次ページ )

• これが一番強力

Page 26: Continuous delivery 6

6.5 デプロイメントスクリプト (2/2)

• プラットフォーム毎に適切なパッケージング技術を使って配布– ControlTier 、 BMC BladeLogic のようなデプロイメントツー

ル、 Marionette Collective 、 CfEngine 、 Puppet のような基盤管理ツールは適切なバージョンがインストールされていることを保証してくれる• 11 章「基盤と環境を管理する」

– アプリケーションデプロメント管理と基盤管理の両方で同じツールセットが使える

• エージェントモデル& CI の利点– 作業削減

• チェックインして、 CI サーバを使ってリモートデプロイ– CI サーバがプロセス管理を見える化してくれる– CI サーバがリモートアクセスするので、本番にログインしないなどの

セキュリティが保たれる– エージェントモデルうんぬんじゃなくて、 CI サーバの話

Page 27: Continuous delivery 6

6.5.1 デプロイレイヤとテストレイヤ

• 「適正であることがわかっている土台の上にシステムを構築するよう努力せよ」– コンパイルできない変更をテストしない– コミットテストに失敗した変更をテストしな

い• むしろできなくね?

• ソフトウェアをレイヤ状に考える

Page 28: Continuous delivery 6

6.5.2 環境設定をテストする• 各レイヤをテストして、問題が起きたらすぐに失敗させる

– 問題の明確化• 極めてシンプルなスモークテストを行い、主要なリソース

があることを確認する– スモークテストは、度正常な簡易テスト– p378 「基盤やアプリケーションを監視する」

• スモークテストの例– DB からレコード検索– Web サイトであれば 200 OK– メッセージブローカーにメッセージ送信– ファイアウォール経由での ping– ラウンドロビンができているか

Page 29: Continuous delivery 6

6.6 コツと裏技• 解決策や戦略の一覧化

Page 30: Continuous delivery 6

6.6.1 常に相対パスを使え• 絶対パスを使わない?

– ソフトウェアをレイヤに分けた時に、 OS 層まで入ってなかったっけ?

• すべてにおいて相対パスを使えば、すべてが正しい場所に置かれていることが保証できる?

• 絶対パスを例外– ハードコードされたパスに依存する 3rd ライブラリ

• アプリケーションもシステムのパッケージングツールを使って、 FHS などの規約を強制する– 標準的じゃない場所へのインストールは、設定システムのオ

プションを使う– 2 章「構成管理」

Page 31: Continuous delivery 6

6.6.2 手作業を根絶せよ• 手作業は絶対ミスるし、個人に頼る部分

が多い• 「同じことを 2 回やることになったと

き」は、プロセスの自動化をする

Page 32: Continuous delivery 6

6.6.3 バイナリからバージョン管理へのトレーサビリティを組み込め

• バイナリから生成元のバージョンがわかることは、とても大切– .NET ではアセンブリにメタデータを組み込め

る– JAR もマニフェストファイルにメタデータを

含めることができる• 他のやりかた– 各バイナリの MD5 をリビジョンと一緒に DB

に格納する

Page 33: Continuous delivery 6

6.6.4 ビルド時にバイナリをバージョン管理にチェックインするな

• バイナリが独自のリビジョン番号を持つので混乱する

• その代わりに、バイナリとレポートを共通のファイルシステムに置く?

• ソースから再生成できなければ、構成管理を改善する

• 一般的なルールとして、ビルド、テスト、デプロイメントで生成されるものはチェックインしない– CI でビルドをトリガーとしてリビジョンを紐づけておく

Page 34: Continuous delivery 6

6.6.5 テストが失敗してもビルドは続けよ

• 続けるという意味は、失敗したことを記録し、ビルドプロセスの最後で各タスクの失敗をレポートすればよい

• 各タスクでビルドプロセスを止めると、次のタスクの結果が分からない

• Nant 、 Ant では failure-property で制御できる

Page 35: Continuous delivery 6

6.6.6 統合スモークテストでアプリケーションに制約をかけよ

• アプリケーションが不正な状態であれば、停止する– デプロイスクリプトでデプロイするときに、

正しいマシンかどうかをチェックしてもよい• バッチの話があるが、外部連携とかテス

ト起動できないようなのはどうすればいいんだ?

Page 36: Continuous delivery 6

6.6.7 .NET のコツと裏技• .NET のプロジェクトファイルには、実際にビ

ルドするファイルへの参照が含まれる– ファイル消してもダメなときがある– Windows では「隠しファイルを表示する」機能を

ON にする• 理想はソリューションから消した時に一緒に

消してくれるといいが・・・• bin 、 obj も悪さするから消したほうがいい?– 「 clean solution 」コマンドを打てばいい

Page 37: Continuous delivery 6

6.7 まとめ• ビルド、デプロイメントプロセスをガイ

ドとして使ってスクリプトを集める– 自動化は少しずつ進める–何度も繰り返しやって、自動化してく

• スクリプトはデプロイする唯一の方法としなければいけない