オブザーバビリティ - Amazon EKS

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

オブザーバビリティ

序章

オブザーバビリティツールは、ワークロードを効率的に検出、修復、調査するのに役立ちます。テレメトリデータのコストは、EKS の使用が増えるにつれて自然に増加します。運用上のニーズのバランスを取り、ビジネスにとって何が重要かを測定し、オブザーバビリティコストを抑えるのは難しい場合があります。このガイドでは、オブザーバビリティの 3 つの柱であるログ、メトリクス、トレースのコスト最適化戦略に焦点を当てています。これらのベストプラクティスはそれぞれ、組織の最適化目標に合わせて個別に適用できます。

ロギング

ログ記録は、クラスター内のアプリケーションのモニタリングとトラブルシューティングに重要な役割を果たします。ログ記録コストを最適化するために使用できる戦略はいくつかあります。以下に示すベストプラクティス戦略には、ログ保持ポリシーを調べてログデータを保持する期間をきめ細かく制御すること、重要度に基づいてログデータをさまざまなストレージオプションに送信すること、ログフィルタリングを使用して保存されるログメッセージのタイプを絞り込むことなどがあります。ログテレメトリを効率的に管理することで、環境のコスト削減につながります。

EKS コントロールプレーン

コントロールプレーンログの最適化

Kubernetes コントロールプレーンは、クラスターを管理するコンポーネントのセットであり、これらのコンポーネントはさまざまなタイプの情報をログストリームとして Amazon CloudWatch のロググループに送信します。すべてのコントロールプレーンログタイプを有効にするとメリットがありますが、各ログの情報と、すべてのログテレメトリを保存するための関連コストに注意する必要があります。クラスターから Amazon CloudWatch Logs に送信されたログの標準の CloudWatch Logs データインジェストとストレージコストに対して課金されます。 Amazon CloudWatch 有効にする前に、各ログストリームが必要かどうかを評価します。

例えば、本番稼働用以外のクラスターでは、API サーバーログなどの特定のログタイプを分析のためにのみ選択的に有効にし、後で無効にします。ただし、イベントを再現できず、問題を解決するにはより多くのログ情報が必要な本番稼働用クラスターでは、すべてのログタイプを有効にできます。コントロールプレーンのコスト最適化の実装の詳細については、このブログ記事を参照してください。

S3 にログをストリーミングする

もう 1 つのコスト最適化のベストプラクティスは、CloudWatch Logs サブスクリプションを介してコントロールプレーンログを S3 にストリーミングすることです。CloudWatch Logs サブスクリプションを使用すると、ログを S3 に選択的に転送できるため、CloudWatch でログを無期限に保持するよりもコスト効率の高い長期ストレージが提供されます。例えば、本番クラスターの場合、重要なロググループを作成し、サブスクリプションを活用して 15 日後にこれらのログを S3 にストリーミングできます。これにより、分析のためにログにすばやくアクセスできますが、ログをよりコスト効率の高いストレージに移動することでコストを削減できます。

重要

9/5/2023 の時点で、EKS ログは Amazon CloudWatch Logs で Vended Logs として分類されます。提供されたログは、AWS のサービスが顧客に代わってネイティブに発行する特定の AWS サービスログで、ボリューム割引料金で利用できます。Vended Logs の料金の詳細については、Amazon CloudWatch の料金ページを参照してください。

EKS データプレーン

ログの保持

Amazon CloudWatch のデフォルトの保持ポリシーでは、ログを無期限に保持し、有効期限が切れないようにすることで、AWS リージョンに適用されるストレージコストが発生します。ストレージコストを削減するために、ワークロードの要件に基づいて各ロググループの保持ポリシーをカスタマイズできます。

開発環境では、保持期間を長くする必要がない場合があります。ただし、本番環境では、トラブルシューティング、コンプライアンス、キャパシティプランニングの要件を満たすために、より長い保持ポリシーを設定できます。例えば、ピークの祝祭日シーズンに e コマースアプリケーションを実行していて、システムが負荷が高くなり、すぐには気付かないような問題が発生する可能性がある場合は、詳細なトラブルシューティングとイベント後分析のために、より長いログ保持期間を設定する必要があります。

AWS CloudWatch コンソールまたは AWS API で、各ロググループに基づいて 1 日から 10 年の保持期間を設定できます。保持期間を柔軟に設定することで、重要なログを維持しながら、ログのストレージコストを節約できます。

ログストレージオプション

ストレージはオブザーバビリティコストの大きな要因であるため、ログストレージ戦略を最適化することが重要です。戦略は、パフォーマンスとスケーラビリティを維持しながら、ワークロードの要件と一致する必要があります。ログの保存コストを削減する 1 つの戦略は、AWS S3 バケットとそのさまざまなストレージ階層を活用することです。

S3 に直接ログを転送する

開発環境など、重要度の低いログは、Cloudwatch ではなく S3 に直接転送することを検討してください。これにより、ログストレージコストにすぐに影響する可能性があります。1 つのオプションは、Fluentbit を使用してログを S3 に直接転送することです。これは、FluentBit が保持のためにコンテナログを送信する送信先である [OUTPUT]セクションで定義します。追加の設定パラメータについては、こちらを参照してください

[OUTPUT]
        Name eks_to_s3
        Match application.*
        bucket $S3_BUCKET name
        region us-east-2
        store_dir /var/log/fluentbit
        total_file_size 30M
        upload_timeout 3m

短期分析のためにのみ CloudWatch にログを転送する

データの即時分析が必要な本番環境など、より重要なログについては、ログを CloudWatch に転送することを検討してください。これは、FluentBit が保持のためにコンテナログを送信する送信先である [OUTPUT]セクションで定義します。追加の設定パラメータについては、こちらを参照してください

[OUTPUT]
        Name eks_to_cloudwatch_logs
        Match application.*
        region us-east-2
        log_group_name fluent-bit-cloudwatch
        log_stream_prefix from-fluent-bit-
        auto_create_group On

ただし、これはコスト削減にすぐには影響しません。さらに節約するには、これらのログを Amazon S3 にエクスポートする必要があります。

CloudWatch から Amazon S3 にエクスポートする

Amazon CloudWatch logsを長期間保存する場合は、Amazon EKS CloudWatch ログを Amazon Simple Storage Service (Amazon S3) にエクスポートすることをお勧めします。コンソールまたは API を使用してエクスポートタスクを作成することで、ログを Amazon S3 バケットに転送できます。これを行うと、Amazon S3 はコストをさらに削減するための多くのオプションを提供します。独自の Amazon S3 ライフサイクルルールを定義して、ニーズに合ったストレージクラスにログを移動したり、Amazon S3 Intelligent-Tiering ストレージクラスを活用して、AWS が使用パターンに基づいてデータを長期ストレージに自動的に移動させることができます。詳細については、このブログを参照してください。例えば、本番環境のログは CloudWatch に 30 日以上保存され、Amazon S3 バケットにエクスポートされます。その後、後でログを参照する必要がある場合は、Amazon Athena を使用して Amazon S3 バケット内のデータをクエリできます。

ログレベルを減らす

アプリケーションの選択的ログ記録を練習します。アプリケーションとノードの両方がデフォルトでログを出力します。アプリケーションログについては、ワークロードと環境の重要性に合わせてログレベルを調整します。例えば、以下の Java アプリケーションは、一般的なデフォルトのアプリケーション設定であるINFOログを出力しており、コードによっては大量のログデータが発生する可能性があります。

import org.apache.log4j.*;

public class LogClass {
   private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);

public static void main(String[] args) {
      log.setLevel(Level.INFO);

   log.debug("This is a DEBUG message, check this out!");
   log.info("This is an INFO message, nothing to see here!");
   log.warn("This is a WARN message, investigate this!");
   log.error("This is an ERROR message, check this out!");
   log.fatal("This is a FATAL message, investigate this!");    } }

開発環境では、ログレベルを に変更します。これによりDEBUG、問題をデバッグしたり、本番環境に入る前に潜在的な問題を捕捉したりすることができます。

log.setLevel(Level.DEBUG);

本番環境では、ログレベルを ERRORまたは に変更することを検討してくださいFATAL。これにより、アプリケーションにエラーがある場合にのみログが出力され、ログ出力が減少し、アプリケーションのステータスに関する重要なデータに集中するのに役立ちます。

log.setLevel(Level.ERROR);

さまざまな Kubernetes コンポーネントのログレベルを微調整できます。たとえば、EKS Node オペレーティングシステムとして Bottlerocket を使用している場合、kubelet プロセスログレベルを調整できる構成設定があります。この設定のスニペットを以下に示します。kubelet プロセスのログ詳細度を調整するデフォルトのログレベル 2 に注意してください。

[settings.kubernetes]
log-level = "2"
image-gc-high-threshold-percent = "85"
image-gc-low-threshold-percent = "80"

開発環境では、追加のイベントを表示するためにログレベルを 2 より大きく設定できます。これはデバッグに適しています。本番環境では、レベルを 0 に設定して、重要なイベントのみを表示できます。

フィルターの活用

デフォルトの EKS Fluentbit 設定を使用して Cloudwatch にコンテナログを送信する場合、FluentBit は、以下の[INPUT]設定ブロックに示すように、Kubernetes メタデータで強化されたすべてのアプリケーションコンテナログをキャプチャして Cloudwatch に送信します。

 [INPUT]
     Name                tail
     Tag                 application.*
     Exclude_Path        /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
     Path                /var/log/containers/*.log
     Docker_Mode         On
     Docker_Mode_Flush   5
     Docker_Mode_Parser  container_firstline
     Parser              docker
     DB                  /var/fluent-bit/state/flb_container.db
     Mem_Buf_Limit       50MB
     Skip_Long_Lines     On
     Refresh_Interval    10
     Rotate_Wait         30
     storage.type        filesystem
     Read_from_Head      ${READ_FROM_HEAD}

上記の[INPUT]セクションでは、すべてのコンテナログを取り込んでいます。これにより、必要のない大量のデータが生成されます。このデータをフィルタリングすると、CloudWatch に送信されるログデータの量を減らすことができるため、コストを削減できます。CloudWatch に出力する前に、ログにフィルターを適用できます。Fluentbit は、 [FILTER]セクションでこれを定義します。例えば、Kubernetes メタデータがログイベントに追加されないようにフィルタリングすると、ログボリュームを減らすことができます。

    [FILTER]
        Name                nest
        Match               application.*
        Operation           lift
        Nested_under        kubernetes
        Add_prefix          Kube.

    [FILTER]
        Name                modify
        Match               application.*
        Remove              Kube.<Metadata_1>
        Remove              Kube.<Metadata_2>
        Remove              Kube.<Metadata_3>

    [FILTER]
        Name                nest
        Match               application.*
        Operation           nest
        Wildcard            Kube.*
        Nested_under        kubernetes
        Remove_prefix       Kube.

メトリクス

メトリクスは、システムのパフォーマンスに関する貴重な情報を提供します。システム関連または利用可能なすべてのリソースメトリクスを一元的な場所に統合することで、パフォーマンスデータを比較および分析できます。この一元化されたアプローチにより、リソースのスケールアップやスケールダウンなど、より多くの情報に基づいた戦略的意思決定を行うことができます。さらに、 メトリクスはリソースの正常性を評価する上で重要な役割を果たし、必要に応じてプロアクティブに対策を講じることができます。一般的に、オブザーバビリティのコストは、テレメトリデータの収集と保持に応じてスケールされます。以下は、メトリクステレメトリのコストを削減するために実装できるいくつかの戦略です。重要なメトリクスのみを収集し、テレメトリデータの基数を減らし、テレメトリデータ収集の詳細度を微調整します。

重要なものをモニタリングし、必要なもののみを収集する

最初のコスト削減戦略は、収集するメトリクスの数を減らし、保持コストを削減することです。

  1. まず、自分やステークホルダーの要件から逆算して、最も重要なメトリクスを決定します。成功メトリクスは、すべてのユーザーで異なります。良いものがどのように見えるかを把握し、それを測定します。

  2. サポートしているワークロードを深く掘り下げ、その主要業績評価指標 (KPIs「ゴールデンシグナル」を特定することを検討してください。これらは、ビジネス要件とステークホルダー要件と一致する必要があります。Amazon CloudWatch と Metric Math を使用して SLIs、SLOs、SLAs を計算することは、サービスの信頼性を管理するために不可欠です。このガイドで説明されているベストプラクティスに従って、EKS 環境のパフォーマンスを効果的にモニタリングおよび維持します。

  3. 次に、さまざまなインフラストラクチャレイヤーを続行して、EKS クラスター、ノード、追加のインフラストラクチャメトリクスをワークロード KPIs に接続して関連付けます。ビジネスメトリクスと運用メトリクスを相互に関連付けて、観察された影響に基づいて結論を導き出すことができるシステムに保存します。

  4. EKS は、コントロールプレーン、クラスター kube-state-metrics、ポッド、ノードからのメトリクスを公開します。これらのすべてのメトリクスの関連性はニーズによって異なりますが、異なるレイヤーにまたがるすべてのメトリクスは必要ない可能性があります。この EKS 必須メトリクスガイドは、EKS クラスターとワークロードの全体的な状態をモニタリングするためのベースラインとして使用できます。

kubelet メトリクスのみを保持し、すべてのコンテナメトリクスを削除relabel_configするために を使用する prometheus スクレイプ設定の例metric_relabel_configを次に示します。

kubernetes_sd_configs: - role: endpoints namespaces: names: - kube-system bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_service_label_k8s_app] regex: kubelet action: keep metric_relabel_configs: - source_labels: [__name__] regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) action: drop

必要に応じて濃度を下げる

カーディナリティとは、特定のメトリクスセットのディメンション (prometheus ラベルなど) と組み合わせたデータ値の一意性を指します。高基数メトリクスには多くのディメンションがあり、各ディメンションメトリクスの組み合わせの一意性は高くなります。カーディナリティが高いほど、メトリクステレメトリのデータサイズとストレージのニーズが大きくなり、コストが増加します。

以下の高基数例では、メトリクス、レイテンシー、ディメンション、RequestID、CustomerID、サービスがあり、各ディメンションに多くの一意の値があることがわかります。カーディナリティは、ディメンションあたりの可能な値の数の組み合わせの尺度です。Prometheus では、一意のディメンション/ラベルの各セットが新しいメトリクスと見なされるため、カーディナリティが高いほどメトリクスが多くなります。

メトリクスごとに多くのメトリクスとディメンション/ラベル (クラスター、名前空間、サービス、ポッド、コンテナなど) を持つ EKS 環境では、基数が増加する傾向があります。コストを最適化するには、収集するメトリクスの基数を慎重に検討してください。例えば、クラスターレベルで視覚化する特定のメトリクスを集約する場合、名前空間ラベルなどの下位レイヤーにある追加のラベルを削除できます。

prometheus で高基数メトリクスを識別するには、次の PROMQL クエリを実行して、メトリクス (基数) の数が最も多いスクレイプターゲットを判断できます。

topk_max(5, max_over_time(scrape_samples_scraped[1h]))

および次の PROMQL クエリは、どのスクレイプターゲットが最も高いメトリクスチャーン (特定のスクレイプで作成された新しいメトリクスシリーズの数) 率を持つかを判断するのに役立ちます。

topk_max(5, max_over_time(scrape_series_added[1h]))

grafana を使用している場合は、Grafana Lab の Mimirtool を使用して grafana ダッシュボードと prometheus ルールを分析し、未使用の高濃度メトリクスを特定できます。ダッシュボードで参照されていないアクティブなメトリクスを特定するには、 mimirtool analyzeおよび mimirtool analyze prometheus コマンドを使用する方法に関するこのガイドに従ってください。

メトリクスの詳細度を考慮する

毎秒のように、毎分よりも細かくメトリクスを収集すると、テレメトリを収集して保存する量に大きな影響を与え、コストが増加する可能性があります。一時的な問題を確認するのに十分な詳細度と、費用対効果を高めるために十分な低度のバランスをとる、適切なスクレイプまたはメトリクス収集間隔を決定します。キャパシティプランニングとより大きな時間枠分析に使用されるメトリクスの詳細度を下げます。

以下は、デフォルトの AWS Distro for Opentelemetry (ADOT) EKS Addon Collector 設定のスニペットです。

重要

グローバル prometheus スクレイプ間隔は 15 秒に設定されています。このスクレイプ間隔を長くすると、prometheus で収集されるメトリクスデータの量が減少します。

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector-amp

...

config: |
    extensions:
      sigv4auth:
        region: "+++<YOUR_AWS_REGION>+++" service: "aps"+++</YOUR_AWS_REGION>+++

 receivers:
   #
   # Scrape configuration for the Prometheus Receiver
   # This is the same configuration used when Prometheus is installed using the community Helm chart
   #
   prometheus:
     config:
       global:   scrape_interval: 15s
         scrape_timeout: 10s

トレース

トレースに関連する主なコストは、トレースストレージの生成によるものです。トレースでは、パフォーマンスの側面を診断して理解するための十分なデータを収集することが目的です。ただし、X-Ray トレースのコストは X-Ray に転送されたデータに基づいているため、転送後にトレースを消去してもコストは削減されません。適切な分析を実行するためにデータを維持しながら、トレースのコストを削減する方法を確認しましょう。

サンプリングルールを適用する

X-Ray のサンプリングレートはデフォルトで控えめです。収集するデータ量を制御できるサンプリングルールを定義します。これにより、コストを削減しながらパフォーマンス効率が向上します。サンプリングレートを減らすことで、より低いコスト構造を維持しながら、ワークロードに必要なものだけをリクエストからトレースを収集できます。

例えば、問題のある 1 つのルートに対するすべてのリクエストのトレースをデバッグする Java アプリケーションがあるとします。

JSON ドキュメントからサンプリングルールをロードするように SDK 経由で を設定する

{ "version": 2, "rules": [ { "description": "debug-eks", "host": "*", "http_method": "PUT", "url_path": "/history/*", "fixed_target": 0, "rate": 1, "service_type": "debug-eks" } ], "default": { "fixed_target": 1, "rate": 0.1 } }

コンソール経由

AWS Distro for OpenTelemetry (ADOT) によるテールサンプリングの適用

ADOT Tail Sampling を使用すると、サービスに取り込まれたトレースのボリュームを制御できます。ただし、テールサンプリングでは、リクエスト内のすべてのスパンが完了した後に、最初ではなくサンプリングポリシーを定義できます。これにより、CloudWatch に転送される raw データの量がさらに制限されるため、コストが削減されます。

例えば、ランディングページへのトラフィックの 1% と支払いページへのリクエストの 10% をサンプリングする場合、30 分間に 300 トレースが残る可能性があります。特定のエラーをフィルタリングする の ADOT Tail Sampling ルールでは、200 個のトレースを残して保存されるトレースの数を減らすことができます。

processors:
  groupbytrace:
    wait_duration: 10s
    num_traces: 300
    tail_sampling:
    decision_wait: 1s # This value should be smaller than wait_duration
    policies:
      - ..... # Applicable policies**
  batch/tracesampling:
    timeout: 0s # No need to wait more since this will happen in previous processors
    send_batch_max_size: 8196 # This will still allow us to limit the size of the batches sent to subsequent exporters

service:
  pipelines:
    traces/tailsampling:
      receivers: [otlp]
      processors: [groupbytrace, tail_sampling, batch/tracesampling]
      exporters: [awsxray]

Amazon S3 ストレージオプションを活用する

トレースを保存するには、AWS S3 バケットとそのさまざまなストレージクラスを活用する必要があります。保持期間が終了する前にトレースを S3 にエクスポートします。Amazon S3 ライフサイクルルールを使用して、要件を満たすストレージクラスにトレースデータを移動します。

例えば、90 日経過のトレースがある場合、Amazon S3 Intelligent-Tiering は使用パターンに基づいてデータを長期ストレージに自動的に移動できます。後でトレースを参照する必要がある場合は、Amazon Athena を使用して Amazon S3 内のデータをクエリできます。これにより、分散トレースのコストをさらに削減できます。

その他のリソース: