📝

Fargate で top コマンドを実行してログ出力してみた

に公開

Fargate タスク内のコンテナで CPU 使用率やメモリ使用率が上昇した際、どのプロセスが原因かを特定する手段として top コマンドの実行結果をログ出力してみました。

前提

  • コンテナイメージなどの作成環境: Cloud9
  • ECR リポジトリは作成済み

コンテナイメージの作成

以下のスクリプトファイルでは 1 分ごとに top コマンドの上位 20 行を表示します。

log-top.sh
#!/bin/bash

while true; do
  echo "----- $(date) -----"
  top -b -n 1 | head -n 20
  echo
  sleep 60
done
Dockerfile
FROM amazonlinux:2

RUN yum install -y procps aws-cli

# スクリプトをコピー
COPY log-top.sh /usr/local/bin/log-top.sh
RUN chmod +x /usr/local/bin/log-top.sh

CMD ["/usr/local/bin/log-top.sh"]
# ECR リポジトリにプッシュ
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com

$ docker build -t test .

$ docker tag test:latest 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest

$ docker push 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest

Fargate タスクの作成

タスク定義で上記イメージを指定します。
その他のタスク定義の設定はデフォルトです。

タスク定義
{
    "taskDefinitionArn": "xxx",
    "containerDefinitions": [
        {
            "name": "test",
            "image": "xxx",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "test-80-tcp",
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/test",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
    ],
    "family": "test",
    "taskRoleArn": "xxx",
    "executionRoleArn": "xxx",
    "networkMode": "awsvpc",
    "revision": 74,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.28"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "ecs.capability.task-eni"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "1024",
    "memory": "3072",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "2025-06-09T10:06:09.192Z",
    "registeredBy": "xxx",
    "enableFaultInjection": false,
    "tags": []
}

上記タスク定義を使用してタスクを起動します。

$ aws ecs run-task \
--cluster test \
--launch-type FARGATE \
--task-definition my-task-def:1 \
--network-configuration "awsvpcConfiguration={subnets=[my-subnet-id],securityGroups=[my-sg-id],assignPublicIp=ENABLED}" \
--enable-execute-command \
--count 1

タスクの起動後、CloudWatch Logs のロググループに以下のようなログが出力されていれば成功です。

----- Mon Jun  9 10:11:14 UTC 2025 -----
top - 10:11:15 up 3 min,  0 users,  load average: 0.61, 0.15, 0.05
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s): 19.4 us,  9.7 sy,  0.0 ni, 32.3 id, 38.7 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3943304 total,  1790976 free,   284436 used,  1867892 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  3411296 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
   10 root      20   0 1697028  16512   9996 S  18.8  0.4   0:00.03 amazon-ssm+
    1 root      20   0   11568   2440   2264 S   0.0  0.1   0:00.02 log-top.sh
    8 root      20   0   54108   3768   3340 R   0.0  0.1   0:00.00 top
    9 root      20   0    4256    740    672 S   0.0  0.0   0:00.00 head

ECS Exec でコンテナにログインして負荷をかけてみます。

$ aws ecs execute-command \
--cluster test \
--task <task-id> \
--container test \
--interactive \
--command "/bin/sh"

sh-4.2 yes > /dev/null &
[1] 55

上記コマンド実行後のログでは CPU 使用率が上昇していることが確認できました。

----- Mon Jun  9 10:14:15 UTC 2025 -----
top - 10:14:15 up 6 min,  0 users,  load average: 0.24, 0.14, 0.06
Tasks:   8 total,   2 running,   6 sleeping,   0 stopped,   0 zombie
%Cpu(s): 50.0 us,  0.0 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3943304 total,  1807240 free,   257996 used,  1878068 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  3437732 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
   55 root      20   0    6124    776    712 R 100.0  0.0   0:10.16 yes
    1 root      20   0   11568   2588   2388 S   0.0  0.1   0:00.02 log-top.sh
   10 root      20   0 1773128  16972  10188 S   0.0  0.4   0:00.04 amazon-ssm+
   25 root      20   0 1936344  29036  16652 S   0.0  0.7   0:00.08 ssm-agent-+
   43 root      20   0 1854812  26872  13752 S   0.0  0.7   0:00.12 ssm-sessio+
   54 root      20   0   13576   3232   2852 S   0.0  0.1   0:00.00 sh
   57 root      20   0   54108   3688   3256 R   0.0  0.1   0:00.00 top
   58 root      20   0    4256    776    712 S   0.0  0.0   0:00.00 head

まとめ

今回は Fargate で top コマンドを実行してログ出力してみました。
どなたかの参考になれば幸いです。

Discussion