しくじり先生 on AWS

古屋啓介氏(以下、古屋):では「しくじり先生 on AWS」ということで、始めたいと思います。よろしくお願いします。今日は、AWS環境を使って日々運用していく中で発生した、しくじり、失敗事例。そしてそのしくじりの原因と、そこから得られた教訓についてお伝えしようと思います。

今日このお話を聞いたみなさんの中で「あ、うちの環境どうっだったかな?」と、思われる方もいらっしゃるかもしれません。今日お伝えすることの中で、ちょっと気になるところがあるなとか、ちょっと違和感を覚える方もいらっしゃるかもしれませんが、大丈夫かなと思われる方もいらっしゃるかもしれません。

そう思っていると、ひょっとすると大変なことになってしまうかもしれませんので、今日のお話を聞いて「あ、うちの環境どうだったかな?」と、もし思われましたらすぐにでも確認してもらえればいいかなと思います。今日とか今すぐ、ぜひご自身のAWS環境を見てもらえればと思います。そして願わくは、今日発表したようなものと同じようなしくじりが今後発生しなくなればいいなと思っています。

注意事項

というわけで改めまして「しくじり先生 on AWS 〜俺みたいになるな!!〜」を始めたいと思います。

まず注意事項です。この発表は、AWSを触ったことがある運用初心者・中級者の方向けになっています。EC2とかLambdaとかけっこう有名なサービスについては、ここでは改めて解説しません。今日発表するしくじりは、もちろん事実に基づいているんですけれども、構成図とかはいろいろと抽象化してお伝えしています。あくまで技術面にフォーカスした内容となっています。

この発表はJAWS DAYS2020で1回発表しているものですが、今回は発表の時間がJAWS DAYSのときよりもちょっと長いので、新たなしくじりを加えています。JAWS DAYSのときとタイトルが変わっていて、タイトルがブレブレになってしまってすみません。

自己紹介

ちょっと自己紹介をさせてください。アイレット株式会社 cloudpackに所属している古屋と言います。もともとはプログラマーから入って、今はAWSのインフラを構築・運用をしているというお仕事ですね。AWSとイチャイチャするのがお仕事になっています。趣味はドラムを叩くことです。

弊社cloudpackについて少し紹介をさせてください。弊社アイレット株式会社cloudpackは24時間365日お客さまのAWS環境の監視・運用保守をしています。お客さまはcloudpackに契約することで、AWSを活用しながらビジネスに集中することができます、というようなコンシェルジュサービスとなっています。

弊社cloudpackはAWS Partner Summit Tokyo2020において、年間を通してAWSのビジネスにもっとも貢献したパートナーとして「APN Consulting Partner of the Year」というものを受賞しています。このようにAWSの運用に関してはすごく経験があるという弊社の中で起きた、具体的なしくじりについて紹介できればいいかなと思っています。

しくじり1:Athenaで170万円の請求が来た

今日は計4つのしくじりを用意しました。一つひとつ見ていこうと思います。

その前にもう少し、cloudpackの紹介をさせてください。AWSについてはすごく経験と知識のあるすごい人たちがたくさんいます。例えばAWS GameDayというAWSのイベントがあって、そこではあるAWS環境をどこまでセキュアにできるかというような観点でチームで競うというようなイベントがあるんですけれども、そこで優勝した人がいるとか。情報誌にAWS関係の記事を寄稿している人とかもいます。

そしてAthenaで170万円の請求が来た人がいます。これが最初のしくじりです。

Athenaを使ったアクセスログ分析

どういうことかを見ていきましょう。今回はCloud FrontとELBのアクセスログを分析したいというような要件がありました。この分析の種類というのは固定になっていて、朝9時に前日分の分析データを閲覧したい。閲覧する人はエンジニアではないので、SQLを書くとかをさせない。

対象のアクセスログは既に東京とオレゴンのS3に格納してあるという状態でした。この今回の分析にあたってAthenaを使ってみようというような話になりました。

おさらいです。Athenaとはということで、ドキュメントから引っ張ってきました。標準SQLを使用してAmazon S3でのデータの直接分析を簡易化するインタラクティブなクエリサービスです。S3に入っているデータに対してSQLを投げて分析できるサービスですね。料金はSQLを発行してスキャンされたデータあたりの課金体系となっています。

今回そのAthenaを使って、分析の基盤としてこのような構成を組みました。左から行きますとCloud FrontとELBがあって、アクセスログがどんどんとS3に流れていくようなかたちになっています。その溜めたS3のアクセスログをAthenaでSQLを発行して分析します。SQLを投げるために、Lambdaを使ってAthenaを呼び出しています。

これは朝9時までに分析が終わっていないといけません。夜間バッチとして夜の間にLambdaを再帰実行して計672回クエリを発行し、その結果を別のS3のバケットに格納して、朝9時になったらユーザが閲覧するというような仕組みにしました。実際これを稼働させてうまくいって、ちゃんと朝9時には分析の結果が見れるというような状態になっていました。それで数日間、運用を続けていました。

AWSからAthena使用制限の報告が来る

ところが数日後、AWSから「Athenaをめちゃくちゃ使われているのでちょっと使用制限かけますね」というような連絡がそのアカウントに来ました。確かに夜間バッチで、Athenaにクエリを走らせて分析をしているものの、そんな制限がかかるほどめちゃくちゃ使っているかと言われるとそうでもないので、何かおかしいなと思っていろいろアカウントの中を調べていきました。

よく見てみるとデータ転送量が東京とオレゴンで170テラバイトを超えているということがわかりました。データ転送量にもお金がかかる。リージョンまたぎなので、1テラバイトが約1万円なんですね。なのでデータ転送料金だけで170万円を超えてしまっていることがわかりました。

エラー発生によって、分析クエリが永遠に実行される状態に

なんでこうなってしまったのかという話です。夜間バッチで走らせていたLambdaが、実はどこかでエラーが発生していました。ところがエラーを処理するような実装にはなっていなかったので、無限ループし続けてLambdaの分析のクエリを発行し続けていました。Lambdaが永遠に実行されるのでAthenaも永遠に分析し続けていたと。夜間・日中問わずですね。

かつ、もともとのアクセスログが入っていたS3のうち1つが東京リージョンにあったんですね。Athenaをオレゴンで動かしていたので、その東京リージョンにあるS3からAthenaへの転送料金がかかると。Athenaを日中夜間問わずぶん回し続けて、S3が東京からAthenaでどんどんデータを送り続けているためにデータ転送量が170テラバイトを超えて、料金も170万円を超えてしまったというようなお話でした。

アンチパターンを知り、それを避ける

何がいけなかったのかという話です。そもそもLambdaの実装にちょっと不具合があったというところもあるんですが、今回Lambdaを再帰的に呼び出してAthenaのクエリを発行していました。Lambdaで再帰するというのはドキュメントにも書いてあり、アンチパターンになっています。

ドキュメントを読むと「Lambda関数内で、任意の条件が満たされるまでその関数自身を自動的に呼び出すような再帰的なコードを使用しないでください。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります」。ということですね。

このドキュメントは、Lambdaの実行そのものに対して料金が急増する可能性ということを意図しているのかなと思うのですが、今回のようにLambdaで呼び出した先とかLambdaで何か操作しているAWSの他のリソースとか通信料とかということも、当然ながら無限に発行され続けて無限に実行され続けてしまい、料金が急増してしまうと。今回はそのパターンになってしまったという話ですね。

ということで教訓の1つ目としては「アンチパターン、ダメ、ゼッタイ」ということですね。ドキュメントにも書いてあるようなアンチパターンをしてしまうと、思わぬ料金が発生したりとか思わぬ事態が発生してしまうので気をつけましょうということです。

先ほどのドキュメントにも書いてあったりするんですが、AWSクラウドサービス活用資料集、BlackBeltと呼ばれるものにも各サービスについてのアンチパターンとか、逆にこうするといいよというベストプラクティスが書いてありますので、まずはそちらを見てもらえればいいかなと思います。ということで、しくじり1つ目は「Athenaで170万円の請求がきたひと」ということでした。

しくじり2:EC2が復旧できない/復旧できたのにヘン

では次のしくじりに行きます。しくじり2つ目は「EC2が復旧できない/復旧できたのにヘン」という話です。

みなさん「EC2をバックアップする」と言われたときに、どうやっているでしょうか。大きく2つあるかなと思っていて、ボリュームであるEBSのスナップショットを取るか、Amazon Machine Image、AMIを作成するかになるかなと思います。

EBSのスナップショットはボリュームのスナップショットなので、ディスクを他に保管しておくというイメージですね。これ実体はS3に保管されるようになっています。AMIを作成する方法は先ほどのEBSスナップショットとあとはOSですね。S3で使っているOSは何なのかというような、インスタンスを作成するにあたって必要な情報をひとまとめにしたものを保管するというものです。

弊社でもEC2のバックアップするときは、よくこのAMIを作成するという方法を取っています。このAMIを使ったときのしくじりについて紹介します。

バックアップからEC2インスタンスが起動しない

ある日、お客さまから「EC2のインスタンスタイプの変更をお願いします」と依頼が来ました。作業を開始していくわけですね。まずEC2を停止して、お客さまから依頼されたとおりにインスタンスタイプを変更して、最後にEC2を起動すると。と思ったらEC2が起動してこない。ということで緊急対応として、毎日取っているAMIのバックアップから起動しようという話になって起動してみます。これも起動してこない。

なんでこんなことが起きるのかと言いますと、ソフトウェア起因で起動できないことがごくたまに発生しています。ちょっとその原因はその時々で変わってくるので何が原因かと一概に言えないんですけれども、このときの原因としては、boot領域で何かエラーが起こっていたんじゃないかと推測されています。

どうやって復旧したのかという話です。このときは、その壊れたインスタンスのEBSから必要なデータを引っ張ってきて、新しくEC2を構築したという話になったそうです。EBSはデタッチとアタッチができるので、まずは別で新しくインスタンスを作って、デタッチして新しいインスタンスにEBSをアタッチして必要なデータをコピーして新しいほうのインスタンスでなんとか稼働させたというかたちになります。

バッチ実行に異常に時間がかかる

また別のしくじりになるんですけれども、ある日に「バッチサーバをAMIから復元してください」というような依頼が来ました。作業開始していきます。AMIからEC2を立ち上げて、今回は普通に立ち上がりましたと。起動してEC2としての動作確認も問題なかったと。バッチ処理を開始していくという段階になり、バッチ処理を開始したんですけれども、いつもの時間に終わらない。

いつもだったら10分とか20分とかで終わるはずなのに、なぜはこのときは1時間以上かかってしまったと。それで後続の作業とか後続の処理にも影響が出てしまいました。

EBSの初期化に時間がかかる

なんでこんなことになってしまったのかというと、AMIからEC2を復元したあとというのはEBSの初期化が必要だからです。ドキュメントにも書いてあります。「初回アクセス時にS3からブロックがダウンロードされる」って書いてあるんですけれども、ドキュメントを読むと「スナップショットから復元されたボリュームへのアクセスは、ストレージブロックがAmazon S3からプルダウンされてボリュームに書き込まれると可能になります。この事前処理には一定の時間がかかるため、各ブロックへの初回アクセス時には、I/O操作のレイテンシーが著しく増加する可能性があります。ボリュームのパフォーマンスは、すべてのブロックがダウンロードされてボリュームに書き込まれると正常値に達します」。

ということで、先ほどEBSのスナップショットの実体がS3にあるとお話したんですけれども、これはAMIから復旧した後にEBSがすぐに使えるようになるわけではなくて、実体はS3に置かれたままになっています。

なのでまずデータにアクセスしないとS3からその実体がダウンロードされないという話になるので、AMIから復元した直後に何かデータをいっぱい読み込むようなバッチ処理等を走らせると、その初回アクセスがS3からダウンロードするので、そこですごい時間がかかってしまって、パフォーマンスが思ったより出ないというような話になります。

AMIから起動することを確認しておく

これまでお話したしくじりからすると、AMIをとっているから100パーセント安全というわけではないということです。最初のしくじりにあったように、AMIから起動することを事前に確認しておくというのが必要かなと思います。

特にこのAMIから起動するというのは、例えば今動いていたはずのインスタンスが動かなくなったとか、非常時でもあるので、その非常時のときにAMIからせっかく立ち上げようと思ったのにそこが立ち上がらないとなるとつらいので、ここは確認しておくべきだなと思います。また2つ目のしくじりにもあったように、AMIから起動したあとのオペレーションについても確認したほうがいいかなと思います。

AMIから起動した直後にちゃんとアプリが動くかとか、バッチ処理が動くかとかですね。

ということで、教訓の2つ目は「それ、ちゃんと復旧できる?」ということですね。AMIからちゃんと復旧できるか、復旧したあとの動作は大丈夫かというところを確認してもらえればいいかなと思います。

具体的にどうしたらいいのかという話なんですけれども、リリース前にできれば本番相当のAMIでリストアの試験をできればベストかなと思います。

有事の際のリハーサルも兼ねていますので、実際にEC2を消してAMIからリストアする。それで動作に問題ないか確認するというところまでできればベストかなと思うんですけれども、EC2をせっかく立てたというか、EC2を今から削除するのもちょっとなという場合は、少なくともAMIのバックアップがちゃんと動作するか、起動するかというところだけでも確認できれば有事の際の安心材料になるかなと思います。

ということで、しくじり2つ目は「EC2が復旧できない/復旧できたのにヘン」というようなお話でした。(後半へつづく)