QMAws::startTask | ECS failures - job_id: 89685, task_definition: cupix-pano-postprocessor-productio
RCA: QMAws::startTask | ECS failures - DRAINING container instances
Error Log#
QMAws::startTask | ECS failures - job_id: 89685, task_definition: cupix-pano-postprocessor-production, cluster: cupix-tesla-ece-eu, container_instance: arn:aws:ecs:eu-central-1:002596530511:container-instance/cupix-tesla-ece-eu/1e16c03a1eef416c85d83d42f62e9d39, failures: [{"arn":"arn:aws:ecs:eu-central-1:002596530511:container-instance/1e16c03a1eef416c85d83d42f62e9d39","reason":"DRAINING"}]
Impact#
- Service:
cupixworks-any-compute-agent - 발생 횟수: 2
- 최초 발생: 2026-04-14T15:17:29.959Z
- 최근 발생: 2026-04-14T15:17:30.149Z
Root Cause Summary#
listContainerInstances API가 status: 'ACTIVE' 필터로 container instance 목록을 조회한 시점과, 실제 startTask API를 호출하는 시점 사이에 해당 instance가 DRAINING 상태로 전환되는 race condition이 발생했습니다. describeContainerInstances에서도 status == 'ACTIVE'로 확인했지만, 이 검증 이후 ECS가 ASG scale-in 또는 infrastructure 이벤트로 인해 instance를 DRAINING으로 전환했습니다. 이 에러 자체는 SQS 재전송을 통한 retry로 ~5분 후 성공적으로 복구되었으나, 동일한 패턴이 지난 7일간 34건 발생하여 processing 지연을 유발하고 있습니다.
Technical Analysis#
Code Path#
- Entry point:
qmAws.ts:117—runTask메서드에서 ECS task 실행 시작 qmAws.ts:121—listContainerInstances호출로 ACTIVE 상태의 container instance 목록 조회
// applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:238-244
private listContainerInstances = (awsClusterName: string, instanceType: string): Promise<Array<string>> => new Promise((resolve, reject) => {
const params: AWS.ECS.ListContainerInstancesRequest = {
cluster: awsClusterName,
status: 'ACTIVE',
filter: `attribute:ecs.instance-type == ${instanceType} and runningTasksCount == 0`,
maxResults: 10
};
qmAws.ts:135—describeContainerInstances로 상세 정보 조회 후status == 'ACTIVE'재검증
// applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:149-158
if (containerInstance.status == 'ACTIVE'
&& containerInstance.runningTasksCount == 0
&& containerInstance.pendingTasksCount == 0
) {
try {
tasks = await this.startTask(awsClusterName, containerInstance.containerInstanceArn as string, job);
if (tasks.length > 0) break;
} catch (error) {
return; // catch 블록에서 즉시 return — 다른 instance 시도하지 않음
}
}
- Failure point:
qmAws.ts:191-203—ecs.startTaskAPI 호출 시 ECS가 DRAINING failure를 반환
// applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:191-213
this.ecs.startTask(params, (err, data) => {
if (err) {
logger.error('QMAws::startTask | end - %s', err.message);
reject(err); // err 발생 시 reject → runTask의 catch에서 return으로 전체 중단
} else {
if (data.failures && data.failures.length > 0) {
logger.error('QMAws::startTask | ECS failures - ...');
// failures 로깅 후 계속 진행 — reject하지 않음
}
const tasks = data.tasks;
if (tasks == undefined) {
resolve([]); // task가 없으면 빈 배열로 resolve → 다음 instance 시도 가능
} else {
resolve(tasks);
}
}
});
기대 동작 vs 실제 동작:
- 기대:
listContainerInstances에서 ACTIVE로 반환된 instance는startTask시점에도 ACTIVE 상태여야 함 - 실제: 조회 후 수백ms 사이에 instance가 DRAINING으로 전환되어
startTask가 failure를 반환함.data.failures가 있어도 에러로 reject하지 않고 빈 task 배열로 resolve하므로, 코드는 다음 instance를 시도함 (이 점은 올바른 동작). 그러나 이 클러스터의 모든 instance(2개)가 동시에 DRAINING이어서 결국task size: 0으로 종료됨
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-any-compute-agent status:error @environment:production "QMAws::startTask"
service:cupixworks-any-compute-agent @environment:production "89685"
Job 89685 타임라인 (EU region, 2026-04-14):
| 시각 (UTC) | 이벤트 |
|---|---|
| 15:15:57.766Z | SQS 메시지 수신, job 89685 생성 (capture_id: 33467, team: byuk) |
| 15:15:57.913Z | runTask begin — g6.2xlarge instance 조회 시작 |
| 15:15:58.188Z | runTask end — task size: 0 (사용 가능한 instance 없음) |
| 15:17:29.514Z | SQS 재전송으로 두 번째 시도 |
| 15:17:29.762Z | container instance 1e16c03a1eef416c85d83d42f62e9d39 발견 — status: ACTIVE, memory: 30940 MiB, CPU: 8192 |
| 15:17:29.959Z | startTask DRAINING failure — instance 1e16c03a1eef416c85d83d42f62e9d39 |
| 15:17:29.959Z | container instance 8130b6080a4d4114b2c188c8f18390e7 발견 — status: ACTIVE, memory: 30940 MiB, CPU: 8192 |
| 15:17:30.149Z | startTask DRAINING failure — instance 8130b6080a4d4114b2c188c8f18390e7 |
| 15:17:30.149Z | runTask end — task size: 0 (두 instance 모두 DRAINING) |
| 15:19:01.557Z | 세 번째 시도 — instance 없음, task size: 0 |
| 15:20:43.490Z | 네 번째 시도 — 새 instance 31aec61bbd824e29bccc39aa560b758e 발견 |
| 15:20:43.683Z | runTask end — task size: 1 (성공) |
| 15:20:44.014Z | task ARN 할당 완료 |
핵심 에러 로그 원문:
{
"timestamp": "2026-04-14T15:17:29.959Z",
"status": "error",
"service": "cupixworks-any-compute-agent",
"message": "QMAws::startTask | ECS failures - job_id: 89685, task_definition: cupix-pano-postprocessor-production, cluster: cupix-tesla-ece-eu, container_instance: arn:aws:ecs:eu-central-1:002596530511:container-instance/cupix-tesla-ece-eu/1e16c03a1eef416c85d83d42f62e9d39, failures: [{\"arn\":\"arn:aws:ecs:eu-central-1:002596530511:container-instance/1e16c03a1eef416c85d83d42f62e9d39\",\"reason\":\"DRAINING\"}]"
}
{
"timestamp": "2026-04-14T15:17:30.149Z",
"status": "error",
"service": "cupixworks-any-compute-agent",
"message": "QMAws::startTask | ECS failures - job_id: 89685, task_definition: cupix-pano-postprocessor-production, cluster: cupix-tesla-ece-eu, container_instance: arn:aws:ecs:eu-central-1:002596530511:container-instance/cupix-tesla-ece-eu/8130b6080a4d4114b2c188c8f18390e7, failures: [{\"arn\":\"arn:aws:ecs:eu-central-1:002596530511:container-instance/8130b6080a4d4114b2c188c8f18390e7\",\"reason\":\"DRAINING\"}]"
}
7일간 서비스 전체 동일 패턴:
service:cupixworks-any-compute-agent status:error "ECS failures" "DRAINING"
지난 7일간 DRAINING/AGENT 관련 failure가 34건 발생, 3개 리전(us-west-2, eu-central-1, ap-southeast-2) 모두에서 확인됨. 주요 task definition별 분포: cupix-capture-3d-reconstruction-production, cupix-pano-postprocessor-production, cupix-skat-master-production-arm, cupix-capture-refinement-production-arm.
Fix Recommendation#
즉시 조치 (Critical)#
- 파일:
applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:196-203 startTask에서data.failures에 DRAINING reason이 포함된 경우 error 로그 대신 warn 레벨로 변경. 이는 인프라의 일시적 상태 변화로 인한 예상 가능한 실패이며, SQS retry로 자동 복구되므로 error로 분류할 필요 없음- 현재 코드는 failure 시 빈 배열로 resolve하여 다음 instance를 시도하는 동작은 올바르지만, 불필요한 error alert를 발생시킴
단기 개선 (1주 이내)#
- 파일:
applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:149 describeContainerInstances결과에서status == 'ACTIVE'체크 외에,agentConnected == true조건을 추가하여 AGENT 연결이 끊긴 instance도 사전에 필터링startTaskfailure 시 DRAINING/AGENT reason을 감지하면, 해당 instance를 제외하고listContainerInstances를 재호출하여 다른 instance를 즉시 시도하는 retry 로직 추가 (현재는 SQS visibility timeout에 의존하여 ~90초 후 재시도)
장기 개선 (재발 방지)#
- ECS
startTaskAPI 대신runTaskAPI(Fargate 또는 EC2 launch type)를 사용하면 ECS 스케줄러가 자동으로 적절한 instance를 선택하므로 DRAINING race condition을 근본적으로 회피 가능 - ASG scale-in 시 container instance draining에 대한 lifecycle hook을 설정하여, draining 시작 전에 해당 instance를 agent 목록에서 먼저 제거하는 방식 검토
- 클러스터별 최소 active instance 수를 보장하는 ASG 정책 검토 (현재 EU 클러스터에서 2개 instance가 동시에 DRAINING되어 전체 용량 부재 발생)
Monitoring#
- DRAINING failure를 warn으로 변경 후, 아래 쿼리로 빈도 모니터링:
service:cupixworks-any-compute-agent "ECS failures" ("DRAINING" OR "AGENT")
- 특정 클러스터에서 연속 DRAINING failure가 임계치(예: 5분 내 5건)를 초과하면 alert 발생:
service:cupixworks-any-compute-agent status:error "ECS failures" "DRAINING" cluster:cupix-tesla-ece-eu
- job 처리 지연 시간 메트릭 추가: SQS 메시지 최초 수신 시각과 task 성공 시각 간 차이를 추적
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- SQS retry 메커니즘이 자동 복구를 보장하므로 데이터 유실 위험은 없음. 주요 영향은 processing 지연(이 건은 ~5분). 7일간 34건 발생으로 빈도가 높지만, 모두 자동 복구됨.