Edited at

AWSでのデプロイを考える(仕掛中)


なぜ

ちょっと特殊なデプロイ方法を採用してしまったせいでオートスケーリングの際にデータの同期が困難な状況。現状はEFSを複数のオートスケールしたEC2にマウントすることで同期自体をせずに運用している。

もともとは単体のサーバにウェブサーバとアプリケーションサーバの機能を、データベースのみ別サーバで運用していたが、アプリケーションサーバのバッチ処理の負荷が高まり、更にウェブサーバの負荷も波はあるが高まってレスポンスが非常に悪くなってしまった。

AWSへのリプレイスの際にバッチ処理と管理画面をまとめて1つのEC2に、ウェブサーバとアプリケーションサーバはオートスケールする構成に変更したのだが、ソースコードの同期をとる方法として、実際に同期をしなくて済むという安易な選択からNFSを採用した。

一方で、管理画面でアプリケーションのデプロイを管理する仕様なのだが、アプリケーションのマスターからrsyncでNFSへのデプロイに時間がかかる、デプロイしたアプリケーションのレスポンスが良くないなどの影響が出ていた。


問題点

デプロイに時間がかかる。NFS(EFS)マウントの方法をかなり模索したものの、あまり効果的な方法にめぐり会えず。最終的にNFSを利用せずデータを同期することで動作速度確保したい。

現状ウェブサーバのレスポンス取得に3-6秒ほどかかっている。NFSを利用しない場合には1秒ほどでレスポンスを取得できている。

マスターとなるサーバには管理画面のソースコードとアプリケーション自体のソースコードを配置。管理画面から各個別のアプリケーションをデプロイする。親アプリケーションから子アプリケーションをデプロイするようなイメージが近いかもしれない。子アプリケーションは親アプリケーションでバージョン管理などを行うため、サーバ内にのみ構築情報などが存在している。

現状はすべてのアプリケーションのソースコードがNFS上にあり、オートスケール時にマウントするだけで同期の必要はない。

NFSではない構成になった場合、オートスケーリング時にウェブサーバで各アプリケーションのソースコードを最新の状態への同期する必要があること、新規にアプリケーションを構築した際にすべてのウェブサーバで同期する必要があることの二点が重要になる。

オートスケーリング時の同期は、


  1. 子アプリケーションの構築、更新時にオートスケーリング時の起動テンプレートを同時に更新する

  2. スケーリングしたサーバで構築完了後にデータを更新する

上記いずれかで実現できるが、起動テンプレートを更新する作業とアプリケーションデータ自体の同期の作業とを比較すると後者のほうがシンプルに構成できる。



rsyncないしlrsync

lrsyncのメンテナンスがあまり期待できないので導入を躊躇。最近書かれたドキュメントなどもあるのだが、今後の運用を考えると重すぎる負債として残ってしまう可能性を捨てきれなかった。


codepipelines(codecommit + codebuild + codedeploy)

検証してみた。もととなるgitリポジトリのデプロイには利用できそうだしいつかは使用したい。オートスケーリングにも対応しているが、子アプリケーションはgit管理されていないため、すべてのアプリケーションを同期するとなるとかなり複雑な手順・構成になりそうだったので採用を見送り。


[採用] EC2->S3->Lambda->(EC2<-S3)

上の書き方だとよくわからないと思うので概略。

マスターとなるサーバから更新された子アプリケーションのソースをS3へ転送、S3のイベントをフックしてLambdaを実行、LamdaですべてのウェブサーバのIDを取得した上でEC2上のSSM Agentを利用してS3から同期を実行する。

最新のデータ格納用のS3とSSM Agent起動用のLambdaだけを新設すれば利用できる。

S3はオブジェクトストレージなので、シンボリックリンクをサポートしていない。そのためアプリケーション中にシンボリックリンクが必須の役目を果たす場合には単純にファイルを転送するのではなくzipなどで圧縮する必要があるのでこの点留意。


残った課題:オートスケーリング時の最新状態への対応

EC2->S3->Lambda->(EC2<-S3)の構成なら常に最新のデータがS3に上がっている。オートスケール実行時に起動したEC2が、まずS3内の最新データから同期を行えばよい。起動時に一回だけ作業をする場合、systemdを利用してネットワーク関連が起動を前提にS3から最新のデータを同期する。


子アプリケーションの同期手順

仕掛中なのでいずれ追記。

ロールを作ったり、SSM Agentは入っていたり自身で入れたりしなければいけない場合もあるので環境によって作業は多少異なる。