Fargateで起動したコンテナのタスクメタデータを覗いてみる

Fargateで起動したコンテナのメトリクスのモニタリング
僕はDatadogを使って行ってます

次のリンクはDatadogが出している導入記事です
www.datadoghq.com

FargateではなくEC2で起動していた時はホストであるEC2にAgentをいれたり出来ていたが、そのホストであるインスタンスを管理しなくてよくなったFargateでどうやってメトリクスを収集しているのか

それは今年の3月にFargateでタスクメタデータを取得できるようになったからです
AWS Fargate プラットフォームのバージョン 1.1 が、タスクメタデータ、コンテナのヘルスチェック、サービスディスカバリのサポートを追加

このタスクメタデータはタスク内でhttpリクエストでそのタスク内のコンテナのメタデータや統計情報を取得することが出来て、datadog-agentをタスクで一緒に立ち上げることで各コンテナのメトリクスを収集してるっぽい

準備

どんなものが実際にとれるのか見たいけど、EC2の時のようにホストにSSHをすることも出来ないのでタスク定義にsshdをたてるコンテナ定義をする

DockerImageはDockerのドキュメントでも紹介されているものを使用する
今回はHTTPリクエストしてJSONを見るのでcurljqだけ追加した
docs.docker.com

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN apt-get install -y curl jq
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

作成したDocker Imageはdocker hubにあげています

https://hub.docker.com/r/hatappi/sshd/

タスク定義

{
  "family": "sample",
  "networkMode": "awsvpc",
  "executionRoleArn": "arn:aws:iam::1111111111:role/peroEcsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "redis",
      "image": "redis:latest",
      "essential": true,
      "dockerLabels": {
        "com.datadoghq.ad.instances": "[{\"host\": \"%%host%%\", \"port\": 6379}]",
        "com.datadoghq.ad.check_names": "[\"redisdb\"]",
        "com.datadoghq.ad.init_configs": "[{}]"
      }
    }, {
      "name": "datadog-agent",
      "image": "datadog/agent:latest",
      "essential": true,
      "environment": [
        {
          "name": "DD_API_KEY",
          "value": "xxxxxxxxxxxxxxxx"
        },
        {
          "name": "ECS_FARGATE",
          "value": "true"
        }
      ]
   }, {
      "name": "sshd",
      "image": "hatappi/sshd",
      "essential": true
   }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "256",
  "memory": "512"
}

実行

タスクが実行した後は次の手順でsshでログインするためのpublic ipを取得する

$ CLUSTER_NAME=hoge
# 起動しているタスクのarnを取得
$ aws ecs list-tasks --cluster $CLUSTER_NAME --query "taskArns" --output text
# ENI Idを取得する
$ aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks [さっき取得したarn] --query "tasks[].attachments[].details[?name=='networkInterfaceId'].value" --output=text
# public ipを取得する
$ aws ec2 describe-network-interfaces --network-interface-ids eni-xxxxxx --query "NetworkInterfaces[].Association.PublicIp" --output text

一発で取得するならこれ

$ aws ecs list-tasks --cluster $CLUSTER_NAME --query "taskArns" --output text | read arn; aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks $arn --query "tasks[].attachments[].details[?name=='networkInterfaceId'].value" --output=text | read eni_id; aws ec2 describe-network-interfaces --network-interface-ids $eni_id --query "NetworkInterfaces[].Association.PublicIp" --output text

後はそのpublic ipを使って ssh root@xxx.xxx.xxx.xxx でログインする
ログインが出来たら後は curl 169.254.170.2/v2/metadata | jq でタスクのメタデータを取得したりcurl 169.254.170.2/v2/stats | jq でコンテナの統計情報を取得したりできる