ハンズラボ Advent Calendar 2017 11日目の記事です。
Elastic Beanstalkの運用をそれなりに続けてきたので、溜め込んだTIPS+失敗事例を放出します。
プラットフォームはPHPです。
Daily Buildしましょう
「いやいやうちはデイリーどころか1日複数回buildしてdeployですよ」という方もいらっしゃるでしょうが、すべてのアプリケーションに対して毎日、というわけではないのでは?
「同じソースコードをeb deployして昨日は通ったのに今日は落ちる」ということがあります。
AWSは日夜プロダクトを改善していて、ユーザとして恩恵に預かっているわけですが、ときに牙をむくことがあります。
ということで、平日の出勤時間帯にdeployスクリプトをスケジュール実行しておいて、deploy成功していると安心して出勤できます。
- 2016年9月、eb-activity.logにて、ascii以外の文字列が入っているエラーが出てdeploy失敗しました。
(コメントに入ってもNG) - 本番以外の環境で、immutableかrolling with additional batchでのdeploy検証できていると、安心です。この二つはEC2を新規に起動するので、後述のpreinit hookのスクリプトから順に動くためです。
- と言いつつ、.ebextensionsでシンボリックリンクを貼る、みたいなことをしているときに、
already exists
で落ちるケースも。本番deployして初めて失敗する、みたいなケースは辛い・・・。
- と言いつつ、.ebextensionsでシンボリックリンクを貼る、みたいなことをしているときに、
ライブラリのバージョンを固定しましょう
常に最新版のライブラリを適用するのがセキュリティ的には望ましいですが、なかなかそうはいかないのが悩ましいところです。。。
検証環境では最新のライブラリ、本番環境は検証済みライブラリ、とかで分けて管理できればいいのですが・・・。なかなか腰が重いです。
- とあるpeclライブラリをバージョン指定せずに
pecl install
していたところ、最新版がPHP7のみのサポートになってdeployに失敗しました。。。 - プラットフォームのバージョンは検証環境のみ「管理された更新」を適用しています。これも便利。動作に問題がなければ本番環境へ。
eb-activity.logを読みましょう
Beanstalkが管理しているEC2が起動するときや、Application Versionをdeployするときにeb-activity.logが更新されます。
実際に動いてるのは/opt/elasticbeanstalk/hooks
配下のスクリプトです。ここに、.ebextensionsで書いた設定やらシェルスクリプトやらも入ってきます。
$ pwd
/opt/elasticbeanstalk/hooks
$ ls
appdeploy configdeploy postinit preinit restartappserver
- deployがtimeoutする原因について調べていたところ、
composer update
は--no-devがついて実行されていたのに、composer install
はオプション無しで実行されていました。.ebextensionsで記述していないAWS製のdeployスクリプトの中で、EC2新規起動時はcomposer install
を実行する作りになっていました。 - 試行錯誤の結果、下記のようにcomposer_optionsで--no-dev指定することにしました。合わせて、hirakさんのprestissimoを使ってcomposer install/updateの並列実行を実現しています。
- EC2の起動が遅い問題、C5/M5インスタンスが東京リージョンに来てパッと解決してほしい・・・。
commands:
01_update_composer:
command: export COMPOSER_HOME=/root && /usr/bin/composer.phar self-update 1.5.2 && /usr/bin/composer.phar global require hirak/prestissimo
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: COMPOSER_HOME
value: /root
- namespace: aws:elasticbeanstalk:container:php:phpini
option_name: composer_options
value: --no-dev
Time Based Scaling しましょう
Elastic BeanstalkはAuto Scalingもよしなにやってくれますが、スパイクアクセスには弱いです。
日常的にiOS/Androidアプリへモバイルプッシュなどを行っていると、プッシュのタイミングでスパイクアクセスが発生します。
プッシュを登録する担当者と相談して、プッシュ送信する時間帯を制限し、その時間帯はスケールアウトしておくことで対策しています。
BeanstalkだけでなくDynamoDBもTime Based Scalingに対応しましたね!(こちらはまだAWS CLIのみで設定可能・・・)
- BeanstalkのメトリクスだけではELBへの負荷がわからない場合があります。その場合はELBのメトリクスを参照しましょう。AWS CLIでcloudwatchのメトリクスとるときも、NamespaceはELBのものを使います。
- CPU負荷、デフォルトの平均じゃなくて最大でみたほうがいいことがあります。CPU使用率の平均40%だから平気平気、と思ってたらELBが503返してて、CPU使用率を最大で見たら90%超えててEC2が死んでた、とかあるので・・・。
- サポートの方に「503頻発してELB足りないぽいから日常的にPreWarmingお願いします」と依頼したら、「SpillOverCount(過剰数)のカウントが上がっていますのでEC2増やしてください」と返答ありました。AWSサポートの皆様、スキル高くて頼りになります。
- NLB化も検討したいところ。
まとめ
Elastic Beanstalk、AWSにおまかせできる部分が多くて楽ができますが、特有の癖みたいなものがあるので気をつけて使うと安全安心です。
ハンズラボ Advent Calendar 2017 明日12日目は@sr-mtmtです!