Amazon Web Services ブログ

Amazon EKS の Container Insights は AWS Distro for OpenTelemetry Collector をサポートします

この記事は Container Insights for Amazon EKS Support AWS Distro for OpenTelemetry Collector (記事公開日: 2021 年 9 月 17 日) を翻訳したものです。

CloudWatch Container Insights は、コンテナ化されたアプリケーションやマイクロサービスからメトリクスを収集、集約、要約します。メトリクスは、埋め込みメトリクスフォーマット (EMF) を使用してログイベントとして収集されます。これにより、大規模に、高カーディナリティのデータを取り込み、指定された CloudWatch ロググループに保存することが可能です。Amazon CloudWatch は、それらの埋め込まれたメトリクスを使用して、受信した EMF データから CloudWatch の集約されたメトリクスを作成し、CloudWatch の自動ダッシュボードに表示します。

AWS Distro for OpenTelemetry (ADOT) Collector v0.11.0 が、Amazon EKS の Container Insights で利用できるようになりました。今回のサポートでは、EKS のさまざまなコンポーネントの CPU、メモリ、ディスク、ネットワークなど多くのリソースのインフラストラクチャメトリクスを収集する AWS Container Insights Receiver という Receiver を導入しました。この Receiver は、CloudWatch EMF Exporter とともに、EKS クラスターで同様の CloudWatch Container Insights エクスペリエンスをサポートできます。言い換えれば、既存の Container Insights エクスペリエンスに変更を加えることなく、AWS Distro for OpenTelemetry (ADOT) Collector を最大限に活用することができます。

このブログ記事では、AWS Container Insights Receiver のデザインについて説明し、ADOT Collector を使って Container Insights のユースケースのためにインフラストラクチャメトリクスを収集する方法を紹介します。

ADOT Collector での Container Insights サポートのデザイン

以下の図は、AWS Container Insights Receiver のアーキテクチャと、Amazon EKS で Container Insights をサポートするために他のコンポーネントとどのように連携するかを示しています。

AWS Container Insights Receiver architecture diagram

メトリクス処理パイプラインとそのコンポーネント

Amazon EKS Container Insights のインフラストラクチャメトリクスを収集するために、ADOT Collector は DaemonSet としてデプロイされます。すなわち、前の図に示されているように、ワーカーノードごとに必ず 1 つの Collector Pod が存在します。この DaemonSet アプローチは、EC2 ワーカーノードを利用する Amazon EKS でのみサポートされます。ADOT Collector のメトリクス処理パイプラインは、次の 3 つの主要部分で構成されます。

  • さまざまなソースからデータを収集する AWS Container Insights Receiver
  • 既存のメトリクスを処理および操作する OpenTelemetry Processor
  • メトリクスを特定のバックエンドにプッシュするための CloudWatch EMF Exporter

パイプラインの最初のコンポーネントである AWS Container Insights Receiver は、あらゆる種類のアクティビティを担当し、次の 2 つの主要なソースからコンテナ関連のデータを収集します。

  • cadvisor コンポーネントは、コンテナ統計 API から情報を取得し、実行中のコンテナのリソース使用量とパフォーマンス特性を提供する、カスタマイズされた cAdvisor (Container Advisor) ライブラリを組み込みます。カスタマイズされた cAdvisor を使用して特定のメトリクスを収集し、それらのメトリクスは、ノード、ノードファイルシステム、ノードディスク IO、ノードネットワーク、Pod、Pod ネットワーク、コンテナ、コンテナファイルシステムのようなさまざまなインフラストラクチャレイヤーに分類されます。
  • k8sapiserver コンポーネントは、Kubernetes API サーバーからクラスターレベルのメトリクスを収集する役割を担っています。DaemonSet のうちの 1 つの ADOT Collector だけがクラスターレベルのメトリクスを収集していることを確実にするために、k8sapiserverリーダー選出 API をサポートする Kubernetes クライアントを統合します。LOCK プリミティブの一種として Kubernetes ConfigMap リソースを活用し、1 つの Collector のみがリーダーとなるためのロックを保持するようにします。

Receiver は、2 つの主要なデータソースに加えて、内部に組み込まれている host コンポーネントおよび store コンポーネントを介して追加のメタデータ情報を取得します。host コンポーネントは、EKS ワーカーノードに関する情報を収集するために使用されます。これらには proc ファイルシステムを使用したワーカーの CPU/メモリ容量、EC2 メタデータエンドポイントを使用したインスタンス ID/タイプ、EC2 API を使用した関連する Auto Scaling グループ情報などがあります。store コンポーネントは、収集されたすべてのメタデータ情報が保存される情報ストアとして機能します。

host と store を通じて収集された情報は、Amazon EKS の Container Insights のために収集されたメトリクスを強化するために、cadvisork8sapiserver の両方で使用されます。さらに、cadvisor は、Container Insights の Pod とコンテナのメトリクスを充実させる際に、追加のメタデータ情報を必要とします。このため、Container Insights Receiver は、同じノード上で実行されているすべての Pod オブジェクトをリストしてキャッシュするために、Kubelet とも対話する必要があります。また、Pod に関連するサービス名を取得するために、Kubernetes API サーバーにクエリを実行する必要もあります。この情報が必要なのは cadvisor だけです。

パイプラインの 2 番目のコンポーネントは、OpenTelemetry Processor 群です。これらはオプションですが、データがエクスポートされる前の、前処理を担当する重要なものです。Processor は属性を変更し、失敗した場合には再試行することで、データがパイプラインを正常に通過するようにします。次の様な多くの OpenTelemetry Processor が利用可能です。

  • 不要なメトリクスを除外するために使用できる Filter Processor
  • 不要な属性を削除するために使用できる Resource Processor
  • スパン、メトリクス、またはログを受け入れ、それらをバッチに配置する Batch Processor

しかしながら、私たちのデフォルト設定では、CloudWatch EMF ログのリクエストのスループットを向上させるために、Batch Processor を有効にしています。この Batch Processor の設定では、収集された OpenTelemetry メトリクスデータは、タイムアウトのしきい値 (デフォルトでは 30 秒) またはバッチサイズ (デフォルトでは 8192 バイト) のいずれかに達するまでメモリ内でバッチ処理されます。ビジネスやアプリケーションの要件を満たすために、ADOT Collector でサポートされている追加の Processor を追加する必要があるかもしれません。

パイプラインの 3 番目であり最後のコンポーネントは CloudWatch EMF Exporter (awsemf) で、メトリクスを EMF ログとして CloudWatch バックエンドに送信するために使用されます。awsemf Exporter の設定では、ロググループ名とログストリーム名に主に 2 つのプレースホルダー {ClusterName} と {NodeName} があります。これらは、クラスターの名前と ADOT Collector が動作しているノードの名前に動的に置き換えられます。

始めてみよう

AWS OTel Collector を使用してサービスクラスターのインフラストラクチャメトリクスを収集するには、すべての前提条件が満たされていることを確認する必要があります。

次に、以下のコマンドを入力することで、AWS OTel Collector を DaemonSet としてクラスターに展開できます。

curl https://raw.githubusercontent.com/aws-observability/aws-otel-collector/main/deployment-template/eks/otel-container-insights-infra.yaml |
kubectl apply -f -

コマンドを実行して AWS OTel Collector をデプロイすると、”aws-otel-eks” という新しい Namespace が作成され、関連するすべての Kubernetes オブジェクトは、default Namespace ではなくこの Namespace 内に作成されます。

インストールの確認

以下のコマンドを実行して、AWS OTel Collector が正常に実行されているかどうかを確認できます。

kubectl get pods -l name=aws-otel-eks-ci -n aws-otel-eks

さらに、Pod のログを確認し、以下の期待される出力と比較することもできます。

kubectl logs aws-otel-eks-ci-XXXXX -n aws-otel-eks

Pod レベルでの期待される出力

2021/08/08 00:18:19 AWS OTel Collector version: v0.11.0
2021/08/08 00:18:19 find no extra config, skip it, err: open /opt/aws/aws-otel-collector/etc/extracfg.txt: no such file or directory
2021-08-08T00:18:19.975Z info service/collector.go:262 Starting aws-otel-collector... {"Version": "v0.11.0", "NumCPU": 2}
2021-08-08T00:18:19.975Z info service/collector.go:170 Setting up own telemetry...
2021-08-08T00:18:19.976Z info service/telemetry.go:99 Serving Prometheus metrics {"address": ":8888", "level": 0, "service.instance.id": "ee7ecd58-340c-4166-b693-9fd688c27d60"}
2021-08-08T00:18:19.976Z info service/collector.go:205 Loading configuration...
2021-08-08T00:18:19.979Z info service/collector.go:221 Applying configuration...
...
2021-08-08T00:18:19.981Z info service/service.go:137 Starting extensions...
2021-08-08T00:18:19.981Z info builder/extensions_builder.go:53 Extension is starting... {"kind": "extension", "name": "health_check"}
2021-08-08T00:18:19.981Z info healthcheckextension/healthcheckextension.go:41 Starting health_check extension {"kind": "extension", "name": "health_check", "config": {"Port":0,"TCPAddr":{"Endpoint":"0.0.0.0:13133"}}}
2021-08-08T00:18:19.981Z info builder/extensions_builder.go:59 Extension started. {"kind": "extension", "name": "health_check"}
2021-08-08T00:18:19.981Z info service/service.go:182 Starting exporters...
...
2021-08-08T00:18:19.981Z info service/service.go:187 Starting processors...
...
2021-08-08T00:18:19.981Z info service/service.go:192 Starting receivers...
2021-08-08T00:18:19.983Z info host/ec2metadata.go:72 Fetch instance id and type from ec2 metadata {"kind": "receiver", "name": "awscontainerinsightreceiver"}
W0808 00:18:20.332742 1 manager.go:288] Could not configure a source for OOM detection, disabling OOM events: open /dev/kmsg: no such file or directory
2021-08-08T00:18:20.692Z info builder/receivers_builder.go:75 Receiver started. {"kind": "receiver", "name": "awscontainerinsightreceiver"}
2021-08-08T00:18:20.692Z info healthcheck/handler.go:129 Health Check state change {"kind": "extension", "name": "health_check", "status": "ready"}
2021-08-08T00:18:20.692Z info service/collector.go:182 Everything is ready. Begin running and processing data.

重要: “not authorized” エラーが発生した場合、EKS ワーカーノードに必要な “CloudWatchAgentServerPolicy” IAM ポリシーがアタッチされていることを確認する必要があります。

インストール後

セットアップを確認し、正常にデプロイされると、AWS OTel Collector は、/aws/containerinsights/{your-cluster}/performance という名前のロググループを作成します。このロググループにパフォーマンスログイベントの送信を開始します。クラスタノード上の各 Collector Pod は、ワーカーノードの名前を持つログストリームにログを公開します。次のスクリーンショットでは、3 つのログストリームがロググループ /aws/containerinsights/eks-otel-v1/performance の下にあり、それぞれが 1 つのワーカーノードに対応しています。

Log streams present under log group

以下は、これらのログストリーム内に取り込まれたパフォーマンスログイベントの例です。

{
    "AutoScalingGroupName": "eks-e2bd9188-e94a-3339-af3b-bf09b661ba5f",
    "ClusterName": "eks-otel-v1",
    "InstanceId": "i-01234abcdef",
    "InstanceType": "m5.large",
    "NodeName": "ip-192-168-17-16.us-east-2.compute.internal",
    "Sources": [
        "cadvisor",
        "calculated"
    ],
    "Timestamp": "1628455529505",
    "Type": "NodeNet",
    "Version": "0",
    "interface": "eth0",
    "kubernetes": {
        "host": "ip-192-168-17-16.us-east-2.compute.internal"
    },
    "node_interface_network_rx_bytes": 5392.51738408303,
    "node_interface_network_rx_dropped": 0,
    "node_interface_network_rx_errors": 0,
    "node_interface_network_rx_packets": 16.09165306162301,
    "node_interface_network_total_bytes": 8418.50657774278,
    "node_interface_network_tx_bytes": 3025.9891936597514,
    "node_interface_network_tx_dropped": 0,
    "node_interface_network_tx_errors": 0,
    "node_interface_network_tx_packets": 16.668710292316455
}

Amazon EKS の Container Insights のモニタリングダッシュボードとメトリクス

AWS Distro for OpenTelemetry (ADOT) Collector を使用する CloudWatch Container Insights では、追加の設定をすることなく、EKS クラスター上で実行されているコンテナ化されたワークロードに関する詳細なメトリクスを収集することができます。以下は、デフォルトで収集されるメトリクスの一部です。

  • ワーカーノードレベルのメトリクス
    • node_cpu_utilization
    • node_memory_utilization
    • node_network_total_bytes
    • node_cpu_reserved_capacity
    • node_memory_reserved_capacity
    • node_number_of_running_pods
    • node_number_of_running_containers
  • Pod レベルのメトリクス
    • pod_cpu_utilization
    • pod_memory_utilization
    • pod_network_rx_bytes
    • pod_network_tx_bytes
    • pod_cpu_utilization_over_pod_limit
    • pod_memory_utilization_over_pod_limit
    • pod_cpu_reserved_capacity
    • pod_memory_reserved_capacity
    • pod_number_of_container_restarts
  • その他の関連するメトリクス
    • cluster_node_count
    • cluster_failed_node_count
    • service_number_of_running_pods
    • node_filesystem_utilization

Container Insights が収集するメトリクスは、EKS ClustersEKS NamespacesEKS NodesEKS ServicesEKS Pods などのさまざまなリソースタイプとして、CloudWatch の自動ダッシュボードでも利用できます。以下は、eks-otel-v1 という名前のクラスターの Pod レベルメトリクスのスクリーンショットです。

Pod-level metrics for cluster

初期設定時には、収集したメトリクスを処理して、Container Insights ダッシュボード内のダッシュボードで可視化するのに数分かかることがあります。

まとめ

このブログ記事では、AWS Distro for OpenTelemetry (ADOT) Collector と Amazon EKS の Container Insights との統合について説明しました。アーキテクチャの詳細、重要なコンポーネント、インストールとセットアップの検証の詳細をカバーしました。Amazon CloudWatch と AWS X-Ray での AWS のオブザーバビリティ機能の詳細については、One Observability Demo ワークショップをご覧ください (訳注: 日本語も選択可能です) 。

翻訳はプロフェッショナルサービスの杉田が担当しました。原文はこちらです。