皆さんこんにちは。SREチームの安達(@adachin0817)です。去年10月にMENTAがランサーズにグループジョインされて、本日AWSへ移行が完了しました。この5ヶ月間どのような取り組みをしたか、改めて振り返ってみようと思います。
AWSへ移行する前
移行前の環境
・https://menta.work
・さくらのクラウド
・PHP 7.2 / Laravel 5.5
・Nginx / MariaDB /Redis
・SendGrid
・開発環境
・Docker
・リリース方法
・SSHによるシェルスクリプト
・移行プロジェクトメンバー
元々MENTAは2018年にリリースしてからさくらのクラウドで運用していました。また、ランサーズにグループジョインする前は私が副業でサーバー保守していたということもあり、本番環境、Staging環境、Redash環境の3つで管理していましたが、デプロイがし難いことや、アクセス負荷によるレイテンシーの悪さ、冗長性や負荷分散などは担保していない状態でサービス拡大に伴い、今回AWSへ移行することになりました。他にも移行プロジェクトでは主にSREチーム @yakitori009と共に主体となり、入江さん、業務委託の方と共に進めていきました。個人的に副業で一緒に仕事していたので非常にコミュニケーションしやすかったですね。以下はAWSに移行する際にメリットやECS/Fargateによるコンテナ化することの目的をまとめてみました。
目的とコンテナにするメリット
・内部統制対応
・S3、RDSを利用したバックアップ
・CloudWatchLogs+αを利用したログの保存
・冗長化による稼働率の向上
・開発効率のアップ
・共通開発環境の構築
・リリースの属人化の排除
・GitHubと連動してリリース
・運用効率のアップ
・Immutableなサーバーの運用
・タスク単位で自由に割当のリソースが変更できる
・オートスケールによる負荷分散
・AWS WAFによるセキュリティ強化
新開発環境を作るポイント
・リポジトリ配下にdockerディレクトリを作成
・本番環境と同等の構成を再現
・ELB(H2O)コンテナ(リバースプロキシ)
・Appコンテナ
・PHP7.2-alpine/Laravel 5.5/Nginx
・phpMyAdminコンテナ
・MySQLコンテナ
・Redisコンテナ
・Stripeコンテナ
・Seleniumコンテナ
・SendGridコンテナ
・nodeコンテナ
・各アプリケーションの起動はSupervisorで管理
・composer installはAppコンテナでログイン時に実行
・supervisorctlでphp-fpmをrestartするように
開発環境は以前移行したLancers Agencyのコンテナをベースにより本番環境に近い環境を作り直しました。Docker ImageはPHP7.2-alpineを利用しており、プロセス管理はSupervisorで管理しています。メール送信ではSendGridを利用していますが、送信テスト時に実際にメールが届いてしまうことからSendGridのモックコンテナを使って開発環境でテスト送信できるように実装しました。
Staging環境/本番環境の構成
・Staging環境の構成
・本番環境の構成図
・分析基盤
・Amazon KinesisによるログストリーミングとDatadog
・Terraformで全リソースコード化
・Staging環境は極力コストを抑えタスク数は1つ
・社内用はランサーズProxyでアクセス(phpMyAdmin,SendGrid,Digdag,Redash)
・SendGridコンテナによるメールテスト
・phpMyAdminコンテナによるデータ出し
・オートスケールによる最大6台のAppコンテナで運用
・devops/SSHコンテナの利用でaws cli.MySQLの操作
※現在ではdevopsコンテナを廃止してECS Execで直接Appコンテナにログインしています
・Digdag/Embulk/BigQueryによる分析基盤の構築
・DBはRDS Auroraに移行
・ElastiCacheによるログインキャッシュ化
・画像等S3化
・ログはCloudWatch Logs
・バッチはECS Scheduled Tasks
・内部監査(ログの集約)
・Amazon Kinesis
・AWS KMSによる暗号化
・WAFでのDDosアタック制御
・監視はDatadogでコンテナリソースとAPM
今回インフラ面で新しく挑戦した技術ですが、ECS/Fargateでのオートスケールを実装しました。今まではタスク数2台でしたが、AppコンテナのCPUが20%超えると最大6台までスケールアウトするようになっているのでアクセス負荷時にも耐えられる環境となりました。以下私の個人ブログで紹介しているので参考にしてみてください。また、分析基盤(Digdag,Embulk,BigQuery)はランサーズでも運用しており、EC2で運用するように環境を共通にしました。BigQueryのサービスアカウントの鍵はAWS KMSを利用して暗号化し、実行時に復号しています。他にもランサーズと同様の環境であるカナリア環境で本番同等の環境も構築しました。これにより本番リリースする前にチェックができるので、リリース後でのトラブルが減ります。
https://blog.adachin.me/archives/47303
CircleCIでのリリース
・CircleCIでのコンテナデプロイ
・Staging環境/カナリア環境へのデプロイ
・github flow
・シェルスクリプト
・任意のブランチを指定してAPI経由でデプロイ
・Masterマージで本番環境リリース
・素早くデプロイが可能
・開発効率がアップ
・Terraform CI環境を実装
MENTAでは、AWS移行前からGitHub ActionsでUnit TestやE2E Testを行っていましたが、ランサーズではCircleCIを利用していたため移管しました。また、デプロイもCIで行うようにしました。コンテナデプロイは前回移行した方法と同様に、Terraform CI、API経由でのStaging環境デプロイ/カナリア環境デプロイ、Masterマージでの本番環境デプロイで成り立っています。
大変だったこと、今後やること
・S3 画像アップロードが一部の機能しか対応していなかった
・Laravel5.8へのバージョンアップ
・バッチや過去の企画のソースを棚卸することで、負債となっていたソースを整理できた
・Unit/Feature/E2Eの自動テスト整備
・PHPCSを使った規約統一
・PHPStan(Larastan)使った静的解析での品質向上バグ削減
・リファクタリング
今後やること
・Datadogでのアクセスログ可視化
・コンテナ脆弱性管理
・画像読み込みのレスポンスを改善
・Terraformバージョンアップ
・devopsコンテナを廃止してAPI経由でコンテナにログイン
上記業務委託メンバーからコメントをいただきました。AWS移行をきっかけに企画・アイディアベースのプロトタイプ開発から将来を見据え運用・保守も意識した開発スタイルに変わりました。また、技術的な負債の整理を行い移行を実施できたと思います。ランサーズと同じ開発スタイルに変わったのでやりやすくなったので良かったと感じています。
気になるコストですが、さくらのクラウド時代と比べて月額で数十万円高くなっています。しかしながら、冗長化やオートスケーリングを設定し、高い可用性を実現したサーバー構成になり、今後のMENTAを支えていく土台が整いました。
移行プロジェクトのまとめ
去年10月から始めていた移行プロジェクトですが、過去の経験が生きたこともあり、短期間で移行できたのでよかったです。協力していただいたメンバーの皆さんにも感謝いたします!個人的に副業で利用していたサービスの保守担当隣、さらにはランサーズグループへJOINし、AWSの移行を担当できたのはなかなかできないので、良い機会をいただくことができました!