🔭

AWS Distro for OpenTelemetryから収集したデータをDatadogからトレーシングをしてみる

2023/04/23に公開

これはなに?

マイクロサービスなどで発生するサービス間通信のトレーシングを検証したくなり、ADOT(AWS Distro for OpenTelemetry)を試した際のことをメモとしてまとめました。
OpenTelemetryやADOTについては深く触れないので、そのあたりについては参考に掲載した記事を御覧ください。

準備

EKSを起動

お好みの方法でEKSを動かすための環境を準備します。

cert-managerをインストールする

ADOT Operatorはadmission webhooksを使う関係上、cer-managerをインストールします。

The ADOT Operator uses admission webhooks to mutate and validate the Collector Custom Resource (CR) requests. In Kubernetes, the webhook requires a TLS certificate that the API server is configured to trust. There are multiple ways for you to generate the required TLS certificate. However, the default method is to install the latest version of the cert-manager manually. The cert-manager generates a self-signed certificate.

https://docs.aws.amazon.com/eks/latest/userguide/adot-reqts.html

インストールはこちらを参考にしつつ。
https://cert-manager.io/

ADOT OperatorをEKS add-on経由でインストールする

ADOT OperatorはEKSのadd-onでサポートされているため、AWSのマネジメントコンソールまたは以下のようなTerraformコード経由でインストールできます。

resource "aws_eks_addon" "this" {
  cluster_name      = var.cluster_name
  addon_name        = "adot"
  # addon_versionは以下のコマンドで取得できる
  # aws eks describe-addon-versions --kubernetes-version 1.25 --addon-name adot | jq -r '.addons[0].addonVersions[0].addonVersion'
  addon_version     = "v1.9.3-eksbuild.2"
  resolve_conflicts = "OVERWRITE"
}

EKS上に展開するOpenTelemetryCollector(次のステップで登場)ではAWSリソースへのアクセスが必要になるため、IRSAを用意しつつ以下のような権限を付与します。

resource "aws_iam_role_policy_attachment" "aws_otel_collector" {
  for_each = toset([
    "arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess",
    "arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess",
    "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy",
  ])
  policy_arn = each.key
  role       = "aws-otel-collector"
}

OpenTelemetryCollectorをデプロイする

こちらのサンプルを参考にしつつ、OpenTelemetryCollectorをインストールします。
OpenTelemetryCollectorの詳細についてはこちらを参照してください。

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    # 前のステップで作成したIRSA
    eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/aws-otel-collector
  name: aws-otel-collector
---
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector
spec:
  mode: deployment
  serviceAccount: aws-otel-collector
  config: |
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318
    processors:
      batch/traces:
        timeout: 5s
        send_batch_size: 50
    exporters:
      # このあたりが参考になる
      # https://aws-otel.github.io/docs/partners/datadog
      # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/datadogexporter/examples/collector.yaml
      datadog:
        api:
          site: datadoghq.com
          key: ${datadog_api_key}
    service:
      pipelines:
        traces:
          receivers:
            - otlp
          processors:
            - batch/traces
          exporters:
            - datadog

サンプルアプリケーションをデプロイする

こちらのサンプルGolangアプリケーション を参考にしつつ、アプリケーションをEKSにデプロイします。
サービス間通信に伴う経路が追えることを観察したいので、サンプルのGolangコードを変更して以下図のようなアクセス経路を準備します(2つのGolangアプリケーションをデプロイします)。

apiVersion: v1
kind: Service
metadata:
  labels:
    name: sample-app-1
  name: sample-app-1
spec:
  ports:
    - port: 8080
  selector:
    name: sample-app-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: sample-app-1
  name: sample-app-1
spec:
  replicas: 1
  selector:
    matchLabels:
      name: sample-app-1
  template:
    metadata:
      labels:
        name: sample-app-1
    spec:
      containers:
        - env:
            - name: AWS_REGION
              value: "ap-northeast-1"
            # https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: http://my-collector-collector:4317
            - name: OTEL_RESOURCE_ATTRIBUTES
              value: service.namespace=GettingStarted,service.name=GettingStartedService
          image: xxxxxxxxx
          name: sample-app-1
          ports:
            - containerPort: 8080

※sample-app-2用のリソースもsample-app-1と同様に準備する。

Datadogから確認する

OpenTelemetryCollectorが収集してDatadogへ転送したデータはトレースから確認できます。

trace_id から一連のアクセスを検索でき、Span List にアクセスの経路が表示されていることが分かります。

アクセスの途中で失敗した際にもそれっぽく辿れるようになりました

雑感

EKSがadd-onで対応していることもあり下地の準備自体はある程度簡単にできそうですが、運用で意味のあるトレーシングとなるような設計をするにはアプリケーションエンジニアとの連携しつつ模索する必要がありそうだなと感じました。

参考

https://aws.amazon.com/jp/otel/

https://aws-otel.github.io/

https://aws.amazon.com/jp/blogs/news/metrics-and-traces-collection-using-amazon-eks-add-ons-for-aws-distro-for-opentelemetry/

Discussion