Amazon Web Services ブログ

Amazon EKS の Container Insights は AWS Distro for OpenTelemetry コレクターをサポートします

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

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

ADOT コレクターでの Container Insights サポートのデザイン

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

AWS Container Insights Receiver architecture diagram

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

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

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

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

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

レシーバーは、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 レシーバーは、同じノード上で実行されているすべての Pod オブジェクトをリストしてキャッシュするために、Kubelet とも対話する必要があります。また、Pod に関連するサービス名を取得するために、Kubernetes API サーバーにクエリを実行する必要もあります。この情報が必要なのは cadvisor だけです。

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

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

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

始めてみよう

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

次に、以下のコマンドを入力することで、AWS OTel コレクターを 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 コレクターをデプロイすると、”aws-otel-eks” という新しい Namespace が作成され、関連するすべての Kubernetes オブジェクトは、default Namespace ではなくこの Namespace 内に作成されます。

インストールの確認

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

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 コレクターは、/aws/containerinsights/{your-cluster}/performance という名前のロググループを作成します。このロググループにパフォーマンスログイベントの送信を開始します。クラスタノード上の各コレクター 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) コレクターを使用する 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) コレクターと Amazon EKS の Container Insights との統合について説明しました。アーキテクチャの詳細、重要なコンポーネント、インストールとセットアップの検証の詳細をカバーしました。Amazon CloudWatch と AWS X-Ray での AWS のオブザーバビリティ機能の詳細については、One Observability Demo ワークショップをご覧ください (訳注: 日本語も選択可能です) 。

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