メインコンテンツまでスキップ

クラスターメトリクス

EKSクラスター用のCloudWatch Container InsightsメトリクスをADOTコレクターで有効にする方法を調査します。最初に必要なことは、クラスター内にコレクターを作成して、ノード、ポッド、コンテナなどのクラスターのさまざまな側面に関するメトリクスを収集することです。

完全なコレクターマニフェストは以下で確認でき、その後で詳しく分解して説明します。

コレクターマニフェスト全体を展開
~/environment/eks-workshop/modules/observability/container-insights/adot/opentelemetrycollector.yaml
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: adot-container-ci
namespace: other
spec:
image: public.ecr.aws/aws-observability/aws-otel-collector:v0.40.0
mode: daemonset
serviceAccount: adot-collector-ci
config:
receivers:
awscontainerinsightreceiver:
add_full_pod_name_metric_label: true

processors:
batch/metrics:
timeout: 60s

exporters:
awsemf/performance:
namespace: ContainerInsights
log_group_name: "/aws/containerinsights/${EKS_CLUSTER_NAME}/performance"
log_stream_name: "{NodeName}"
resource_to_telemetry_conversion:
enabled: true
dimension_rollup_option: NoDimensionRollup
parse_json_encoded_attr_values: [Sources, kubernetes]
metric_declarations:
# node metrics
- dimensions: [[NodeName, InstanceId, ClusterName]]
metric_name_selectors:
- 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
- dimensions: [[ClusterName]]
metric_name_selectors:
- 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
- node_cpu_usage_total
- node_cpu_limit
- node_memory_working_set
- node_memory_limit

# pod metrics
- dimensions:
[
[FullPodName, PodName, Namespace, ClusterName],
[PodName, Namespace, ClusterName],
[Service, Namespace, ClusterName],
[Namespace, ClusterName],
[ClusterName],
]
metric_name_selectors:
- 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
- dimensions:
[
[FullPodName, PodName, Namespace, ClusterName],
[PodName, Namespace, ClusterName],
[ClusterName],
]
metric_name_selectors:
- pod_cpu_reserved_capacity
- pod_memory_reserved_capacity
- dimensions:
[
[FullPodName, PodName, Namespace, ClusterName],
[PodName, Namespace, ClusterName],
]
metric_name_selectors:
- pod_number_of_container_restarts

# container metrics
- dimensions:
[
[FullPodName, PodName, Namespace, ClusterName, ContainerName],
[PodName, Namespace, ClusterName, ContainerName],
[Namespace, ClusterName, ContainerName],
[ClusterName, ContainerName],
]
metric_name_selectors:
- container_cpu_utilization
- container_memory_utilization
- number_of_container_restarts

# cluster metrics
- dimensions: [[ClusterName]]
metric_name_selectors:
- cluster_node_count
- cluster_failed_node_count

# service metrics
- dimensions: [[Service, Namespace, ClusterName], [ClusterName]]
metric_name_selectors:
- service_number_of_running_pods

# node fs metrics
- dimensions: [[NodeName, InstanceId, ClusterName], [ClusterName]]
metric_name_selectors:
- node_filesystem_utilization

# namespace metrics
- dimensions: [[Namespace, ClusterName], [ClusterName]]
metric_name_selectors:
- namespace_number_of_running_pods

extensions:
health_check: {}

service:
pipelines:
metrics:
receivers: [awscontainerinsightreceiver]
processors: [batch/metrics]
exporters: [awsemf/performance]
extensions: [health_check]

securityContext:
runAsUser: 0
runAsGroup: 0

env:
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: HOST_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "K8S_POD_NAME"
valueFrom:
fieldRef:
fieldPath: "metadata.name"
volumeMounts:
- name: rootfs
mountPath: /rootfs
readOnly: true
- name: dockersock
mountPath: /var/run/docker.sock
readOnly: true
- name: containerdsock
mountPath: /run/containerd/containerd.sock
- name: varlibdocker
mountPath: /var/lib/docker
readOnly: true
- name: sys
mountPath: /sys
readOnly: true
- name: devdisk
mountPath: /dev/disk
readOnly: true
volumes:
- name: rootfs
hostPath:
path: /
- name: dockersock
hostPath:
path: /var/run/docker.sock
- name: varlibdocker
hostPath:
path: /var/lib/docker
- name: containerdsock
hostPath:
path: /run/containerd/containerd.sock
- name: sys
hostPath:
path: /sys
- name: devdisk
hostPath:
path: /dev/disk/

これをいくつかの部分に分けて理解しやすくしましょう。

  image: public.ecr.aws/aws-observability/aws-otel-collector:v0.40.0
mode: daemonset

OpenTelemetryコレクターは、収集するテレメトリによって異なるモードで実行できます。今回はDaemonSetとして実行し、EKSクラスター内の各ノードにポッドが実行されるようにします。これにより、ノードとコンテナランタイムからテレメトリを収集できます。

次に、コレクター設定自体を分解していきます。

  config:
receivers:
awscontainerinsightreceiver:
add_full_pod_name_metric_label: true

まず、AWS Container Insights Receiverを設定して、ノードからメトリクスを収集します。

    processors:
batch/metrics:
timeout: 60s

次に、バッチプロセッサを使用して、最大60秒間バッファリングされたメトリクスをフラッシュすることでCloudWatchへのAPI呼び出し回数を減らします。

    exporters:
awsemf/performance:
namespace: ContainerInsights
log_group_name: "/aws/containerinsights/${EKS_CLUSTER_NAME}/performance"

そしてAWS CloudWatch EMF Exporter for OpenTelemetry Collectorを使用してOpenTelemetryメトリクスをAWS CloudWatch Embedded Metric Format (EMF)に変換し、PutLogEvents APIを使用して直接CloudWatch Logsに送信します。ログエントリは表示されているCloudWatch Logsロググループに送信され、メトリクスはContainerInsights名前空間に表示されます。このセクションの残りの部分は長すぎるため全体を表示できませんが、上記の完全なマニフェストを参照してください。

      pipelines:
metrics:
receivers: [awscontainerinsightreceiver]
processors: [batch/metrics]
exporters: [awsemf/performance]

最後に、OpenTelemetryパイプラインを使用して、レシーバー、プロセッサー、エクスポーターを組み合わせる必要があります。

マネージドIAMポリシーCloudWatchAgentServerPolicyを使用して、IAMロールをサービスアカウントに付与し、コレクターがメトリクスをCloudWatchに送信するために必要なIAM権限を提供します:

~$aws iam list-attached-role-policies \
--role-name eks-workshop-adot-collector-ci | jq .
{
  "AttachedPolicies": [
    {
      "PolicyName": "CloudWatchAgentServerPolicy",
      "PolicyArn": "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
    }
  ]
}

このIAMロールはコレクターのServiceAccountに追加されます:

~/environment/eks-workshop/modules/observability/container-insights/adot/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: adot-collector-ci
annotations:
eks.amazonaws.com/role-arn: ${ADOT_IAM_ROLE_CI}

上記で検討したリソースを作成します:

~$kubectl kustomize ~/environment/eks-workshop/modules/observability/container-insights/adot \
| envsubst | kubectl apply -f- && sleep 5
~$kubectl rollout status -n other daemonset/adot-container-ci-collector --timeout=120s

DaemonSetによって作成されたPodを検査して、コレクターが実行されていることを確認できます:

~$kubectl get pod -n other -l app.kubernetes.io/name=adot-container-ci-collector
NAME                               READY   STATUS    RESTARTS   AGE
adot-container-ci-collector-5lp5g  1/1     Running   0          15s
adot-container-ci-collector-ctvgs  1/1     Running   0          15s
adot-container-ci-collector-w4vqs  1/1     Running   0          15s

これはコレクターが実行されクラスターからメトリクスを収集していることを示しています。メトリクスを表示するには、まずCloudWatchコンソールを開き、Container Insightsに移動します:

ヒント

以下の点に注意してください:

  1. CloudWatchにデータが表示され始めるまで数分かかることがあります
  2. 拡張観測性を備えたCloudWatchエージェントによって提供される一部のメトリクスが欠落している可能性があります
AWS console iconCloudWatchコンソールを開く

ContainerInsightsConsole

コンソールを探索して、クラスター、名前空間、ポッドなど、メトリクスが表示されるさまざまな方法を確認することができます。