DatadogのAutodiscoveryでFargate上で動作するnginxとjavaアプリケーションを監視する


AWS Fargate上にアプリケーションを移行後、以前まで悩まされたオートスケーリング周りでのトラブルが減り運用がかなり楽になしました。
ただこれまで利用していたMackerelではFargateのリソース監視がまだできないのでFargate対応を早くから謳っているDatadogのAutodiscoveryでリソース監視をしてみます。

Fargateの監視

各方面で書かれいるのでさらっと流します。
Monitor AWS Fargate applications with Datadog
に書かれているように設定すればOKです。
ecs-cli で運用しているのでdocker-compose形式の記述で以下のように追記してやります。

docker-compose.yml
version: '3'
services:
   :
   :
  datadog-agent:
    image: datadog/agent:latest
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true

環境変数のAPIキーとECS_FARGATにtrueを設定してあげればコンテナ毎のリソースの取得が可能になります。

nginxの監視

nginxのstub_statusの有効化

nginxのstub_statusの値を取得させるため、nginx.conf に以下のように追記します。

nginx.conf
location /server-status {
   stub_status on;
   access_log off;
   allow 127.0.0.1;
   allow 172.16.0.0/12;
   deny all;
}

これで /server-status にアクセスすればステータスが取得できるようになります。

docker labelの追加

stub_statusの値が取得できるようにdocker labelを追記します。
こちらが参考になりました。 DOCKER EXAMPLE: NGINX DOCKERFILE

docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx:mainline-alpine
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["nginx"]
      - com.datadoghq.ad.instances=[{"nginx_status_url":"http://localhost/server-status"}]
      - com.datadoghq.ad.init_configs=[{}]
  datadog-agent:
    image: datadog/agent:latest
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true

通常はホストのIPなどを組込変数の %%host%% などを使うのですが、
Fargateでは同一タスク内で起動している他コンテナへはlocalhostでアクセスできるのでlocalhostで問題ありません。
これでコネクション数やreading、writingなどが見られるようになります。

javaの監視

jmxの有効化

datadogでjavaの監視周りを調べるとjmx経由で取得しているようなので、JAVA_OPTSに以下を追記します。
ポートは今回は2003にしましたが、空いているポートであれば良いと思います。
こちらはDockerfile側でもEXPOSEする必要があります。

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=2003
-Dcom.sun.management.jmxremote.rmi.port=2003

docker labelの追加

こちらもdocker labelを追記してきます。
jmxを使う場合にはdatadog/agent:latest-jmxというdocker imageを使用します。

version: '3'
services:
  java-app:
    image: java-app:latest
    environment:
      - ENV=dev
      - JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2003 -Dcom.sun.management.jmxremote.rmi.port=2003
    command:
      /bin/sh -c
        "java -jar app-$$ENV.jar"
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["jmx"]
      - com.datadoghq.ad.instances=[{"jmx_url":"service:jmx:rmi:///jndi/rmi://localhost:2003/jmxrmi"}]
      - com.datadoghq.ad.init_configs=[{}]
  datadog-agent:
    image: datadog/agent:latest-jmx
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true

これで、threadやheapのグラフが見れるようになりました。

最後に

AWS Fargateの監視ずっと悩んでいたのですが、現状ではdatadogか自作するかしかないのかもしれません。
Mackerelも年内に何かしら出してくれると言っていたので、そちらが出れば試してみたいと思います。
docker-composeファイルの全文も載せておきます。

docker-compose.yml
version: '3'
services:
  java-app:
    image: java-app:latest
    ulimits:
      nproc: 65536
      nofile:
        soft: 65536
        hard: 65536
    environment:
      - ENV=dev
      - JAVA_OPTS=-Xms1024m -Xmx2048m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -Duser.country=JP -Duser.language=ja -Duser.timezone=Asia/Tokyo -Djava.awt.headless=true -XX:-OmitStackTraceInFastThrow -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=2003 -Dcom.sun.management.jmxremote.rmi.port=2003
    command:
      /bin/sh -c
        "java -jar app-$$ENV.jar"
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["jmx"]
      - com.datadoghq.ad.instances=[{"jmx_url":"service:jmx:rmi:///jndi/rmi://localhost:2003/jmxrmi"}]
      - com.datadoghq.ad.init_configs=[{}]
    logging:
      driver: awslogs
      options:
        awslogs-group: "java-app"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"
  nginx:
    image: nginx:mainline-alpine
    labels:
      - Env=dev
      - com.datadoghq.ad.check_names=["nginx"]
      - com.datadoghq.ad.instances=[{"nginx_status_url":"http://localhost/server-status"}]
      - com.datadoghq.ad.init_configs=[{}]
    logging:
      driver: awslogs
      options:
        awslogs-group: "nginx"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"
  datadog-agent:
    image: datadog/agent:latest-jmx
    environment:
      - DD_API_KEY=[api key]
      - ECS_FARGATE=true
    logging:
      driver: awslogs
      options:
        awslogs-group: "datadog-agent"
        awslogs-region: "ap-northeast-1"
        awslogs-stream-prefix: "dev"