[AWS] ECS: 작업정의 정보 조회하기
ECS-Fargate에는 작은 한계점이 있는데, Docker 기반 스택들(cgroup)의 일반적인 명세들을 완전히 지키는게 아니란 것이다.
그래서 cgroup 기반으로 현재 컨테이너의 메모리 제한 등을 가져오는게 어렵고, 메모리 제한 기반의 GC 설정이나 Alert를 구현하는데 약간의 문제가 있다. K8S 기반으로 만들어진 몇몇 모니터링 라이브러리는 사용할 수 없을 것이다.
하지만 방법이 없는건 아닌데,
ECS 나름대로 컨테이너 자체에 대한 메타 정보를 조회하는걸 로컬 API의 형태로 제공한다.
아래는 그걸 수행하는 간단한 코드다. 언어는 Go다.
awsMetadataURI := os.Getenv("ECS_CONTAINER_METADATA_URI_V4")
fmt.Println("========================================")
fmt.Println("AWS ECS Metadata URI: ", awsMetadataURI)
resp, err := http.Get(awsMetadataURI + "/task")
if err != nil {
log.New().Fatalf("err get task metadata: %v", err)
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
log.New().Fatalf("err read task metadata: %v", err)
}
fmt.Println("========================================")
fmt.Println("AWS ECS Task Metadata: ", string(bodyBytes))
ECS_CONTAINER_METADATA_URI_V4라는 환경 변수에 로컬 API의 엔드포인트가 있는데, 저기서 /task라는 API를 쏘면 정보를 JSON으로 말아서 준다.
ECS에 올려서 돌려보면
URL은 이런 식으로 나오고
메타데이터는 엄청 크다.
아래는 전체 포맷이다.
{
"Cluster": "arn:aws:ecs:ap-northeast-2:?:cluster/클러스터명",
"TaskARN": "arn:aws:ecs:ap-northeast-2:?:task/태스크명/c4e2ca26f6e84102945e205a581ebaee",
"Family": "서비스명",
"Revision": "929",
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": { "CPU": 0.25, "Memory": 512 },
"PullStartedAt": "2024-10-29T10:07:32.652212009Z",
"PullStoppedAt": "2024-10-29T10:07:42.014789788Z",
"AvailabilityZone": "ap-northeast-2a",
"LaunchType": "FARGATE",
"Containers": [
{
"DockerId": "c4e2ca26f6e84102945e205a581ebaee-1009763361",
"Name": "metricbeat",
"DockerName": "metricbeat",
"Image": "?.dkr.ecr.ap-northeast-2.amazonaws.com/...",
"ImageID": "sha256:eb72f4fe8a8121dfb20e8a25c380244b909fab44202caf4dca4866f768538d18",
"Labels": {
"com.amazonaws.ecs.cluster": "arn:aws:ecs:ap-northeast-2:?:cluster/...",
"com.amazonaws.ecs.container-name": "metricbeat",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:ap-northeast-2:?:task/?.../c4e2ca26f6e84102945e205a581ebaee",
"com.amazonaws.ecs.task-definition-family": "?...-api-dev",
"com.amazonaws.ecs.task-definition-version": "929"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": { "CPU": 2 },
"CreatedAt": "2024-10-29T10:07:42.734988634Z",
"StartedAt": "2024-10-29T10:07:42.734988634Z",
"Type": "NORMAL",
"ContainerARN": "arn:aws:ecs:ap-northeast-2:?:container/?.../c4e2ca26f6e84102945e205a581ebaee/ddc91943-89de-42f8-809c-4b5ef1bced0f",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": ["172.31.1.129"],
"AttachmentIndex": 0,
"MACAddress": "02:72:65:f3:98:65",
"IPv4SubnetCIDRBlock": "172.31.0.0/20",
"DomainNameServers": ["172.31.0.2"],
"DomainNameSearchList": ["ap-northeast-2.compute.internal"],
"PrivateDNSName": "ip-172-31-1-129.ap-northeast-2.compute.internal",
"SubnetGatewayIpv4Address": "172.31.0.1/20"
}
],
"Snapshotter": "overlayfs"
},
{
"DockerId": "c4e2ca26f6e84102945e205a581ebaee-3941558923",
"Name": "?...-api-dev-container",
"DockerName": "?...-api-dev-container",
"Image": "?.dkr.ecr.ap-northeast-2.amazonaws.com/?...:1aeb1a27336b155f10e845f4ff795a962a26c595",
"ImageID": "sha256:9b6d61130cb38f0f177aa5ecd35c84f3a6d6a954896267d02b891100b0161b47",
"Labels": {
"com.amazonaws.ecs.cluster": "arn:aws:ecs:ap-northeast-2:?:cluster/?...",
"com.amazonaws.ecs.container-name": "?...-api-dev-container",
"com.amazonaws.ecs.task-arn": "arn:aws:ecs:ap-northeast-2:?:task/?.../c4e2ca26f6e84102945e205a581ebaee",
"com.amazonaws.ecs.task-definition-family": "?...-api-dev",
"com.amazonaws.ecs.task-definition-version": "929"
},
"DesiredStatus": "RUNNING",
"KnownStatus": "RUNNING",
"Limits": { "CPU": 2 },
"CreatedAt": "2024-10-29T10:07:43.325165757Z",
"StartedAt": "2024-10-29T10:07:43.325165757Z",
"Type": "NORMAL",
"LogDriver": "awslogs",
"LogOptions": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/?...-api-dev",
"awslogs-region": "ap-northeast-2",
"awslogs-stream": "ecs/?...-api-dev-container/c4e2ca26f6e84102945e205a581ebaee"
},
"ContainerARN": "arn:aws:ecs:ap-northeast-2:?:container/?.../c4e2ca26f6e84102945e205a581ebaee/a8b1842a-25f2-4c14-9b82-5f70993d6d11",
"Networks": [
{
"NetworkMode": "awsvpc",
"IPv4Addresses": ["172.31.1.129"],
"AttachmentIndex": 0,
"MACAddress": "02:72:65:f3:98:65",
"IPv4SubnetCIDRBlock": "172.31.0.0/20",
"DomainNameServers": ["172.31.0.2"],
"DomainNameSearchList": ["ap-northeast-2.compute.internal"],
"PrivateDNSName": "ip-172-31-1-129.ap-northeast-2.compute.internal",
"SubnetGatewayIpv4Address": "172.31.0.1/20"
}
],
"Snapshotter": "overlayfs"
}
],
"ClockDrift": {
"ClockErrorBound": 0.4183675,
"ReferenceTimestamp": "2024-10-29T10:07:28Z",
"ClockSynchronizationStatus": "SYNCHRONIZED"
},
"EphemeralStorageMetrics": { "Utilized": 590, "Reserved": 20496 }
}
개인적인 정보들은 마스킹했다.
여기서 가장 유용한 것은 아마 Limits일 것이다.
이거 말고도 API는 몇가지 더 있다. 더 많은 정보를 원한다면 문서를 참조한다.
https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/task-metadata-endpoint-v4.html