Next.js + ECS + Jenkins를 통한 CI/CD 프로젝트 셋업을 하던중 task definition이
다음 이미지와 같은 STOPPED ( CannotStartContainerError: Error response from dae ) 이유로 컨테이너가 제대로 RUNNING 되지 않는 이슈가 있었습니다.
처음에는 왜 Stop이 되는지에 대해 자세히 알지못하였고 여러번의 삽질을 해봤습니다.
결론부터 말씀드리면 CloudWatch에 로그그룹이 제대로 생성되지 않아서 발생하는 이슈였습니다.
전에 생성했던 프로젝트들을 보면 분명 자동으로 로그그룹이 생성되었던 것으로 확인했습니다.
aws 공식문서와 task definition에 정의한 옵션들을 찾아봤습니다.
먼저 내가 taskdefinition을 잘못 작성하였을 수도 있기 때문에 STOP이 되지않을까란 생각으로 ecs에서의 작업을 직접 설정하면서 보니 아래 사진처럼 처음 task definition을 만들때 컨네치너 추가 옵션쪽에 [Auto-configure CloudWatch Logs] 자동으로 CloudWatch를 만들것인지 체크하는 체크박스가 있었습니다.
또한 옵션으로
awslogs-group : /esc/test-task-definition
CloudWatch LogGroup에 위의 이름으로 생성된다. (required )
awslogs-region : ap-northeast-2
CloudWatch가 서울리전에 생성된다는 내용 ( required )
awslogs-stream-prefix : ecs
CloudWatch LogGroup안에 있는 로그 스트림을 의미한다.
prefix-name/container-name/ecs-task-id
자동으로 기입되있는것을 볼 수있습니다.
직접 설정하는 부분에서는 Auto-comfigure CloudWatch Logs도 제대로 체크 되어있었습니다.
따라서 해당 작업이 생성되어 올라갈때 /ecs/test-task-definition이라는 로그그룹이 생성되어 올라갔습니다.
cloudwatch 를 확인해보면 서울리전의 /ecs/test-task-definition이라는 로그그룹이 생성되고 그안에 ecs/test-task-definition/xxxxx 라는 이름의 로그 스트림이 생성되었습니다.
또한 정상 동작하였습니다.
그러면 내가 taskDefinition을 잘못작성했구나 라는 생각을 하였습니다. Jenkins에서 빌드해보니 CloudWatch가 자동으로 생성되지 않았습니다.
그 결과 CloudWatch에 로그그룹이 없어서 제대로 생성하지 못하였습니다.
다음 내용은 실제로 프로젝트를 올리기위한 taskDefinition 정보입니다
{
"memory": "%memoryUnit%",
"cpu": "%cpuUnit%",
"networkMode": "awsvpc",
"executionRoleArn": "%executionRoleArn%",
"requiresCompatibilities": [
"FARGATE"
],
"containerDefinitions": [{
"portMappings": [{
"containerPort": 80,
"protocol": "tcp"
}],
"essential": true,
"name": "%taskFamily%",
"cpu": %cpuUnit%,
"memory": %memoryUnit%,
"image": "%imageUrl%",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "%awsLogGroup%",
"awslogs-region": "%awsLogRegion%",
"awslogs-stream-prefix": "%awsLogPrefix%"
}
},
"environment": [
{
"name": "NODE_ENV",
"value": "%nodeEnv%"
}
]
}],
"family": "%taskFamily%"
}
다른 설정들을 다 재껴놓고 logConfiguration의 options만 보겠습니다. options를 보면 자동으로 로그그룹을 생성해줘! 라는 옵션이 없는것을 확인할 수 있었습니다. 그래서 찾아보니 task definition을 확인해 보니 로그 그룹을 자동으로 생성해주기 위해서는 awslogs-create-group을 true로 설정해줘야 했습니다.
공식문서의 내용을 사진으로 확인해보겠습니다.
awslogs-create-group
옵션은 무조건 필요한 옵션은 아닙니다.
awslogs-create-group
은 로그 그룹을 자동으로 만들것인지에 대한 여부를 받는 옵션입니다. 옵션이 지정되지 않았을경우 기본값은 false
!!!!
awslogs-create-group
옵션을 사용할때 해당 사용자는 logs:CreateLogGroup
IAM 정책을 가지고 있어야 합니다.
{
"memory": "%memoryUnit%",
"cpu": "%cpuUnit%",
"networkMode": "awsvpc",
"executionRoleArn": "%executionRoleArn%",
"requiresCompatibilities": [
"FARGATE"
],
"containerDefinitions": [{
"portMappings": [{
"containerPort": 80,
"protocol": "tcp"
}],
"essential": true,
"name": "%taskFamily%",
"cpu": %cpuUnit%,
"memory": %memoryUnit%,
"image": "%imageUrl%",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group" : "true",
"awslogs-group": "%awsLogGroup%",
"awslogs-region": "%awsLogRegion%",
"awslogs-stream-prefix": "%awsLogPrefix%"
}
},
"environment": [
{
"name": "NODE_ENV",
"value": "%nodeEnv%"
}
]
}],
"family": "%taskFamily%"
}
결과적으로 해결은 하였지만 앞으로 document를 좀더 자세히 읽어보고 일을 해야할것 같습니다.
많은 분들에게 도움이 되길 바랍니다 ㅠㅠ
ECS배포가 안돼서 헤맸는데 덕분에 원인을 찾았네요. logConfiguration 관련 옵션을 싹 다 지우니 성공했습니다. 감사합니다 ㅎㅎ