みなさん、CloudNativeしていますか?

古屋啓介氏(以下、古屋):それでは「うんうん、それ(EC2+ASG)もまたCloudNativeだね」ということでお話しします。私は古屋と言います。アイレット株式会社のcloudpackに所属していて、ふだんはAWSやGoogle Cloudとイチャイチャするのが仕事です。

さてみなさん、CloudNativeしてますか? CloudNativeとは。CLOUDNATIVE DAYSに参加したことがある方なら、何回か見ていると思いますが、これはCNCFが定義している、Cloud Native Definitionから引用したものです。

「クラウドネイティブ技術は、パブリッククラウド、プライベートクラウド、ハイブリッドクラウドなどの近代的でダイナミックな環境において、スケーラブルなアプリケーションを構築および実行するための能力を組織にもたらします。このアプローチの代表例に、コンテナ、サービスメッシュ、マイクロサービス、イミュータブルインフラストラクチャ、および宣言型APIがあります。

これらの手法により、回復性、管理力、および可観測性のある疎結合システムが実現します。これらを堅牢な自動化と組み合わせることで、エンジニアはインパクトのある変更を最小限の労力で頻繁かつ予測どおりに行うことができます」

というものです。具体的にどんな技術が使われているかという話になりますが、こちらもお馴染みのCNCFの「CLOUD NATIVE TRAIL MAP」に書いてあります。

CloudNativeするためのステップアップ

まずCloudNativeにするには、どのようにステップアップしていけばいいのかという道筋になるかと思っていますが、1がCONTAINERIZATION、2がCI/CD、3がORCHESTRATION & APPLICATION DEFINITION、4がOBSERVABILITY & ANALYSISのように続いていくわけです。

具体的には、「コンテナ化しましょう」「CI/CDであったらargoを使いましょう」「オーケストレーションであればKubernetes、Helmを使いましょう」のような話です。

さらに今回のCLOUDNATIVE DAYSで紹介されている技術、これは発表のセッションの一覧をちょっと抜きましたが、発表の内容としてはKubernetesのライフサイクル、コンテナランタイムや、Kubernetes、Helmや、Kubernetesです(笑)。

CloudNative=Kubernetesとは限らない

ということで、CloudNativeといえばKubernetesでしょ、と。Kubernetes自体、私もすごく興味があるし、すごくおもしろい技術だと思っています。ただ「ちょっと待て」と。本当にCloudNative=Kubernetes、またはコンテナなのかという話です。

CloudNative=Kubernetesとは限らないということで、これはCloudNative界隈の神々もいろいろ言っていますが、KubernetesはCloudNativeじゃないと。CloudNativeの考え方に沿っていないKubernetesは、CloudNativeじゃない。

「例えば手動で、手で温かみのあるデプロイを回して、CI/CDしていないKubernetesはCloudNativeとは言えないし、逆にオンプレのVMであってもCloudNativeの考え方に沿っていれば、それはCloudNativeであると言える」と言っています。

Kubernetesまたはコンテナじゃなくても、CloudNativeができるはずであると。私は業務でAWSをよく触っているので、AWSでいうところの、VMベースとAWSの標準サービスを使ってCloudNativeするにはどうしたらいいのかを考えて実践しています。

以降、CloudNativeの考え方自体、アプリにも考えることがいっぱいありますが、今回はインフラの話をします。

EC2について

おさらいにはなりますが、EC2とは何か。これはけっこう有名なので知っているかもしれませんが、AWSでおなじみのコンピューティングサービスで、さまざまなプロセッサ、CPUやメモリの組み合わせ、先日Macが追加されましたが、いろいろなOSから選べる、いわゆるVMのインスタンスです。

このEC2を使ってCloudNativeするためには、どうしたらいいのかを考えてみました。先ほどのCloud Native Definitionにあったような項目を満たしていけば、EC2でCloudNativeができていると言えるのではないかと考えて、回復力と可観測性、疎結合、堅牢な自動化という大きく4つのポイントを満たしていけばいいんじゃないかと思いました。

CloudNativeするために:回復力

まずは回復力です。これは今回、“何かあっても勝手に復旧してくれる”と定義しています。実際もっと細かい話もいろいろあると思いますが、今回はこの“何かあっても勝手に復旧してくれる”ポイントで考えてみました。ここで使うサービスは、「Auto Scaling Group」です。

これは、先ほどのEC2インスタンスを希望台数になるように維持してくれるサービスです。Auto Scalingという名前のとおり、負荷が上がったら勝手にインスタンスを増やして、負荷が下がったらインスタンスを減らすのようなスケール制御をしてくれます。

このAuto Scaling Groupですが、例えば運用するシステムの特性上、スパイクが発生しない。そんなに急にドバッとリクエストが来ることがなく、そんなに負荷が増減しない場合であっても、Auto Scaling Groupで希望台数を設定しておくことが大事かと思っています。

これはなぜかというと、インスタンスを希望台数になるように維持することで、インスタンス障害が起きても自動で復旧してくれる。すなわち、この回復力につながるのではと思っています。

CloudNativeするために:可観測性

次に可観測性の話です。可観測性は次の3つの要素があるので、それぞれ分けて考えています。まずはロギングです。これには「CloudWatch Logs」というサービスを使います。これはAWSの標準のログを収集したり、検索したりできるサービスです。具体的にやることとしては、EC2にCloudWatch AgentというAgentをインストールして、どのログをCloudWatch Logsに送るかを設定する必要があります。

例えば、EC2の中でWebサーバーとアプリが動いている場合は、WebサーバーのアクセスのログやアプリケーションのログをCloudWatch Logsに送るような設定をする必要があります。

可観測性の2つ目が、メトリクスです。使うサービスは「CloudWatch Metrics」です。こちらもAgentを介せば、基本的なメトリクスは網羅できるようになっています。やることは先ほどと同じで、EC2にCloudWatch Agentをインストールして設定します。特にEC2のメモリはAgentがないと取ってこれないので、設定しておく必要があるかと思います。

3つ目のトレースは「X-Ray」というサービスを使います。アプリに組み込んでパフォーマンスモニタリングできて、どの関数に時間がかかっているのかが見れるようになります。具体的にやることは、EC2にX-Ray daemonをインストールすることと、X-RayのSDKをソースコードに埋め込むことが必要になってきます。

可観測性は、今までAWSの標準のサービスで話をしていましたが、例えば弊社ではNew RelicやDataDogなど、サードパーティのサービスを使って監視しています。こういうのも可観測性のすべての要素を揃えているので、使うといろいろと楽になりますよ、というおまけ的な話です。

CloudNativeするために:疎結合システムと堅牢な自動化

次に疎結合システムです。これは状態をEC2に持たせない話と考えます。例えばセッションの情報をEC2の中に持たずに、ElastiCacheを使ってRedisやMemcachedを使うとか、データベースもEC2の中に持つのではなくRDSやDynamoDBに持たせるとか。

あとはファイルです。ファイル自体もEC2の中に入れるのではなくてS3とか、あるいはEFS、FSxを使って共有のディレクトリを使うようなことをすればいいと思います。

最後に堅牢な自動化です。これもCI/CDの話と読み替えています。パイプラインは「CodePipeline」という、そのままのサービスがあります。あとはCodeCommit、AWSのGitリポジトリを使って、例えばCodeCommitのプロダクションのブランチにコードがプッシュされたら、それをトリガーにしてCodePipelineを起動する設定を組む必要があります。

ビルドとCI/CDデプロイ

次にビルドです。ビルドは「CodeBuild」というサービスを使います。これはソースコードのコンパイルやテストを、サーバーレスで行えるサービスです。具体的にやることとしては、buildspec.ymlという設定ファイルを作って、ソースコードに入れる必要があります。buildspec.ymlの中にはビルドで必要なひととおりのコマンド、シェルのコマンド群を定義する必要があります。

最後に、CI/CDのデプロイは「CodeDeploy」というサービスを使います。EC2のCodeDeploy Agentを介してアプリをデプロイできるサービスで、EC2の先ほどのAuto Scalingと組み合わせるといい感じにしてくれます。いい感じというのは、EC2がスケールして増えたときに、勝手にデプロイしてくれる、いい感じの動きになっています。

具体的にやることとしては、EC2にCodeDeploy Agentをインストールしておくことと、appspec.ymlという設定ファイルをソースコードの中に入れておく必要があります。appspec.ymlの中では、デプロイですね、アプリをダウンロードして置くのに必要な前後の処理を、シェルスクリプトで書きます。

オートスケールの話が出たので、さらにベースイメージを管理する必要があります。使うサービスとしては「Image Builder」で、これはEC2のイメージの構築、テストを簡素化してくれるサービスです。Image Builderを使うには、コンポーネントと呼ばれるシェルコマンドのリストを作成しておく必要があります。

これは構成管理ツールです。ChefやPuppetを使ったことがある方はなんとなくイメージできるかと思いますが、インストールするミドルウェアや、OSの設定をスクリプトの形式で書いておく。そうしたら、Image Builderがそのスクリプトに沿って、希望どおりのOSイメージをよしなに作ってくれます。

EC2をベースにしたCloudNativeな構成

今まで紹介したようなサービスを組み合わせることで、EC2をベースにしたCloudNativeな構成ができたのではないかと思います。図の上からいくと、ユーザーがアクセスをする。紹介していませんでしたが、Cloud FrontとS3です。右側にS3のパスが伸びていますが、画像やそのようなコンテンツは、Cloud Frontを介して配信します。

その下のALB、ロードバランサーにいって、その下にEC2とAuto Scaling Groupがあります。例えば、Webサーバーとアプリケーションサーバーが同居しているようなEC2を、複数台のAuto Scaling Groupで管理します。データベースはRDS、Auroraを使って、セッション情報はElastiCacheで管理します。下がCodePipelineを使った、一連のCI/CDのパイプラインです。

CodeCommitからCodePipelineを起動して、CodeBuildでビルドして、CodeDeployでデプロイする。右側にいくとCloudWatch。X-Rayで何かあったときに調査できるようになっているし、Image Builderを使って、Auto Scaling Groupのイメージも管理しましょう。図的にはちょっといろいろ簡素化しているので、本当はちゃんとマルチAZに渡って冗長化したりもありますが、そこはちょっと心の目で見てもらえればと思います。

これらの手法で回復性、可観測性、疎結合、堅牢な自動化がだいたい実現できているはずなので、エンジニアはインパクトのある変更を、最小限の労力で頻繁かつ予測どおり行える状態になっているのではないかと思います。

実際にこれに近しい感じでお客さんの環境を作っています。ちゃんとは聞けていませんが、やはり今までCI/CDを組んでこなかったお客さんだと「楽になった」と、けっこう体験がよくなったと思われていると思います。

コンテナ化していなくてもCloudNativeになる

ということで、コンテナ化していなくても各サービスを正しく使うだけで、CloudNativeになるのではないかと考えています。特に変わったことはしていません。AWSをご存知の方だと「普通じゃん」「サービスを当たり前に使っているだけじゃん」のような感じですが、ちゃんと適切に使うことで、CloudNativeになるのではないかと思います。

AWSを知っている方は知っているかもしれませんが、Well-Architected Frameworkという、AWSでクラウドのアプリケーションを開発、運用する上でのベストプラクティス集のような基準があります。こちらに沿ったかたちに収束していくっぽいなと思っていますが、そこの企画や考察は今回はしていません。

ぼくのかんがえる「CloudNativeにすること」

ぼくのかんがえる「CloudNativeにするとは」という話で、人が考えるとか、気にする余地を減らすことが「CloudNativeにすること」なのではないかとちょっと思っています。今まで紹介したような、勝手にスケーリングしたり復旧したり、自動でデプロイしたり、マネージドサービスを使ってもろもろAWSに任せることで、CloudNativeになっていると言えるのではないかと思います。

EC2ベースでもCloudNativeできたのではないかと思いますが、とはいえ、コンテナ化して、CI/CDして、オーケストレーションしたい話もちょっとあって。そういうときはECSを使ってみましょうという、おまけ的な話になります。ECSはAWSのコンテナオーケストレーションサービスとなっていて、こちらはコンテナを希望台数に維持、スケーリングするサービスです。

このコンテナを動かす基盤は、先ほどのEC2か、AWSが管理しているFargateという基盤を選択できます。例えば、先ほどの構成でEC2をECSに置き換えるとどうなるか、何がうれしいかというと、FargateはOSレイヤーまでAWSの面倒を見てくれるので、例えばセキュリティパッチをこちらで当てなくてもいい、AWSがよしなにしてくれる。やはりこれも、考えることを減らしてくれるという意味で、コンテナ化もやはりいいよね、のような話になります。

コンテナ化していなくてもCloudNativeなシステムは作れる

まとめですが、コンテナ化していなくてもCloudNativeなシステムは作れると思っています。人が考えることを減らしていくことが大事だと思っています。考えることを減らしていくために、考えて作っていくことが大事かもしれません。EC2でもできますが、やはりコンテナ化もいいよねという、よくわからない感じですが、これで以上です。

これからもこのCloudNativeな考え方に従ってというか、沿ってというか。参考にしながら「それもまたCloudNativeなシステムだね」と言えるようなものをどんどん作っていけたらいいなと思っています。以上です。ありがとうございます。