Docker×Datadog×PHP実装まとめ(APM編)


概要

Datadogを使って、Docker(ECS)で実装しているPHPウェブアプリのメトリクスを収集し、Datadogコンソール(APMService)で監視できるようにする。

アウトライン

・PHPコンテナに、DatadogAPMの計測設定
・ローカル開発環境(docker-compose)で、datadog/agentコンテナを実装
・クラウド開発環境(ECS)で、datadog/agentコンテナを実装

作業ログ

PHPコンテナに、DatadogAPMの計測設定

・PHPにDatadog拡張機能(datadog-php-tracer)をインストール
→PHPコンテナのDockerfileにインストールする。

ENV DDTRACE_VERSION=0.30.1
RUN curl -Lo datadog-php-tracer.apk https://github.com/DataDog/dd-trace-php/releases/download/${DDTRACE_VERSION}/datadog-php-tracer_${DDTRACE_VERSION}_noarch.apk \
&& apk add datadog-php-tracer.apk --allow-untrusted \
&& rm datadog-php-tracer.apk

※コンテナを実行して、↓phpinfo()でインストールされていることを確認

※datadog-php-tracerをインストールするだけで、勝手に計測してdatadog/agentのEPに計測データを送信してくれる。

ローカル開発環境(docker-compose)で、datadog/agentコンテナを実装

ローカルでコンテナを実行し、datadogコンソールにデータを送信できることを確認する。
↓構成としてはこんな感じ。

datadog/agentコンテナ

datadogの公式イメージ(datadog/agent)に、環境変数を設定して実行

  • datadogのAPIキー

※キーは、Datadogコンソールの Integrations - APIs - API keys から確認

DD_API_KEY=***
  • Datadog Agentのトレースメトリクスを有効にする。
DD_APM_ENABLED=true
  • データ送信先サイトを設定
DD_SITE=datadoghq.com
  • 非ローカルトラフィックのトレース許可
DD_APM_NON_LOCAL_TRAFFIC=true
PHPコンテナの設定

環境変数で計測データの設定を行う。

  • datadog-agentコンテナのhost名を設定
DD_AGENT_HOST=datadog-agent

※datadog/agentのサービス名をdatadog-agentにしたのでそのまま設定(デフォルトはlocalhost)

  • APM - Services名 (APMのサービス名)
DD_SERVICE_NAME=php-apm

docker-compose.yml

version: '3'
services:
  php-apache:
    container_name: php_apache_container
    build: ./php_apache_container
    volumes:
      - ./php_apache_container/src:/var/www/html
    environment:
      DD_AGENT_HOST: "datadog-agent"
      DD_SERVICE_NAME: "php-apache"
      DD_TRACE_GLOBAL_TAGS: "env:local,service:php-apache"
      DD_TRACE_ANALYTICS_ENABLED=true
    networks:
      - net


  datadog-agent:
    container_name: datadog-agent
    image: datadog/agent:latest
    environment:
      DD_API_KEY: "******"
      DD_APM_ENABLED: "true"
      DD_SITE: "datadoghq.com"
      DD_APM_NON_LOCAL_TRAFFIC: "true"
    networks:
      net:

networks:
  net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.16.238.0/24

※だいたい↑の感じ。。業務用コード、固有名詞をざっくり削除、編集したもの載せてます。動作は見てない。

クラウド開発環境(ECS)で、datadog/agentコンテナを実装

↓だいたい下記の感じで実装

・ECSはEC2モード
・PHPコンテナは、Replica、AWSVPCモード、Datadogコンテナは、Daemon、Bridgeモードで起動

ENIの制限

※使用するインスタンスタイプはENI数:3
AWSVPCモードだと1タスクにつき1つのENIを使用する為、ENI枯渇を防ぐ為、datadogコンテナはbridgeモードで実装

PHPコンテナ→Datadogコンテナの通信経路

タスク間を跨いで通信する場合、直接通信できない為、Route53でPrivateHostedZone→ALBを通して、datadog/agentコンテナに計測メトリクスを送信する。
※サービス検出とSRVレコードを使った方法もあるらしいが、datadog-php-tracer(の通信に使ってるCURL)がSRVレコードに対応してないようなので使えない?ぽい。

タスク定義

・ローカル環境でも設定した環境変数をenvironmentに設定
・APIキーはパラメータストアに設定して、ARNを指定
・portはdatadogAPM用ポート8126を設定
※terraformで管理してる為、設定値を${var}の形で外部から設定できるようにしてる。(JSONのLINTに怒られるけど気にしない)

[
  {
    "name": "datadog-agent",
    "image": "datadog/agent:latest",
    "cpu": 10,
    "memory": 256,
    "portMappings": [
      {
        "hostPort": ${dd_trace_agent_port},
        "protocol": "tcp",
        "containerPort": ${dd_trace_agent_port}
      }
    ],
    "essential": true,
    "mountPoints": [
      {
        "containerPath": "/var/run/docker.sock",
        "sourceVolume": "docker_sock",
        "readOnly": true
      },
      {
        "containerPath": "/host/sys/fs/cgroup",
        "readOnly": true,
        "sourceVolume": "cgroup"
      },
      {
        "containerPath": "/host/proc",
        "readOnly": true,
        "sourceVolume": "proc"
      }
    ],
    "environment": [
      {
        "name": "DD_APM_ENABLED",
        "value": "true"
      },
      {
        "name": "DD_SITE",
        "value": "datadoghq.com"
      },
      {
        "name": "DD_APM_NON_LOCAL_TRAFFIC",
        "value": "true"
      },
      {
        "name": "DD_TAGS",
        "value": "php-sample"
      }
    ],
    "secrets": [
      {
        "name": "DD_API_KEY",
        "valueFrom": "${dd_api_key}"
      }
    ]
  }
]