リリースサイクルは、「継続的に配布すること」つまり、Continuous Deliveryの実践です。
今回のアメブロリニューアルでは、ブランチやプルリクエストを活用し、リリースと確認を行いました。リリースは、「通常リリース」と「ホットフィックスリリース」に分けられます。
新しい案件などの変更を取り込みたいときには、「通常リリース」となります。このリリースは週1回行います。それ以外のバグフィックスなどのリリースは、チームリーダーの判断により「ホットフィックスリリース」を随時行います。
リリースバージョンはSemVerを採用し、通常リリースの場合minorバージョンを上げます(例 v1.1.0 → v1.2.0)。ホットフィックスリリースはpatchバージョンを上げます(例 v1.2.0 → v1.2.1)。
「通常リリース」の際に、まずリリース担当者がdevelopブランチからrelease/vX.XX.XXのようなブランチを作成し、package.jsonのバージョンを修正し、GitHubにプッシュします。Circle CIはGitHub上のreleaseブランチを自動的に検知し、テストを行い、確認用Dockerイメージをビルドし、「準本番サーバ」にデプロイします。確認用Dockerイメージのタグは「日付 - Git Rev」の形です(例:20170401-6c96bc5)。
それと同時に静的なファイルもCDNに上げます。ここでreleaseブランチの名前とpackage.jsonのバージョンはわざと重なるようにしていますので、一致しないとテストが通りません。
デプロイには多少時間がかかるので、この間にリリース担当者がreleaseブランチからmasterへプルリクエストを作っておきます。プルリクエストの内容は、ツールで簡単に生成できるChangeLogであり、必要な作業は、各ChangeLogの項目の前にチェックボックスを入れてチェックできるようにするだけです。
「準本番サーバ」へのデプロイが完了したら、全員「準本番サーバ」で確認を行い、各自担当の項目をチェックします。確認が終わり次第、masterにマージし、Circle CIは本番デプロイ用のDockerイメージ(SemVerタグ)をビルドします。ビルド後、もう1回「準本番サーバ」に上げ、静的なファイルなどが正しく反映されるかどうか確認します。
確認の際に不具合を見つけたら、直ちにIssueを作ってリリース分と同じマイルストーンに入れ、リリース担当者に連絡します。もしくは担当者がマイルストーンの残タスク数を確認し、リリースを止めるようにし、修正が終わり次第リリースを再開します。将来的にこの部分は自動化する予定で、マイルストーンにリリース分のプルリクエスト以外のIssueがある場合、リリースビルドが通らないようにします。
masterブランチのビルドにより、Circle CIは自動的にタグをGitHubにプッシュします。リリース担当者はプッシュされたタグの内容を編集し、きれいなリリースノートを作ります。
リリースサイクルの段階は「準本番サーバ」までですので、「本番サーバ」への影響はありません。「本番サーバ」への反映は運用サイクルで行います。
最後に、「本番サーバ」での確認のために、masterからdevelopへの「バージョン取り戻し」というプルリクエストを作成しておき、もう一度、変更分とチェックボックスを入れます。これで「通常リリース」が終わります。
「ホットフィックスリリース」フローは「master => hotfix/vX.XX.XX => master」となり、リリース手順は「通常リリース」と一緒です。
GitHubとCircle CIを連動し、リリースをスムーズに行うこともできます。それに各段階で確認作業を設けていることにより、サービスの安定性も担保できるようになりました。しかし、リリースノートの入稿やマイルストーン残タスク確認など、リリース担当者に対してまだ負担となる作業が残っています。それを軽減するため、変更内容の作成などの単純な作業の自動化が今後の課題になっています。
ちなみに、「リリースサイクル」からDockerの話に入りましたが、実は本番サーバ環境と一致させるためにCircle CI上のビルドとテストは全てDockerで行っています。
今回の「アメブロDevOps」では、継続的デプロイメント(Continuous Deployment)は実践できませんでした。リリースサイクルをなくし、随時、本番サーバにデプロイでき、完全に開発サイクルと運用サイクルを結合することが理想的な状況でしょう。しかし、この理想にたどり着くためには、関連者との連携や厳密なテストと監視などを取り込むことが大事になります。従って、リリースサイクルをどんどん小さくすることが今後の課題となっています。
運用サイクルは、本番用Dockerイメージを使い、本番サーバへのデプロイ、そして常に稼働状況を監視することで構成されます。リリースサイクルで準備ができ次第、本番サーバへのデプロイが始まり、運用サイクルに入ります。
アメブロでは、デプロイ専用のリポジトリを用意しています。デプロイ担当者がバージョンを指定し、本番デプロイ用ブランチをプッシュして、Circle CIが1台目の本番サーバに上げます。そこで監視項目を確認した上で、ブランチをデプロイリポジトリのmasterにマージし、Circle CIがサーバ全台にデプロイし始めます。
デプロイするツールとして、現在アメブロは「Rancher」を採用しています。
デプロイ後、全ての関係者は、リリースサイクルで作られた本番確認用のプルリクエストで、本番確認を行います。さらにデプロイの途中では、Rancherで進捗(しんちょく)を確認でき、「New Relic」「Datadog」でサービスとDockerの稼働状況も確認できます。毎回リリースした後、「SpeedCurve」で自動的にテストし、前回のデプロイと比較したフロントエンドの実行速度の変化をSlackで通知します。
インフラ側の監視は「Sensu」を使っています。NewRelic、Datadog、Sensuを併せて使うことにより、サービス、Docker、インフラを全部監視でき、いったん障害が起きると、即時にSlackやメールにアラートが飛んできます。
運用サイクルのフィードバックの一環として、アラートが発生したときには、サーバ担当者の判断により、ほとんど即時での障害対応が必要となります。もし即時対応する必要がない場合、Issueを作成して全体サイクルに任せます。
Dockerの導入により、まずNode.jsをデプロイする際の統一性が保証できました。
かつてNode.jsをリリース前にビルドして、リリースの当日にライブラリバージョンアップまたはライブラリのリポジトリ通信障害により、リリースが失敗したことがありました。Dockerを使えば、ライブラリのバージョンに左右されることなくデプロイができます。それにデプロイ途中またはデプロイ直後に不具合に気付いたら、即時に切り戻すことができます。
安定的なサービスにするため、障害時の対応時間をできる限り短縮しなければならなりません。自動復旧など自動化を導入することにより、サーバ担当者の負担を軽減できますし、サービスの復旧時間も短縮できます。Dockerを導入することにより、サーバが落ちたときにも自動復旧できています。
さらに、Dockerイメージをデプロイするだけでサービスが立ち上がるので、トピックスにより急にアクセス量が増える際には、増設も簡単になり、スケーラビリティが大幅に向上しました。
今回は、2016年のアメブロフロントエンドリニューアルとともに採用されたDevOpsの取り組みを紹介しましたが、いかがだったでしょうか。
リニューアルしても、何年か経てばまた古くなるでしょう。しかし、「CAFE」というDevOpsフレームワークを使うことにより、全体のDevOpsを幾つかのサイクルに分けて設計し、サービスを安定させながらどんどん進化させ続け、常にモダンな状態を維持することは、われわれが最も重視していたことです。その進化により、時代に合った技術の利便性やスピードを実感できます。そうすることで、エンジニアのモチベーションを高く保ち、最高な環境になることを目指しています。
次回は、Isomophic JavaScriptの独特なパフォーマンス・チューニング手法についてお伝えする予定です。
Copyright © ITmedia, Inc. All Rights Reserved.