お客様のDXの推進やクラウド活用をサポートする
NRIグループのプロフェッショナルによるブログ記事を掲載

EKS運用におけるコスト削減活動のご紹介

はじめに

こんにちは。NRIの西山と江口です。わたしたちはシステムの監視やアラート、ジョブ制御などの運用に関わる運用基盤サービスを提供するクラウド(以下運用クラウド)のプラットフォームエンジニアとして活動しています。

よりよいサービスを利用者に提供するために、アジリティ・セキュリティ・品質向上・コスト削減などを考えて、運用クラウドの開発から運用に関わる全ての領域において活動し、運用クラウド環境を維持管理しています。また、NRI運用システムのアプリ開発を担当する内部のアプリチームに対して、低い学習コストでプラットフォームを利用いただくことをミッションのひとつとしています。

運用クラウドではAmazon Elastic Kubernetes Service(以下EKS)を利用しています。5年ほど本番運用しており、現在では約150台のワーカーノードと約2500Podが稼働しています。
本ブログでは、わたしたちが取り組んだEKSのコスト削減活動について紹介します。EKSを運用している方々の参考になれば幸いです。

 

運用クラウドのEKS環境について

運用クラウドでは、お客様システムの監視やジョブ管理といったシステム運用をサポートする運用ソリューションを開発し、提供しています。アプリケーションから基盤まで各レイヤーの専門家がワンチームとなって活動しており、アジリティ高く様々なソリューションを提供するためにEKSを採用しました。

運用クラウドのEKS環境は、本番環境とUAT環境の2面を提供しています。 本番環境はその名の通り本番用途に利用しており、UAT環境はユーザ受入テストをはじめ、外部結合や総合テスト環境としても利用しています。
UAT環境の機能/非機能(主に性能)は本番と全く同じとしており、違うところは論理的なネットワーク部分のみとなっています。
UAT環境と本番環境の環境差異を極力小さくすることでテストや本番リリース作業の品質の向上につなげています。

 

コスト面の課題

本番環境と同等のUAT環境を準備することで品質を向上できる一方、コスト面の課題がありました。 EKSはEC2インスタンスを利用して稼働させるのですが、規模が大きくなるにつれ、このEC2インスタンスのコストが大きくなります。 この対策としては「リザーブドインスタンスを活用する」ことや「使っていない時間帯でインスタンスは停止する」ことなどがあげられます。
前者のリザーブドインスタンス活用は以前から行っていましたが、NRIでは日欧米の運用拠点からフォロー・ザ・サンで24時間365日運用されており、日本の夜間でも海外拠点のエンジニアからUAT環境を利用されることがあります。 UAT環境は常に使える状態にしておかなければならないため後者の「使っていない時間帯でインスタンスは停止する」ことは現実的な改善策となりませんでした。

 

課題への対策

UAT環境の機能と非機能の特性を整理すると以下のようになります。

  • 機能
    • 本番環境と同等のものが要求される
  • 非機能
    • 性能やセキュリティレベルは本番環境と同等のものが要求される
    • 可用性は本番環境ほど問われないが、24時間365日での利用が要求される
    • コスト要件として、極力低減することが要求される

この特性から「スポットインスタンスの活用」と「インスタンス数の削減」という対策を実施しました。

 

対策1:UAT環境のスポットインスタンスの活用

1つ目の対策として、スポットインスタンスの活用を行いました。
EKSでは、ノードグループ作成時に「キャパシティ購入オプション」を設定することで、オンデマンドインスタンスとスポットインスタンスを簡単に切り替えることが可能です。 この機能を活用することで、柔軟なリソース管理とコスト削減を両立できます。
ここでは、スポットインスタンスの概要とともに、EKSでのスポットインスタンス利用の考慮事項について解説します。

 

スポットインスタンスとは

スポットインスタンスは、AWSの未使用リソースを活用するインスタンスで、オンデマンドインスタンスに比べて最大70%のコスト削減が可能です。 ただし、AWSのリソース状況によって予告なしに中断される可能性があります。 この特性を理解し、適切に活用することが重要です。

このデメリットを許容しコストメリットを受けるために、スポットインスタンス利用のベストプラクティスとして以下の5つが挙げられます。

  1. インスタンスタイプ・AZを柔軟に選定:複数のインスタンスタイプやアベイラビリティゾーンを利用することで、必要なリソースを確保しやすくします。
  2. 料金キャパシティ最適化オプションを使用:Auto Scalingの「料金キャパシティ最適化」オプションを利用し、価格が低く余剰が多いスポットインスタンスを選択します。
  3. 「容量の再調整」の有効化:「容量の再調整」を有効化することで、インスタンスの中断通知が来る前に、新しいスポットインスタンスに置き換えワークロードの安定性を高めます。
  4. AWSの統合サービスを活用:EKS、ECS、EMRなどのAWSサービスのキャパシティ購入オプションを利用することで、スポットインスタンスの運用負荷を軽減します。
  5. スケーリングサービスと併用:Auto Scalingを活用し、ワークロードの変動に柔軟に対応します。

 

スポットインスタンスの選定

スポットインスタンスに利用するインスタンスタイプの選定は、3つの観点で実施しました。

  1. 上記ベストプラクティス1「インスタンスタイプ・AZを柔軟に選定」に倣い複数のインスタンスタイプを選定することで、UAT環境のサービス継続性を向上させる。
  2. 本番環境と同等のスペック・アーキテクチャのインスタンスタイプを選定することで、本番相当の環境を提供する。
  3. オンデマンド料金からの費用節減率を確認し、コストメリットの大きいインスタンスタイプを選定する。

わたしたちの本番環境では、m5.largeのインスタンスを利用しています。 上記の3点を考慮し、以下のインスタンスタイプを選定しました。
6つのインスタンスタイプを利用しAuto Scalingを構成することでUAT環境で必要なキャパシティを安定して確保しつつ、60%程度のコスト削減を実現しました。
ネットワーク帯域幅に関しては、わたしたちの環境で稼働しているアプリケーション特性を考慮し、インスタンスタイプ選定では考慮しない方針としました。

#

インスタンスタイプ

vCPU

メモリ (GiB)

ネットワーク帯域幅 (Gbps)

オンデマンド比費用節減 ※1

中断の頻度 ※1, ※2

1

m5.large

2

8

最大 10

60%

>20%

2

m6i.large

2

8

最大 12.5

64%

15-20%

3

m6id.large

2

8

最大 12.5

62%

15-20%

4

m6idn.large

2

8

最大 25

63%

15-20%

5

m7i.large

2

8

最大 12.5

62%

5-10%

6

m7i-flex.large

2

8

最大 12.5

62%

<5%

  • ※1: 2024/10/25 18:30時点のスポットインスタンスアドバイザーを参照
    • ※2: 中断の頻度は、直近の1か月の期間にEC2スポットサービスがキャパシティを回収した割合を示します。その割合は <5%、5~10%、10~15%、15~20%、>20% の範囲です。

その他のAuto Scalingの設定については、下記の通りとなります。

  • スポット割り当て戦略: EKSでは「料金キャパシティ最適化」が選択される
  • 容量の再調整: ON(デフォルトON)

 

対策2-1:インスタンス数の削減〜aws-nodeのパラメータ調整〜

2つ目の対策として、インスタンス数を削減することでコスト削減を実現しました。
本番環境では、aws-nodeのパラメータ調整により、1インスタンスで稼働するPod数を制限しており、UAT環境も同様の設定としていました。そこで、UATのパラメータの見直しを行い、1インスタンスで最大限Podが稼働するように設定変更を行いました。 ここでは、aws-nodeの概要とパラメータチューニングについて説明します。

aws-nodeとは

aws-nodeとは、EKSのアドオンである「Amazon VPC CNI plugin for Kubernetes」を追加することでデプロイされる各ワーカーノードに配置されるPodで、VPCネットワークインターフェース(ENI)をPodに割り当てる役割を担います。

大きく2つの機能を有しています。

  • IPアドレスのPodへの割り当てと管理:各Podが使用するIPアドレスをインスタンスにアタッチされているENIから割り当てます。
  • ENIとIPアドレスの動的管理:Podのライフサイクルやノード上のPod数に合わせて、必要なENIやIPアドレスを動的にEC2に割り当てたり解放したりします。

aws-nodeの環境変数の変更により、インスタンスにアタッチするENIや確保するIPアドレスの動作をチューニングすることが可能です。

主な環境変数は3つです。

パラメータ

説明

デフォルト

ベストプラクティス

WARM_ENI_TARGET

インスタンスが確保する余剰ENI数。Podに使用されていないENIをさします。1つでもPodが起動すると余剰ENIが追加される。上限はインスタンスタイプに依存する。 (例: m5.largeの場合、3ENI)

1

Podのスケールが頻繁に起こる場合に推奨

WARM_IP_TARGET

インスタンスが確保する余剰IP数

指定無し

小規模なクラスタや、Podの起動停止が少ないことが想定される場合に推奨

MINIMUM_IP_TARGET

インスタンスに最低限確保するIPアドレス数。指定がない場合、ENIの最大IP数を確保する (m5.large場合、10IP)

指定なし

Pod数の見積に基づき余裕を持って設定

EKSのIPアドレス枯渇問題については過去のブログでも紹介されていますので、詳細はそちらをご参考ください。

aws-nodeの設定変更

デフォルト設定の場合、m5.largeのインスタンスでは、以下の計算式より、最大で29個のIPをPod割り当て可能です。 (ネットワークインターフェイスあたりの IP アドレスの最大数)

10(IP/ENI) * 3(ENI) - 1(インスタンス自身のIP) = 29IP

一方、この設定では以下の問題が発生する可能性があります。

  • IP枯渇のリスク:実際に利用されないIPが確保され、IPが枯渇する。
  • リソース枯渇のリスク:配置されるPod数が多い場合、ノードのCPUやメモリが枯渇する可能性が高くなる。

そこで、本番環境ではPod数を20個(20IP)に制限する設計としました。 これにより、リソース枯渇のリスクを抑えつつ、必要な分だけIPを確保します。
具体的には、本番環境では以下の設定で運用しています。

  • MINIMUM_IP_TARGET: 15
  • WARM_IP_TARGET: 5

当初、UAT環境の環境変数についても本番環境と同様の設定としていましたが、あくまで本番環境向けの設定のため、UAT環境の利用用途・ワークロードにはそぐわない設定となっていました。

  • 安定性の優先度が低い:UAT環境は本番環境ほど安定稼働が必要ない。
  • リソースの遊休:テスト利用などPodの稼働が低いため、リソースが有効活用されていない。
  • 無駄な制限:20Podの制限により、過剰にノードが必要になっていた。

そこで、設定を変更し29Podを1ノードで収容可能にすることで、ノード数を削減しながらリソースを効率的に活用できるようにしました。
具体的には以下の設定へ変更しました。

  • MINIMUM_IP_TARGET: 20
  • WARM_IP_TARGET: 10

 

対策2-2:インスタンス数の削減〜アプリPodデプロイ時の自動リソース値変更〜

Kubernetesのコンテナのリソースについて

Kubernetes上で稼働するPod内のコンテナはリソースを制限することができます(参考)。リソースではrequestsとlimitsを利用してcpuとmemoryを制限することで、より厳格にKubernetes上で稼働するシステムを管理することができます。

  • requests
    • コンテナに確実に確保されるリソースが設定できます。
    • Kubernetesのスケジューラはrequestsで指定された情報を使用して、そのリソースが十分に確保できるノードにPodを配置します。
  • limits
    • コンテナはこの値を超えてCPUあるいはメモリを利用することはできません。
    • コンテナが稼働するにあたって、CPUはこの値でピン留めされ、メモリはこの値を超えるとkubeletがOOM Killerでコンテナが強制停止されます。
    • limitsはノードの割り当て可能なリソースを超えて設定することができ、いわゆるオーバーコミットすることができます。

Admission Controller / Admission Webhookについて

Kubernetesには、Admission Controlという機能があり、kubectlなどでオブジェクトが受け入れられた場合、それがetcdに保存されるまでに、その内容を変更したりバリデーションすることができます。 例えばAdmission Controlの機能により以下の処理が自動で行われます。

  • 存在しないnamespaceにリソースを定義するとき、namespaceの自動作成
  • デフォルトのストレージクラスの選択

Admission Controlにより、ポリシーとガバナンスの強制・クラスタ全体のセキュリティ向上・一貫した考えに基づくリソース管理といったことを実現することができます。

また、Admission Controlの機能を動的に実現するためにHTTPコールバックでアドミッション要求を受け取るAdmission Webhookという機能があります。この機能を利用してアプリPodをデプロイする際に自動的にリソース値を変更することができます。 Admission Webhookは以下の図のように動作します。

 

Admission Webhook定義の追加

わたしたちはAdmission Webhookを利用して、UATクラスタのコンテナリソース要求を小さくすることを実施しました。組織として以下のような背景があったため、Admission Webhookの効果を大きく受けることができました。

  • もともとアプリケーションのデプロイに関してはUAT環境と本番環境で共通するところが多く、同じマニフェストを利用しているところがある。コンテナリソース部分は同じであった。
  • プラットフォームエンジニアリングチームはアプリチームに負荷をかけることなくコスト削減を進めることを目標としており、アプリチームにマニフェストの変更してもらうことに抵抗があった。

Admisson Webhookの定義は以下のものを追加しました。
わたしたちの環境ではセキュリティ向上のためにGatekeeperを利用しています。 GatekeeperのAdmissionの変更機能を活用し、リソース要求の設定を強制的に上書きするよう設定しました。

具体的には、以下の設定を追加しました。

apiVersion: mutations.gatekeeper.sh/v1beta1
kind: Assign
spec:
  applyTo:
    - groups: [""]
      versions: ["v1"]
      kinds: ["Pod"]
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  location: "spec.containers[name:*].resources.requests"
  parameters:
    assign:
      value:
        cpu: "10m"
        memory: "10Mi"

この設定により、以下のイメージでPodがデプロイされる際にリソース要求が変更されます。

 

スポットインスタンスへの移行

スポットインスタンスへの移行に伴い前述の設定を効率よく適用するために、移行は4ステップで実施しました。

  1. Admission Webhook適用
  2. aws-node設定変更とスポットノードグループ作成
  3. オンデマンドノードグループのPodを再配置
  4. オンデマンドノードグループの削除

 

ステップ1: Admission Webhook適用
まず、Admission Webhookを適用します。
前述のとおり、リソース要求を強制的に上書きする設定を移行に先立って適用しました。 これにより、この後のノードグループ移行によるPod再配置時に、リソース要求を小さく抑えることができます。

ステップ2: aws-node設定変更とスポットノードグループ作成
次に、aws-nodeの設定変更とスポットノードグループを作成します。
Podの再配置のタイミングを制御するために、既存のオンデマンドノードグループとは別にスポットノードグループを追加する形で作成しました。

ステップ3: オンデマンドノードグループのPodを再配置
続いて、オンデマンドノードグループからスポットイノードグループへPodを移行します。
具体的には、「オンデマンドワーカーノードにPodが配置されないよう設定を追加し、Podを別のノードに再配置する(drain)」操作をすべてのオンデマンドノードに対して実行しました。 これにより、オンデマンドノードにはPodが配置されていない状態を作り、安全に次のステップ4を進められる環境を整えました。

ステップ4: オンデマンドノードグループの削除
最後にオンデマンドノードグループを削除します。

 

以上の4ステップで、今回設計した設定を反映しつつ、安全にスポットインスタンスへの移行を実施できました。

 

おわりに

今回は、EKS利用において現場運用に要求される事例についての実践的なコスト削減について紹介しました。 本記事で紹介したUAT環境のように高い可用性が求められないEKS環境を維持管理している方に有用と考えています。

わたしたちプラットフォームエンジニアリングチームは今回紹介したEKSの環境だけでなく、アプリチームの利用する開発環境・オンプレミス・OCI・AWS・リモートリポジトリ・CI/CDなどを維持管理しています。 これらの環境を自ら維持管理する中で、アジリティ向上・セキュリティ強化・品質向上・コスト削減・アプリチームの認知負荷削減など、数多くのノウハウを蓄積しているので、またの機会にご紹介できればと思います。

EKS環境の運用でお困りのことがありましたらぜひお気軽にお問合せください。

 

お問い合わせ

atlax では、ソリューション・サービス全般に関するご相談やお問い合わせを承っております。

 

関連リンク・トピックス

・atlax / クラウドの取り組み / AWS(Amazon Web Services)

・2023/01/24 「2022 年末 AWS GameDay 大会 for AWS Top Engineers」で、NRIが第1位を獲得 - 北條 学男・花岡 大輔・蒲 晃平・米澤 拓也 の チームが活躍 -

※ 記載された会社名 および ロゴ、製品名などは、該当する各社の登録商標または商標です。
※ アマゾン ウェブ サービス、Amazon Web Services、AWS および ロゴは、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。
※ Microsoft、Azure は、米国 Microsoft Corporation の米国およびその他の国における登録商標または商標です。
※ Google Cloud、Looker、BigQuery および Chromebook は、Google LLC の商標です。
※ Oracle、Java、MySQL および NetSuite は、Oracle Corporation、その子会社および関連会社の米国およびその他の国における登録商標です。NetSuite は、クラウド・コンピューティングの新時代を切り開いたクラウド・カンパニーです。