マルチテナントのAWSアカウントとKubernetesにおけるコストの可視化

マルチテナントのAWSアカウントとKubernetesにおけるコストの可視化

こんにちは、カート決済SREブロックの飯島と、ECプラットフォーム基盤SREブロックの織田です。

本記事では複数チームで運用する共通のAWSアカウントとKubernetesにおけるコストの可視化についてご紹介します。

背景

現在、ZOZOTOWNはモノリスなサービスを機能ごとに分け、マイクロサービスに移行しながらモダンアーキテクチャへのリプレイスを実施しています。マイクロサービスの移行先としてクラウドプラットフォームはAWSを、アプリケーション実行基盤はKubernetesを選定しています。両者とも複数チームで共通アカウントを利用するマルチテナント構成となっています。

AWSアカウントやKubernetesをマルチテナント化することには、メリットとデメリットの両面があります。

マルチテナントのメリットとしては、1つのAWSアカウントや1つのKubernetesクラスタですべてのサービスを管理できるため、運用作業が簡素化されます。Kubernetesの場合、アップグレードの回数が減り、共通の設定を他のクラスタに展開する必要がないため、運用コストを削減できます。

しかしその一方で、マルチテナントにすることで課題も生じます。特に、コスト可視化の面での影響が大きく、1つのアカウントやクラスタを複数のチームやサービスが利用しているため、チームやサービス単位でのコスト分離が困難になり、コストの可視化が難しくなります。

このように、マルチテナントにすることで運用が簡素化される半面、コストの可視化や分離が難しくなるというトレードオフが発生しておりました。

コスト可視化に対する課題

上記で述べた通り、マルチテナントでは共有されたリソースを複数のチームやサービスが利用するため、個別のコスト把握が困難になる傾向があります。1つのAWSアカウントやKubernetesクラスタで請求やリソース使用量が集約されてしまうため、チームやサービス単位でコストを明確に分離・可視化できていませんでした。

そのため、各プロジェクトやチームのコスト負担を正確に見積もることが難しくなり、予算計画の精度が下がります。マルチテナントの利点を生かしつつ、コスト可視化を実現するためには、仕組みを構築する必要がありました。

次に紹介するアプローチを講じることで、マルチテナントでもチームやサービス単位でのコスト可視化を実現し、より適切な予算管理を行えるような取り組みを実施しました。

課題解決へのアプローチ

課題解決のアプローチとして、AWSコスト配分タグの活用と、KubernetesクラスタへのKubecostの導入を実施しました。次のセクションからはそれぞれの詳細について説明します。

AWSリソースのコスト可視化

AWSコスト配分タグ

AWSコスト配分タグとは、AWSリソースに割り当てることができるラベルです。このタグにより、リソースのコストをより詳細に追跡し、分析できます。

タグの定義と運用ルール

AWSコスト配分タグとして以下の表に示すタグを新たに作成しました。

Key Value
CostEnv AWS環境を表す文字列。「dev」や「prd」など。
CostService どのサービスで使用しているかを表す文字列。Namespace名に統一。
CostTeam どのチームが管理しているかを表す文字列。

各タグのValueの値には、命名規則を設けてフォーマットを統一しています。原則として、AWSリソースには「CostEnv」と「CostService」を付けることを必須としています。CostServiceが付いていれば管理しているチームは把握できるため、「CostTeam」は任意としています。

タグの付け方

基本的にAWSリソースはAWS CloudFormationで管理されています。そのため、スタックテンプレートを使用してタグを付けます。以下にサンプルのコードを示しますが、タグの書き方はリソースによって異なりますので、詳細は公式ドキュメントをご参照ください。

Resources:
  IAMUserSample:
    Type: "AWS::IAM::User"
    Properties:
      UserName: "IAMUserSample"
      Tags:
        - Key: CostEnv
          Value: "dev"
        - Key: CostService
          Value: "zozo-techblog-sample"

上記のサンプルのコードを実行すると、AWSコンソールから以下のようにタグ付けされていることが確認できます。

AWSコスト配分タグのサンプル

注意すべきポイントはタグ付けができないAWSリソースも存在することです。また、AWS CLIではタグ付けができてもAWS CloudFormationではできない場合もあります。以下の公式ドキュメントに情報がまとまっているので、合わせてご参照ください。

AWS Cost Explorer

AWS Cost Explorerとは、AWSのコストおよび利用状況を可視化し、分析するためのツールです。事前にAWS Billing and Cost Managementコンソールからタグの有効化を実施することで、AWSコスト配分タグを利用した検索やフィルタリングが可能です。

AWSコスト配分タグの活用例

AWS Cost Explorerの操作方法について説明します。以下の図は、検索とフィルターを使用していない状態で、AWSアカウント全体のコストの合計が表示されています。

AWSアカウント全体のコスト

例えば、ディメンション機能を使用してTag:CostServiceを選択すると、サービスごとのコストの合計が表示されます。

サービス単位のコスト

また、ディメンション機能で「サービス」を選択し、フィルター機能を使用してTag:CostServiceから特定のサービスを選択すると、そのサービスのAWSリソースごとのコストが表示されます。

特定のサービスにおけるAWSリソースごとのコスト

Kubernetesクラスタのコスト可視化

Kubecost

Kubecostとは、Kubernetesクラスタ内のリソース利用とコストを追跡・管理するためのツールです。無料版とエンタープライズ版が提供されています。また、AWSが提供している、Amazon EKS上でKubecostを利用するのに最適化されたカスタムバンドルもあります。弊社ではAmazon EKSでKubernetes環境を構築しているため、このカスタムバンドルを採用しました。

比較検討

どの種類を採用するか決めるにあたり、主に「データの閲覧可能な期間」と「利用料金」の2つの観点で検討しました。以下の表は各種類の特徴をまとめたものです。

Kubecostの種類 データの閲覧可能な期間 利用料金
カスタムバンドル 15日前までの制限あり 無料
無料版 15日前までの制限あり 無料
エンタープライズ版 制限なし 有料

カスタムバンドルと無料版では、データの閲覧可能な期間が15日前までに制限されており、それ以前のデータは閲覧できません。コストを見積もる際には、月や年単位の過去のデータが必要となるため、コスト可視化の用途には適していませんでした。利用料金についてはどちらも無料ですが、カスタムバンドル以上のメリットがない無料版は選択肢から外しました。

一方、エンタープライズ版ではデータの閲覧に制限がなく、無期限に閲覧できます。ただし有料であり、Amazon EKSクラスタで稼働するNode数に応じて料金が決まります。利用料金を算出した結果、エンタープライズ版の採用が即決できるものではありませんでした。

カスタムバンドル採用の決め手

KubecostにはデータをエクスポートできるAPIが提供されています。詳細については後述しますが、このAPIを使用してデータをAmazon S3に保存することで、閲覧可能な期間の制限に縛られなくなります。このようにして、カスタムバンドルのネックが解消できたため、採用することにしました。

余談ですが、カスタムバンドルのメリットの1つに、AWSサポートでの問い合わせが可能ということが挙げられます。問題発生時の問い合わせ先がAWSに統一できることはユーザーとしてもメリットとなります。

アーキテクチャ

弊社で採用しているKubecostのアーキテクチャです。公式のアーキテクチャも合わせてご確認いただくと理解しやすいかと思います。

kubecostのアーキテクチャ

Kubecost内のコンポーネントごとの役割としては以下のようになっています。

  • Kubecost Cost-Analyzer
    • Frontend: nginxを実行し、Prometheusへのルーティングを行う
    • Cost model: コストの計算とメトリクスを提供する
    • AWS Sig V4 proxy: Amazon Managed service for Prometheusからクエリするためのプロキシ。パスワードレス認証が可能になり、AWS認証情報が公開されるリスクを軽減できる
  • Prometheus
    • Prometheus Pod: Kubecost Cost-Analyzerが生成したデータをAmazon Managed service for Prometheusにリライトする
    • Amazon Managed service for Prometheus: コストとメトリクスを格納する時系列データストアでKubecostが生成したデータを格納する

Kubecostは、Kubernetes APIサーバーからNode、Pod、コンテナ、ボリュームなどのメトリクスを収集します。主要なクラウドプロバイダー(AWS、GCP、Azure、etc.)の価格データが組み込まれており、そのデータを使用して、リソース使用量に基づきコストを算出します。

また、収集したメトリクスと価格データを組み合わせて、リソースごとのコストをモデリングします。CPUとメモリの使用量、永続ボリュームの種類とサイズ、ネットワークの送受信データ量などから、それぞれのコストを計算します。

Namespace、Deployment、Service、Podなどのレベルでコストを集計しているため、特定のワークロードのコストを確認できます。Kubecostはリザーブドインスタンスやスポットインスタンスの利用、適切なインスタンスタイプ選択に関する最適化の提案をします。また継続的にメトリクスを収集することで、長期的なコストトレンドの分析や予測も可能になります。

Web UIやGrafanaを使用することで、メトリクスの可視化やアラートを設定できます。しかし弊社では、先述したようにカスタムバンドルでのデータ永続化に課題があったため、独自に可視化の仕組みを構築しています。詳細に関しては、次のセクションで説明します。

可視化の仕組み

先述したように、KubecostのAPIを使用してデータをエクスポートし、Amazon S3に保存しています。その処理と、Amazon S3のデータを可視化する仕組みについて説明します。アーキテクチャは以下の通りです。

コスト可視化のアーキテクチャ

まず、毎日定時に起動するGitHub ActionsのWorkflowからAPIを実行し、前日のNamespaceごとのコストをCSVファイルで取得します。その後、取得したCSVファイルをAmazon S3にアップロードします。APIは以下のcurlコマンドで実行しています。

curl "http://kubecost-cost-analyzer.kube-support.svc.cluster.local:9090/model/allocation" \
-d window=yesterday \
-d aggregate=namespace \
-d accumulate=true \
-d format=csv \
-G

次に、Amazon S3のイベント通知機能を使用し、アップロードしたCSVファイルをAmazon SQSのキューに通知します。最後に、それをSplunkのAdd-onで取り込み、ダッシュボードで可視化しています。弊社でのSplunkの活用に関する情報はテックブログで公開されていますので、そちらもぜひご覧ください。

techblog.zozo.com

techblog.zozo.com

ダッシュボード

ダッシュボードではデータを表示したい日付の範囲と、対象のAmazon EKSクラスタの環境が選択できます。選択した日付の範囲内の、Amazon EKSクラスタのコストの合計が表示されます。

Splunkダッシュボード

また、日ごとのAmazon EKSクラスタ全体のコストとNamespaceごとのコストが表示され、選択した日付の範囲内で推移を確認できます。

EKSクラスタ全体のコスト

Namespace単位のコスト

先述したようにKubecostではNamespaceだけでなくDeploymentやServiceなどのコストも集計しています。またコストの分析や予測、監視といった機能も提供していますが、弊社ではチームやサービス単位でのコストの可視化を目的としたため、上記の仕組みを採用しました。

効果

これまでの課題解決へのアプローチにより、マルチテナントのAWSアカウントとKubernetesのコスト可視化が実現できました。その結果、コストを正確に見積もることができるようになり、適切な予算管理が可能になりました。またチームやサービス単位でコストが明確に分離・可視化できるようになりました。

次に、コスト可視化の活用事例をご紹介します。

コスト可視化の活用事例

ZOZOTOWNのカート投入処理では、Webサーバとデータベースの間にキューイングシステムを挟むことでリクエストのキャパシティコントロールを実現しています。このシステムで使われているAmazon Kinesis Data Streamsのシャード数を変更しました。

techblog.zozo.com

以下の図は、左側がシャード数変更前のコストを示し、右側がシャード変更後のコストを示しています。関連リソースのAmazon DynamoDBを含め、大幅なコストの削減が実現できました。

コスト最適化の結果

このようにコスト可視化によって効果が明確に見えるようになったことは、コスト最適化の業務に取り組むうえでのモチベーション向上に繋がりました。

最後に

本記事では、マルチテナントのAWSアカウントとKubernetesにおけるコスト可視化の課題に対し、AWSコスト配分タグの活用とKubecostの導入による解決事例を紹介しました。同様の課題を抱えている方がいれば、ぜひ参考にしてください。

SREにおいてコスト最適化は重要なミッションです。今回ご紹介したコスト可視化の仕組みを利用し、ZOZOTOWNの信頼性向上の一環として取り組んでいきます。

ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。

corp.zozo.com

カテゴリー