Amazon Web Services ブログ

EKS と Fargate、AWS Compute Savings Plans で Pod の料金を節約する

この記事は、Saving money a pod at a time with EKS, Fargate, and AWS Compute Savings Plans を翻訳したものです。

re:Invent 2019 では、Amazon Elastic Kubernetes Service (Amazon EKS) で、Kubernetes の Pod を AWS Fargate にデプロイできるようになったことが発表されました。その発表以降、多くのお客様が実際に Fargate 、つまりコンテナを実行するためのサーバーレスインフラストラクチャーに Kubernetes の Pod をデプロイしています。Fargate を利用することで、クラスターの管理やパッチの適用、セキュリティやアイソレーション、スケーリングといった様々な運用業務、「差別化にならない重労働( undifferentiated heavy lifting )」から解放されます。

Amazon EKS と Fargate の詳細については、re:Invent のブレイクアウトセッションでも掘り下げられています。

AWS Fargate は AWS Compute Savings Plans の対象だったものの、これまでは ECS で起動したタスクに対してしか適用されませんでした。本日の発表は、Fargate で EKS の Pod を起動した場合にも AWS Compute Savings Plans を適用できるようになったというものです。こちらで What’s New の記事を読むことができます。既に有効な Compute Savings Plan をお持ちの場合は、自動的にその Savings Plan に沿って Fargate 上の Pod に割引が適用されます。また、 Savings Plan によりどのようにコストを抑えられるのか、AWS Compute Savings Plans FAQをご確認いただくこともできます。1年間または3年間のコンピューティングリソースの使用をお約束いただくことで、Fargate の利用に際し最大 52% の割引を受けることが可能です。

Compute Savings Plans は、特定のテクノロジーの利用をお約束いただくものではありません。Compute Savings Plans はどのコンピューティングサービスを使うとしてもコストを抑えることができる柔軟性があります。例えば、EC2、Fargate、また Lambda でも対象になりますし、Fargate の場合は ECS でも EKS でも好きな方のオーケストレーターを自由に選択できます。

Compute Savings Plans は、EKS と Fargate を利用する場合、最も直接的かつ確実にコストを最適化できる方法の一つです。しかし、それだけではありません。この記事では、Fargate と従来のEC2 インスタンスフリートを比較・検討する妥当なケースについて、いくつかの考慮事項を概観しつつ振り返っていきます。

AWS Fargate の取得コスト

私たちは、ときどき、お客様が Fargate とEC2 のコンピューティングに掛かるコストを比較している場面を見かけることがあります。簡単な例として、us-west-1 にあるオンデマンドの m5.large Linux インスタンス( 2 vCPU、メモリ8GB ) と、同リージョンで同等のキャパシティを Fargate で確保した場合を比較してみます。今日の時点で、この EC2 インスタンスのコストは1時間あたり $0.096 です。それと同等の Fargate タスクは、次の式、「 ( $0.04048 x 2 vCPU ) + ( $0.004445 x 8GB )」で計算できます。つまり1時間あたり、$0.11652 となります。

Fargate は実際には様々な EC2 インスタンスタイプの混合フリートとなっており、m5 や c5 といった最新世代の EC2 インスタンスと正確にはパフォーマンスが異なるかもしれない、という点には注意が必要です。なので、上記の例は Fargate が EC2 よりも 20% しかコストが掛からない、というベストケースのシナリオになっていますが、本当の「金銭的な価値」は、このインスタンスの世代という変数を考慮した場合には異なってくるかもしれません。お客様特有の条件、前提を考慮し、独自の観点で検証を行うことを推奨します。私たちは、お客様がこのようなパフォーマンスのギャップや矛盾を感じる状況を減らしていくために、Fargate の基盤を常にアップデートしつづけています。

前述のとおり、Fargate で起動した EKS の Pod は Compute Savings Plans の対象外でした。そのため、Compute Savings Plans が EC2 インスタンスに適用されたケースでは、Fargate と EC2 のコスト差が非常に大きくなっていました。今回の発表で Compute Savings Plans が EKS/Fargate でも利用可能になり、購入モデルを問わず Fargate と EC2 のコスト差が軽減されています。

ただ、私たちとしては、適切な比較のためには全体像を見る必要があると考えています。Fargate では、AWS が運用コストを引き受けるだけではなく、伝統的な仮想マシンのクラスターでお客様が抱えていたアイドル中、未使用のキャパシティーの多くを吸収します。実際、私たちは、お客様が必要とする規模に本来掛かってくるコストよりも低いコストでインフラストラクチャーを提供します。これは AWS が大きな規模でインフラストラクチャーを運用しているためであり、何百万人ものお客様にサービスを提供することで実現できているメリットです。

隠れた運用コストと AWS Fargate の価値

マネージドサービスを使用する利点の一つは、差別化にならない重労働( undifferentiated heavy lifting )と考えられる運用業務が必要なくなり、時間を節約できることです。Fargate もその点は同じで、インフラストラクチャーの詳細を考える必要がなくなり、アプリケーションの構築とそれによるビジネスの成果に集中できるようになります。

以下に挙げたものは、Fargate のようなマネージドサービスを利用すると決めた時点で考える必要がなくなることの一覧です。この一覧も、包括的ではありますが全てを網羅しているわけではありません。これらは全て、「取得するコスト」だけでなく、「所有するコスト」を考慮する必要があるものです。

セキュリティ

コンテナは、アプリケーションの依存関係をパッケージングして分離する(つまり、コンテナイメージに分離する)ことに非常に大きな価値がありますが、実行時に仮想マシンと同レベルの分離とセキュリティを提供するわけではありません。悪意のあるユーザーがホストのコントロールを奪い、そこで稼働している全てのコンテナにアクセスできてしまう「コンテナエスケープ」という問題があります。

この問題を軽減するために色々なテクニックがあり、例えば特にデリケートなワークロードを隔離する別のホストを作ったり、コンテナを非 root ユーザーで実行したりといったことも行われます。このようなテクニックを使っているユーザーは taints と tolerationsaffinity と anti-affinity といった高度な Kubernetes の設定を駆使することもあります。様々なテクニックは、こうした難しい設定が必要になり、複雑さをどんどん増やしていくことになるでしょう。結果として、最適化されていないインフラストラクチャーや運用の負担という形でコストの増加に繋がります。Fargate は、Pod を実行する際に、適切なサイズの専用の仮想マシンを割り当てることでこの問題を根本的に解決します。どの時点でも、二つの Pod が同じ仮想マシンで動くことはありません。Fargate を利用すると、コンテナによるパッケージングと柔軟性、および仮想マシンによる強固な境界内でのコード実行というセキュリティ、双方のメリットを得ることができます。Fargate で実行される Pod はオペレーティングシステムを共有しないので、コンテナエスケープに関連する問題を軽減できます。

また、Fargate のエフェメラルストレージは、ユーザーが何も設定しなくてもデフォルトで暗号化される、ということも大事なポイントです。

一般的には、Fargate は AWS の責任共有モデルの境界を動かします。Fargate では AWS が Pod の実行に使われる仮想マシンのセキュリティに責任を負っており、オペレーティングシステム更新などの運用業務を行います。Amazon EKS Best Practices Guide for Security には EC2 と Fargate で Pod を実行する際のセキュリティ関連の違いについていくつかの点が紹介されており、よい情報源となります。

コンプライアンス

高度に規制された業界のお客様は、実行しているスタックがコンプライアンスに準拠しているか確認するために多くの時間を費やしています。ISO コンプライアンス、HIPAA コンプライアンス、PCI コンプライアンス、その他どんなコンプライアンスであっても、必要なドキュメントを作成するためのエンジニアリングサイクルは非常に高くつきます。AWS Fargate のようなマネージドサービスを利用する様々な利点の一つは、そうした負担を AWS にオフロードして、サービスがコンプライアンスに準拠していることを示す AWS のドキュメントを監査人に提示するだけで済むようになることです。そうでなければ、コンピュートに EC2 などを利用し、そのセットアップがコンプライアンスに準拠していることの確認(そしてそれを適切に文書化すること)に時間とお金を投資することになります。この記事の時点では、Fargate のコンプライアンス認証のほとんどは、Fargate 上で実行されている ECS に適用されます。EKS/Fargate にも適用範囲を拡大しようとしているので、最新情報についてはAWS のコンプライアンスドキュメントをチェックしてみてください。

AMI の管理

私たちは昨年、Kubernetes のワーカーノード運用の負荷を削減するマネージド型ノードグループを発表しました。AWS は AMI のアップデートを提供しており、その AMI を使ってワーカーノードを置き換える作業はシンプルになりました。しかし、それでもノードはお客様の AWS アカウントで動いており、セキュリティやパッチ適用の責任はお客様にあります。お客様はインスタンスの root 権限を持っているので、EKS がライフサイクル管理を補助してはいますが、AWS フルマネージドなものとは言えません。マネージド型ノードグループと違い、Fargate を使う場合は、Fargate を使うということ以外に追加の作業はありません。例えば、AMI について考えたり、ホスト OS のパッチを当てたりする必要はありません。同様に、Fargate では、新規に起動した Pod は全て、完全にパッチが適用されたインフラストラクチャーで実行されていると見なすことができます。つまり、どのノードにどの AMI が使われているのか意識する必要がありません。

他の考慮点として、マネージド型ノードグループであったとしても、ノードを更新する際は新しい AMI をローリングデプロイする必要があるということが挙げられます。これは Pod への副作用を伴います。Pod には終了のシグナルが送られ、ノードから退避させられます。単なるスケールアウトやステートレスアプリケーションの場合は問題にならないことも多いですが、他のタイプのアプリケーションの場合はインフラストラクチャーがアップデートされる度に混乱を招くことになるかもしれません。金融機関で CISO が30日周期で AMI をローテーションすることを提案するケースが多いことを考えると、こうした組織にとってこのことが定期的な負荷となりうる、ということがご理解いただけるかと思います。

一般的な k8s のワーカーノード管理

AMI の管理に加え、上記の節で述べたように、汎用ワーカーノードの管理とそれにかかるコストを考慮する必要があります。マネージド型ノードグループや Auto Scaling Group (ASG) を利用することで多くの労力を削減できますが、Kubernetes エコシステムには適切にインフラストラクチャーを管理するためにノードで実行するよう推奨されているツールがいくつもあります。例えば、node problem detector などです。これ自体は大したことではないかもしれませんが、Pod を動かすインフラストラクチャーを自分で管理しているとやるべきとがどんどん積み上がっていきます。

Fargate であれば、そのインフラストラクチャーは完全に AWS によって管理されます。インフラストラクチャーは定期的にアップデートされ、Pod が起動すれば真新しい仮想マシンが最新バージョンのソフトウェアと共にプロビジョニングされるので、Pod は常に最新のスタック上で起動されます。

Cluster Autoscaler

Cluster Autoscaler (CA) は広く利用されている Kubernetes のアドオンで、実行されている Pod の負荷に応じてクラスターのワーカーノードをスケールアウトしたりスケールインしたりするものです。CA は非常に機能が豊富で、自身のユースケースに応じて適切に設定するのも相応に複雑になることがあります。例えば、ノードを追加、削除するタイミングを決めるための設定は、クラスターの実行コストに大きく影響します。CA FAQ を見ると、設定項目がどれだけ豊富で柔軟性があるか、想像できるかと思います。これは、CA の動作を調整するためにサポートされているパラメータのリストです。

もう一つ考慮する必要があるのは、CA がスケールインすべきと判断したときに実行中の Pod に与える影響です。スケールインの対象となっているノードで実行している Pod は削除され、別のノードで再起動されます。このトピックについては、FAQ で説明されています。Pod が何をしているかにもよりますが、特に完全にステートレスでない場合は、これはタスクを混乱させる可能性があります。

Fargate では、CA は必要ありません。そのため、これらのどの懸念も無関係です。Fargate を使用すると、各 Pod は Pod 自身と同じライフサイクルを持つ、適切なサイズの仮想マシンで起動されます。ノードが無関係なので、クラスターをスケーリングする必要もありません。

ワーカーノードのサイジングと、利用可能なキャパシティー

Kubernetes の Pod は普通、EC2 インスタンスのフリートで起動する必要があります。これらのインスタンスのサイズを集約すればクラスターの総容量になるわけですが、適切なサイズのインスタンスサイズを選ぶことは容易ではありません。また、インスタンスのサイズを一つだけ選択することで、ノード間で空き容量のバランスが崩れることに繋がります。これは特定のインスタンスタイプで構成された一つのノードグループだけを利用している場合などで発生します。複数のノードグループを利用するよう Cluster Autoscaler を設定してキャパシティを最適化することもできますが、クラスターの構成は確実に複雑になります。Fargate を利用すると、Pod は適切なサイズの仮想マシンで実行され、必要なリソースに対してのみコストが発生します。インスタンスのサイズや種類、利用率などを考慮する必要はありません。

ノードのサイジングのもう一つの側面は、ホストのスペック上の総容量のうち、どれだけの容量が Pod に利用できるかということです。ワーカーノードが 8GB のメモリーを持っているとして、実際にアプリケーションが利用できるメモリーはその一部です。例えば、オペレーティングシステム自体が実行しているサービスのリソース、kubelet が使うリソース、Kubernetes のeviction threshold で確保されているリソースなどを考慮する必要があります。それらを全て合計すると、システムのために予約されるリソースだけでホストのリソースの 10% から 30% を占めることもあります。外部の記事では、システムで予約されているこうしたリソースについていくつかの例が紹介されています。さらに、ノードから何かを追い出す必要が出てきたときに、どのワークロードが優先すべきか決める必要も出てきます。こうした点を考慮しても、残りのリソースが全て Pod によって利用されるわけではありません。Fargate では、kubelet 関連のリソースと正味のコンピューティングリソースに対してのみ料金が発生します。その他の「システムにより予約された」リソースを考慮する必要はありません。これについては後ほど詳しく説明します。

こうした設計上のシステム予約に加えて、多くのお客様がクラスターで意図的にオーバープロビジョニングを行う傾向にあります。これには様々な理由があり、例えば Pod を高速にスケールアウトするためであったり、Cluster Autoscaler の豊富なオプションで可用性を向上させるためだったりしますが、本質的には、将来起動されるかもしれない Pod のためにあらかじめクラスターのサイズを大きくしておくよう CA に指示する、ということです。非常に大きな柔軟性が得られる一方で、実際には利用していない(少なくとも常時利用しているわけはない)リソースに対して料金を支払うこととなり、インフラストラクチャーのコストは増加します。

チャージバック

EKS では多くのお客様がマルチテナントでクラスターを運用しています。この場合、中央の IT 管理チームにとって、内部ユーザー(クラスターのテナント)間でコストを按分できるということが非常に重要になります。しかし、ここにある二項対立が存在します。クラスターの管理者にとってコストの単位はワーカーノードとなるインスタンスタイプです。一方、クラスターのユーザーにとってはコストの単位は彼らが実行している Pod なのです。お客様は「誰が何を使っているのか」を把握し、チャージバックの仕組みを作り出すことでこの対立を埋めようとしていますが、これはいくつかの理由から簡単なことではありません。Kubernetes の Pod は AWS のファーストクラスオブジェクトではない(Kubernetes オブジェクトである)ため、AWS ネイティブのコストアロケーションの仕組みでは Pod を追跡することができません。

このため、お客様の多くはサードパーティー製のツールで利用状況を追跡し、それに基づいてチャージバックのレポートを管理しています。ただ、これらのツールも上記の二項対立からある点の考慮が必要です。つまり、未使用のリソースには誰が料金を支払っているのか、ということです。前述のとおり、クラスターが 100% の利用率で稼働していることは実際にはまずありません。利用率が 50% 以下というケースも珍しくありませんし、多くのエンジニアリングリソースを費やしてクラスターを微調整しているお客様でも、一般的には利用率が 80% を超えるということはありません。これらの数字に科学的な根拠があるわけではありませんが、お客様との会話で語られた逸話に基づいたものです。上記の二項対立に立ち返ると、この 20%とか 50% といったアイドリングリソースにお金を払っているのは、一体誰なのでしょうか? 全てのテナントに再分配されているのでしょうか? それとも、中央の IT 管理チームが負担しているのでしょうか?

EKS/Fargate を利用する場合、マルチテナントのクラスターを運用している中央の IT 管理組織にとって、このような二項対立は根本から存在しません。クラウドの請求にあるコストを、1:1 のマッピングで内部ユーザーに按分できます。

Fargate pod の適切なサイジングと無駄なコストの削減

上記で挙げたそれぞれの項目はすべて重要な側面であり、Fargate を利用する大きなビジネス上の理由になりうるものです。しかし重要な点は、料金を支払っているキャパシティーのうち、実際に使用しているのはどのくらいなのかということです。

例えば、Fargate を検討する上でよくある誤解は、お客様が Fargate Pod のキャパシティーを、従来のワーカーノードのキャパシティーと比較していることです。述べてきたように、Pod のキャパシティーはコンテナが消費できる正味のキャパシティーであるのに対し、ワーカーノードのキャパシティーはお客様が料金を支払った CPU とメモリの総量ではありますが、コンテナを実行するために活用できるのはその一部だけです。

従来の Kubernetes クラスターは、要件や運用の成熟度に依りますがクラスター総容量の 20% から 50% を無駄にしていると上で述べました。Fargate を利用することで、理論的なキャパシティーの使用率を自動的に(ほぼ)100% にして無駄を排除できます。

これは、Pod がリクエストしているキャパシティをフルに活用していることが前提です。言うまでもありませんが、Pod のキャパシティーのうち 50% しか活用できていない状況にあるのであれば、Fargate を利用したところで従来の EC2 インスタンスより費用対効果が高いとは言えません。だからこそ、Fargate pod の「適切なサイジング」が経済的な意味で非常に重要なのです。AWS Compute Savings Plans を使うことに加えて、または Savings Plans を補完する、重要な考え方になります。

ここでは、Kubernetes の Pod を適切にサイジングする方法を説明します。

従来の Kubernetes クラスターでは、ワーカーノードがアトミックなコンピュートの単位です。この単位は、実行しているクラスターのコストだけでなく、Pod が利用可能な総容量を定義するものです。このコンテキストでは Kubernetes の requests とlimits を設定するべきですが、技術的には強制されません。Pod に CPU の requests とlimitsメモリーの requests と limits を設定すると、Pod の仮想的なサンドボックスが定義されます。これらのパラメーターを設定しないと、全ての Pod がクラスターのキャパシティー、特にスケジュールされたノードのキャパシティーを奪い合うようになります。

EKS/Fargate では、リソースのモデルが異なります。利用可能なワーカーノードはクラスターにないので、Pod 自身がその基盤となるキャパシティーのサイズを決定し、リクエストします。Fargate を効率的に使用するには、このステップが正しく行われる必要があります。こうした理由から、良いパフォーマンスを実現し、無駄を避けるには、Pod を適切に設定することが非常に重要になるのです。

ドキュメントのこのページや、re:Invent の EKS/Fargate に関するブレイクアウトセッションのこのセクションで、Pod をデプロイする際に Fargate でどのようにサイジングされるか、詳細に掘り下げられています。端的に言うと、それぞれのコンテナの requests 設定値を利用し、上記リンクにあるロジックを適用しています。

(requests 値で明示的に指定した)サイズが、実際のワークロードのパターンに適切にフィットするようなものであることが非常に重要です。理想的には、requests 値で設定したキャパシティーを可能な限り多く使いたいところです。Pod のキャパシティーが十分に利用されていないことを検知したいので、Pod の利用状況をモニタリングすることが最も重要になります。そのためには、Datadog (EKS/Fargate をサポートしており意識することなく利用できます) のようなツールを使用するか、別の記事で紹介した Prometheus や Grafana のようなオープンソースの技術を活用します。

重要な点ですが、EKS/Fargate で動作する Pod は、Kubernetes の Horizontal Pod AutoscalerVertical Pod Autoscaler をフルサポートしています。開発者は、前者を使ってワークロードに応じて Pod の数を増減させることができます。また、後者を使うと、割り当てられたリソースが適切なサイズになるよう、Pod をスケールアップまたはスケールダウンさせることもできます。この両者は相性が良くないので、Kubernetes に Pod のサイジングを自動的に調整させたいのであればリソースの消費パターンに応じて適切な方を選択する必要があります。Pod のキャパシティーをなるべく 100% 使えるようにする、ということを意識すると良いでしょう。

まとめ

この記事では、Kubernetes の Pod を Fargate でデプロイする際に、AWS Compute Savings Plans をフル活用できるようになったという新機能をご紹介しました。これまでは、Amazon ECS 経由で起動したFargate タスクのみが Compute Savings Plans の対象となっていました。また、この場を借りて Fargate の価値提案について一般的なところを、特に EKS の文脈でお話しさせていただきました。具体的には、サーバーレスアプローチを使う際に、総所有コスト (TCO) を削減できる可能性がある方法について議論してきました。

また、Fargate が全ての状況で正しい選択になるわけではない、ということをご理解いただくことも重要です。GPU など特定のハードウェアが必要になる、デプロイを微調整してインスタンスタイプを指定する必要があるなど、お客様が従来どおり EC2 インスタンスを使い続ける理由はたくさんあります。これに加えて、このドキュメントに記載があるとおり、Fargate を利用する上で考慮する必要があるポイントがいくつかあり、アプリケーションの要件次第では Fargate を使うことができないケースもあります。これらの考慮事項は、EKS と Fargate がこれから機能を追加するにつれて変更されていきますので、上記リンク先のドキュメントを定期的にご確認ください。

この記事でご紹介した利点にご興味がある、EKS と Fargate を使って検証を始めたい、という場合は、Getting Started のドキュメントをご活用ください。

– Principal Technologist, Massimo Re Ferre

翻訳はソリューションアーキテクトの林が担当しました。