弥生 Advent Calendar 2021 6日目の記事です。
システム開発部Misocaチームエンジニアの mizukmb です。
クラウド請求書作成ソフトであるMisocaのインフラはサービス稼動開始からつい最近までAWS EC2を使ってアプリケーションを運用していましたが、この度Dockerコンテナ管理サービスであるECSに移行し、この移行作業がほぼ完了致しました 🎉
ECS移行に際しては長い時間をかけて準備や検証を行っており、開発者ブログで紹介したいネタがいくつかあるのですが、今回は実際にEC2で稼動するappサーバを無停止且つ段階的にECSに移行した方法について紹介したいと思います。
ECS移行前の状態と作業の概要
移行前のMisocaアプリケーションのインフラは複数台のEC2インスタンス上で稼動しており、各EC2インスタンスへのリクエスト振り分けはALBを使って制御していました。ドメインとALBの紐付けはRoute53のエイリアスレコードを利用しています。
移行後はEC2インスタンスが複数のECSタスクに、ALBもEC2用からECS用の新規ALBリソースに置き換わります。この移行作業の準備としてMisocaアプリケーションのコンテナ化やECSサービス・タスク定義の作成、ECS用のALBの用意を事前に行いました。
移行作業は以下の点を重視し、これらが実現できる方法について調べました。
- サービスの停止時間を作らずに移行作業ができる
- 一気にECS環境に切り替えるのではなく、カナリアリリースのように段階的にECS環境を本番に投入して負荷状況等を監視したい
- 段階的に投入する事でECSもしっかり本番環境でサービスが提供できているという安心感を得たい 1
- 万が一ECS起因の障害が発生したとしても影響を最小限にしつつ素早くロールバックできるようにしたい
こちらについてAWS Japan ソリューションアーキテクトの方に技術相談をしたところ、Route53の加重ルーティング (Weighted routing) 機能について教えていただきました。 2
Route53加重ルーティング機能について
正確な機能紹介についてはAWSドキュメントを読む事が最も良いので、ここではざっくりとした紹介をします。
Route53の加重ルーティング機能は、同一レコード名で登録し、重み (Weight) を各レコードで設定する事でその重みに応じた割合でリクエストを振り分けることができます。振り分け方法はラウンドロビン方式です。また、片方の重みを0にする事で設定したレコードへリクエストが振り分けられなくなり、もう片方のレコードに全てのリクエストが振り分けられるようになります。
例えば、 hoge.example.com
への振り分けを EC2:ECS=30:70
としたい場合は以下のように重みを設定しそれぞれレコード登録します。
レコード名 | ルーティングポリシー | 重み | ルーティング先 |
---|---|---|---|
hoge.example.com | 加重 | 30 | EC2用のALBドメイン |
hoge.example.com | 加重 | 70 | ECS用のALBドメイン |
この重みを変更する事でリクエストの振り分ける割合を柔軟に設定が可能になります。
無停止・段階的に移行するための作戦
行う事はシンプルで、加重ルーティングで設定する各レコードの重みを編集して少しずつ EC2:ECS=100:0
な状態から EC2:ECS=0:100
にすれば作業は完了します。
MisocaチームではインフラをTerraformで管理しているので、Route53レコードの設定や重みの変更はTerraformコードを修正し、プルリクエストの作成とコードレビューを経て terraform apply
を実行し適用するという流れでした。
重みの変更によるアプリケーションの停止時間は発生しないので、この値が間違っていないか十分注意していれば簡単に無停止・段階的な移行が可能になります。
実際の移行作業ですが、最初は EC2:ECS=95:5
の割合から始めて、1〜2日様子を見てECS側の重みを増やして EC2:ECS=70:30
にする。さらに様子を見てECS側の重みを増やして…といった作業を繰り返していき、約1週間程かけて EC2:ECS=0:100
な状態に移行し、サービスの稼動に影響が無い事を確認できました。
おわりに
MisocaのアプリケーションインフラのEC2からECSへの移行にRoute53の加重ルーティング機能を活用した話を書きました。
ECS移行に関する知見についてはまだまだあるので、できる限り開発者ブログで紹介したいと考えています。
弥生 Advent Calendar 2021 では弥生のエンジニアが様々な内容で記事を公開しますのでぜひ他の記事もチェックしてみてください!
採用
積極採用活動中です!!
付録:最初に考えてた作戦内容と却下理由
ALBのリスナールールではリクエストを転送するターゲットグループの重み付けができるため、最初はALBのレイヤで無停止・段階的な移行を進めるつもりでいました。
しかしながら、ECS環境のデプロイはCodeDeployのBlue/Greenデプロイメント機能を使っている関係からこの案は技術的に不可能である事がわかりました。理由ですが、CodeDeploy Blue/Greenデプロイメント機能を実行するとCodeDeploy内部でリスナールールに紐付くターゲットグループをBlueからGreenに付け替えるといった事を行っており、実質リスナールールの転送先はECSに固定されてしまうためです。
CodeDeploy Blue/Greenデプロイメント機能を使わなければこの案で進められますが、これのためにBlue/Greenデプロイを止めるのは割に合わないと判断したため却下となりました。