翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
オブザーバビリティ
序章
オブザーバビリティツールは、ワークロードを効率的に検出、修復、調査するのに役立ちます。テレメトリデータのコストは、EKS の使用が増えるにつれて自然に増加します。運用上のニーズのバランスを取り、ビジネスにとって何が重要かを測定し、オブザーバビリティコストを抑えるのは難しい場合があります。このガイドでは、オブザーバビリティの 3 つの柱であるログ、メトリクス、トレースのコスト最適化戦略に焦点を当てています。これらのベストプラクティスはそれぞれ、組織の最適化目標に合わせて個別に適用できます。
ロギング
ログ記録は、クラスター内のアプリケーションのモニタリングとトラブルシューティングに重要な役割を果たします。ログ記録コストを最適化するために使用できる戦略はいくつかあります。以下に示すベストプラクティス戦略には、ログ保持ポリシーを調べてログデータを保持する期間をきめ細かく制御すること、重要度に基づいてログデータをさまざまなストレージオプションに送信すること、ログフィルタリングを使用して保存されるログメッセージのタイプを絞り込むことなどがあります。ログテレメトリを効率的に管理することで、環境のコスト削減につながります。
EKS コントロールプレーン
コントロールプレーンログの最適化
Kubernetes コントロールプレーンは、クラスターを管理するコンポーネントのセット
例えば、本番稼働用以外のクラスターでは、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
ログレベルを減らす
アプリケーションの選択的ログ記録を練習します。アプリケーションとノードの両方がデフォルトでログを出力します。アプリケーションログについては、ワークロードと環境の重要性に合わせてログレベルを調整します。例えば、以下の 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 オペレーティングシステムとして Bottlerocketkubelet
プロセスのログ詳細度を調整するデフォルトのログレベル
[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.
メトリクス
メトリクス
重要なものをモニタリングし、必要なもののみを収集する
最初のコスト削減戦略は、収集するメトリクスの数を減らし、保持コストを削減することです。
-
まず、自分やステークホルダーの要件から逆算して、最も重要なメトリクス
を決定します。成功メトリクスは、すべてのユーザーで異なります。良いものがどのように見えるかを把握し、それを測定します。 -
サポートしているワークロードを深く掘り下げ、その主要業績評価指標 (KPIs「ゴールデンシグナル」を特定することを検討してください。これらは、ビジネス要件とステークホルダー要件と一致する必要があります。Amazon CloudWatch と Metric Math を使用して SLIs、SLOs、SLAs を計算することは、サービスの信頼性を管理するために不可欠です。このガイド
で説明されているベストプラクティスに従って、EKS 環境のパフォーマンスを効果的にモニタリングおよび維持します。 -
次に、さまざまなインフラストラクチャレイヤーを続行して、EKS クラスター、ノード、追加のインフラストラクチャメトリクスをワークロード KPIs に接続して関連付け
ます。ビジネスメトリクスと運用メトリクスを相互に関連付けて、観察された影響に基づいて結論を導き出すことができるシステムに保存します。 -
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