SREチームの安達(@adachin0817)です。去年の5月から行っていた移行プロジェクト第二段であるグループ会社のLancers Agency株式会社の各サービスをAWS(ECS/Fargate)へ移行完了しました。今回、移行背景やECS/Fargateでのコンテナ運用について振り返りを行ってみたいと思います。
AWSへ移行する前
AWSへ移行する前はさくらのクラウドで運用していました。また今回の移行の目的としては前回のLCC移行(Rails)と同様でランサーズに統一させるということです。またECS/Fargateでの移行経験を生かして今回はCakePHPでのコンテナ運用にチャレンジすることとなりました。以下はコンテナ化にするメリットと各サービスの情報をまとめてみました。
目的とコンテナ化にするメリット
・内部統制対応
・S3、RDSを利用したバックアップ
・CloudWatchLogs+αを利用したログの保存
・冗長化による稼働率の向上
・開発効率のアップ
・共通開発環境の構築
・リリースの属人化の排除
・GitHubと連動してリリース
・運用効率のアップ
・Immutableなサーバーの運用
・タスク単位で自由に割当のリソースが変更できる
・スケールアウトのしやすさ
移行前の環境
・https://prosheet.jp 、https://lancersagent.com/
・PHP5.4 CakePHP2.5.4
・Apache,MySQL5.7
・メール送信はPostfix
・コーポレートサイト https://lancers-agency.co.jp/
・PHP5.5
・メディアサイト(WordPress) https://prosheet.jp/blog
・PHP5.5,MySQL5.7
・開発環境
・VagrantによるAnsibleで管理
・リリース方法
・Fabric
新開発環境を作るポイント
・リポジトリ配下にdockerディレクトリを作成
・本番環境と同等の構成を再現
・ELB(H2O)コンテナ(リバースプロキシ)
・Appコンテナ
・PHP5.5-alpine/CakePHP2.5.4/Nginx
・MySQLコンテナ
・SendGridコンテナ
・phpMyAdminコンテナ
・WordPressコンテナ(PHP7.3-alpine/Nginx)
・各アプリケーションの起動はSupervisorで管理
・composer installはAppコンテナでログイン時に実行
・supervisorctlでアプリをrestartするように
・開発環境のディレクトリ構成
$ tree docker/dev
docker/dev
├── README.md
├── app
│ ├── Dockerfile
│ ├── nginx
│ │ ├── local.biz.prosheet.jp.conf
│ │ ├── local.lancersagent.com.conf
│ │ ├── local.prosheet.jp.conf
│ │ └── nginx.conf
│ ├── php
│ │ ├── 15-xdebug.ini
│ │ ├── config.inc.php
│ │ ├── php-fpm.conf
│ │ ├── php.ini
│ │ ├── www.conf
│ │ └── xdebug.so
│ └── supervisor
│ ├── app.conf
│ └── supervisord.conf
├── docker-compose.noelb.yml
├── docker-compose.yml
├── elb
│ ├── Dockerfile
│ ├── h2o
│ │ ├── conf.d
│ │ │ ├── local.biz.prosheet.jp.conf
│ │ │ ├── local.lancers-agency.co.jp.conf
│ │ │ ├── local.lancersagent.com.conf
│ │ │ ├── local.pma.prosheet.jp.conf
│ │ │ ├── local.prosheet.jp.conf
│ │ │ └── local.sendgrid.prosheet.jp.conf
│ │ └── h2o.conf
│ └── service.sh
└── mysql
├── Dockerfile
├── mysql_init.sh
├── mysqld.cnf
└── service.sh
・supervisor/app.conf
[supervisord]
nodaemon=true
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stopsignal=TERM
user=root
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:php-fpm]
command=/usr/local/sbin/php-fpm -F
autostart=true
autorestart=true
stopsignal=TERM
user=root
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true
stopsignal=TERM
user=root
開発環境はVagrantからDockerに移行しました。Docker ImageはPHP5.5-alpineを利用しており、Appコンテナ一つでProsheet、Lancers Agentをバーチャルホスト、プロセス管理はSupervisorで管理しています。メール送信ではPostfilxを利用していましたが、ランサーズはSendGridを利用しているため移行したいこともあり、SendGridのモックコンテナを使って開発環境でテスト送信できるように実装しました。またコーポレートサイトもCakePHPで動作していましたが、メンテナンスしやすいWordPressに移行しました。これにより素早く開発環境を提供できるようになりました。
Stg/本番環境の構成
・Amazon KinesisによるログストリーミングとDatadog
・stg dockerディレクトリ構成
$ tree docker/stg
docker/stg
├── deploy.sh
└── prosheet-app
├── Dockerfile
├── README.md
├── common
│ └── prompt.sh
├── nginx
│ ├── default.conf
│ ├── stg.biz.prosheet.jp.conf
│ ├── stg.lancersagent.com.conf
│ ├── stg.prosheet.jp.conf
│ ├── stg.try-out.work.conf
│ └── nginx.conf
├── php
│ ├── php-fpm.conf
│ ├── php.ini
│ └── www.conf
└── supervisor
├── app.conf
└── supervisord.conf
・Terraformで全リソースコード化 ・Stg環境は極力コストを抑えタスク数は1つ ・devops/SSHコンテナの利用でaws cli.MySQLの操作 ・DBはRDS Auroraに移行 ・メール送信はPostfixからSendGrid化 ・コーポレートサイトはWordPress化 ・ALBのリスナールールによるパスによる転送 ・画像等S3化 ・WordPressの画像 ・WP Offload Media LiteプラグインでS3に ・ログはCloudWatch Logs ・バッチはECS Scheduled Tasks ・内部監査(ログの集約) ・Amazon Kinesis ・デプロイはCircleCIのみで実装 ・監視はDatadogでコンテナリソースとAPM
前回のLCC移行と構成は同様ですが、一番大変だったのはSendGridへ移行、WordPressコンテナ化に伴う画像をS3に移行、職務経歴書などのファイルをS3に移行することでした。もちろんコンテナの場合ソースコードで管理していないファイルや画像等はデプロイ時に削除されてしまうので、これらの実装ができていないと移行ができません。主にアプリエンジニアが対応していただき、SendGrid移行時ではメール送信ロジックが一つにまとまっていなかったので対応箇所が多かったところと、SendGrid APIの仕様で送信結果を別途取得しなければならないのが想定外でした。S3移行ではファイルアップロード、ダウンロード処理が共通化されている部分と共通化されてない部分があり、対応方法もそれぞれ異なり、昔のソースコードへの対応後、確認方法がわからなくて苦戦しました。
また、さくらのクラウドからAWSに移行してコストがどのくらい変わったのか確認してみたところ、さくらのスペックが高かったこともあり、年間約60万ほど削減できました。続いてはCircleCIでのコンテナデプロイについて紹介します。
CircleCIでのコンテナデプロイ
・Stg環境のデプロイ
・github flow
・シェルスクリプト
・任意のブランチを指定してAPI経由でデプロイ
・素早くデプロイが可能
・開発効率がアップ
・Masterマージで本番環境リリース
・Terraform CI環境を実装
$ sh deploy.sh
下記のようにブランチを指定して実行してください。
(例) sh deploy.sh ブランチ名
$ sh deploy.sh
下記のようにブランチを指定して実行してください。
(例) sh deploy.sh ブランチ名
$ sh deploy.sh fix-nginx
{
"number" : 74,
"state" : "pending",
"id" : "xxxxxx-xxxxx-xxxxx-xxx-xxxxxxxx",
"created_at" : "2020-08-27T06:14:43.973Z"
}
ブランチ名/ fix-nginx のStgデプロイを開始しました!
Stg、本番環境デプロイはCircleCI一つで実装しています。StgではCircleCIのAPIをシェルスクリプトで引数(ブランチ名)を指定してデプロイし、本番はMasterマージ後にデプロイするように実装しました。WordPressもリポジトリ化をしてデプロイも同様になります。CIではTerraformが動作していますが、今後PHPのCIも取り入れる予定です。
移行プロジェクトの振り返りとまとめ
去年の5月から着手していたグループ会社のECS/Fargate移行がようやく本日完了した!
— adachin👾SRE (@adachin0817) February 6, 2021
今回はランサーズSREチーム、アプリメンバーと共に移行していきましたが、前回の経験もあったことで素早く構築することできましたし、PHPでの本番コンテナ運用もノウハウが高まったので非常にいい経験となりました。また、個人的な感想としてPROsheetは5年前のシェアゼロ時代から知っていたので、前CTOにも移行したことを報告して、メンテナンスされてありがたいとのことで感謝もされて非常に感慨深いです。
今後やることとしては現在PHPは5.5、CakePHPは2.5.4を利用しています。先日PHP8もリリースしたということもあって、SREチームとアプリメンバー含めてバージョンアップの対応やコンテナの脆弱性検知(Trivy)やDatadogでのアクセスログ可視化を行っていきたいと考えています。半年間近くでしたが、レガシーシステムを移行するにあたって時間もかかりましたし、最後までやりきることができたので非常に感動です。次の移行プロジェクトはMENTAとなりますので、また移行したらブログ書いていこうと思います。ありがとうございました!