QMAws::startTask | ECS failures - job_id: 90459, task_definition: cupix-skat-master-production-arm,
RCA: QMAws::startTask | ECS failures - DRAINING container instance
Error Log#
QMAws::startTask | ECS failures - job_id: 90459, task_definition: cupix-skat-master-production-arm, cluster: cupix-tesla-ece-eu, container_instance: arn:aws:ecs:eu-central-1:002596530511:container-instance/cupix-tesla-ece-eu/c6a22b33f1b64addbe150be3df88cefb, failures: [{"arn":"arn:aws:ecs:eu-central-1:002596530511:container-instance/c6a22b33f1b64addbe150be3df88cefb","reason":"DRAINING"}]
Impact#
- Service:
cupixworks-any-compute-agent - Team: groupamana
- 발생 횟수: 1 (이 클러스터), 19건 (최근 7일 동일 패턴)
- 최초 발생: 2026-04-18T06:17:30.078Z
- 최근 발생: 2026-04-18T06:17:30.078Z
Root Cause Summary#
ECS container instance c6a22b33f1b64addbe150be3df88cefb가 DRAINING 상태로 전환 중이었으나, listContainerInstances API가 status: 'ACTIVE' 필터로 조회했음에도 해당 인스턴스를 반환했다. 이는 ECS API의 상태 전환 지연(race condition) 때문이다. 이후 startTask 호출 시 ECS가 DRAINING 사유로 task 배치를 거부했다. 현재 코드는 startTask 실패 시 return으로 즉시 종료하여 다른 정상 인스턴스를 시도하지 않는다. SQS 메시지 재처리(약 10초 간격)를 통해 5번째 시도에서 다른 인스턴스(9c6a809a...)로 성공했지만, 총 약 55초의 불필요한 지연이 발생했다. 이 패턴은 최근 7일간 8개 job에서 19회 반복되고 있다.
Technical Analysis#
Code Path#
- Entry point:
qmAws.ts:117-runTask()메서드가 SQS 메시지 처리 시 호출됨 qmAws.ts:121-listContainerInstances()로 ACTIVE 상태 인스턴스 목록 조회qmAws.ts:135-describeContainerInstances()로 상세 정보(메모리, CPU, 상태) 확인qmAws.ts:149-151- status == 'ACTIVE', runningTasksCount == 0, pendingTasksCount == 0 조건 확인qmAws.ts:154-startTask()호출하여 ECS task 배치 시도- Failure point:
qmAws.ts:156-157-startTask실패 시catch블록에서return으로 즉시 종료 (다른 인스턴스 시도 불가)
listContainerInstances 필터 (qmAws.ts:238-245):
// applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:238-245
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
};
status: 'ACTIVE' 필터를 사용하지만, ECS API는 DRAINING 전환 중인 인스턴스도 잠시 ACTIVE로 반환할 수 있다.
인스턴스 선택 및 startTask 호출 (qmAws.ts:149-159):
// applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:149-159
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; // 즉시 종료 - 다른 인스턴스를 시도하지 않음
}
}
return (line 157)이 핵심 문제점이다. continue가 아닌 return을 사용하여, 하나의 인스턴스에서 실패하면 나머지 정상 인스턴스를 시도하지 않고 전체 runTask가 종료된다.
startTask 에러 처리 (qmAws.ts:191-213):
// 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);
} else {
if (data.failures && data.failures.length > 0) {
logger.error('QMAws::startTask | ECS failures - job_id: %d, ...', ...);
}
const tasks = data.tasks;
if (tasks == undefined) {
resolve([]);
} else {
resolve(tasks); // DRAINING failure 시 tasks는 빈 배열
}
}
});
DRAINING failure는 err가 아닌 data.failures로 반환된다. 에러를 로깅하지만 resolve(tasks)로 빈 배열을 반환하므로, runTask의 tasks.length > 0 검사에서 break하지 않고 다음 인스턴스로 넘어간다. 단, AWS API 레벨 에러(reject)가 발생하면 catch에서 return으로 즉시 종료된다.
기존 수정 시도 (TSLA-12392, commit 41576ec8d): agentConnected 필터 추가 + return → continue 변경이 feature 브랜치에 존재하나, develop/master에 미반영 상태.
Log Evidence#
Datadog 쿼리 1: 에러 로그
service:cupixworks-any-compute-agent status:error "QMAws::startTask"
에러 로그 (1건):
2026-04-18T06:17:30.078Z | ERROR | QMAws::startTask | ECS failures - job_id: 90459, task_definition: cupix-skat-master-production-arm, cluster: cupix-tesla-ece-eu, container_instance: arn:aws:ecs:eu-central-1:002596530511:container-instance/cupix-tesla-ece-eu/c6a22b33f1b64addbe150be3df88cefb, failures: [{"arn":"arn:aws:ecs:eu-central-1:002596530511:container-instance/c6a22b33f1b64addbe150be3df88cefb","reason":"DRAINING"}]
Datadog 쿼리 2: job 90459 전체 타임라인
service:cupixworks-any-compute-agent "90459"
타임라인 (SQS 재처리 기반 6회 시도):
| 시간 (UTC) | 이벤트 |
|---|---|
| 06:17:29.656 | runTask begin - job id: 90459, instance_type: m8g.8xlarge |
| 06:17:29.881 | container instance c6a22b33...: status ACTIVE, 126943 MiB free, 0 running, 0 pending |
| 06:17:29.881 | container instance ba0df0cd...: status ACTIVE, 991 MiB free, 1 pending task (스킵됨) |
| 06:17:30.078 | startTask FAILED - DRAINING failure |
| 06:17:40 ~ 06:18:13 | 재시도 2~4회 - 동일 실패 (task size: 0) |
| 06:18:24.132 | 재시도 5회 - 새 인스턴스 9c6a809a... 선택 (126943 MiB, 0 running, 0 pending) |
| 06:18:24.324 | startTask SUCCESS - task size: 1 |
| 06:18:24.674 | updateTaskIdToJob 완료 - task ARN: 339598c8fb1f45edbbdf2628793f20a2 |
총 복구 시간: 약 55초.
Datadog 쿼리 3: 최근 7일 DRAINING 에러 패턴
service:cupixworks-any-compute-agent status:error "DRAINING"
최근 7일간 19건의 DRAINING 에러가 8개 job에서 발생:
| 날짜 | Job ID | Task Definition | Cluster | DRAINING 인스턴스 수 |
|---|---|---|---|---|
| 2026-04-18 06:17 | 90459 | cupix-skat-master-production-arm | cupix-tesla-ece-eu | 1 |
| 2026-04-18 01:33 | 1022147 | cupix-skat-master-production-arm | cupix-tesla-ece | 1 |
| 2026-04-16 19:23 | 1018906 | cupix-capture-3d-reconstruction-production | cupix-tesla-ece | 3 |
| 2026-04-16 08:33 | 1018106 | cupix-skat-master-production-arm | cupix-tesla-ece | 5 |
| 2026-04-16 08:03 | 1018051 | cupix-skat-master-production-arm | cupix-tesla-ece | 3 |
| 2026-04-14 15:17 | 89685 | cupix-pano-postprocessor-production | cupix-tesla-ece-eu | 2 |
| 2026-04-14 00:53 | 1012847 | cupix-capture-3d-reconstruction-production | cupix-tesla-ece | 1 |
| 2026-04-13 15:33 | 1011694 | cupix-capture-3d-reconstruction-production | cupix-tesla-ece | 3 |
US (cupix-tesla-ece)와 EU (cupix-tesla-ece-eu) 클러스터 모두에서 발생하며, 3개 task definition에 걸쳐 반복됨.
Fix Recommendation#
즉시 조치 (Critical)#
TSLA-12392 (commit 41576ec8d)를 develop/master에 머지해야 한다. 해당 수정은 두 가지 핵심 변경을 포함:
qmAws.ts:149-agentConnected == true필터 추가: ECS agent가 연결 해제된 인스턴스(DRAINING 전환 중 발생)를 사전에 제외qmAws.ts:157-return→continue변경: 한 인스턴스 실패 시 다른 정상 인스턴스로 즉시 fallback
이 수정이 적용되면 SQS 재처리 대기(~10초 x N회) 없이 같은 runTask 호출 내에서 다른 인스턴스를 바로 시도할 수 있다.
단기 개선 (1주 이내)#
startTask에서data.failures에 DRAINING이 포함된 경우, 해당 인스턴스를 로컬 캐시에 기록하여 같은 polling 주기 내에서 재선택하지 않도록 개선. 현재는resolve([])로 반환하므로continue와 조합하면 다음 인스턴스를 시도하지만, 명시적 DRAINING 감지 로직을 추가하면 불필요한startTaskAPI 호출을 줄일 수 있다.listContainerInstances호출 시agentConnected필터를 ECS API 레벨에서 적용 가능한지 검토 (filter파라미터에agentConnected == true추가).
장기 개선 (재발 방지)#
- ECS Capacity Provider 전략 도입을 검토.
startTask(특정 인스턴스 지정) 대신runTask(ECS가 인스턴스 선택)를 사용하면 ECS 스케줄러가 DRAINING 인스턴스를 자동으로 제외한다. - Auto Scaling Group의 instance refresh/replacement 이벤트와 compute agent의 인스턴스 조회 사이에 발생하는 race condition을 근본적으로 해결하기 위해, ECS 서비스 기반 스케줄링으로의 마이그레이션을 고려.
Monitoring#
- DRAINING 에러 빈도 추적:
service:cupixworks-any-compute-agent status:error "DRAINING" | count by @job_id
- task 배치 지연 시간 모니터링 (runTask begin ~ startTask success 사이 시간):
service:cupixworks-any-compute-agent "QMAws::runTask | end" | measure @duration
- TSLA-12392 배포 후 DRAINING 에러 발생 건수가 0으로 감소하는지 확인
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial (기존 수정 TSLA-12392 머지만 필요)
현재 SQS 재처리 메커니즘이 자동 복구 역할을 하고 있어, 서비스 중단은 없다. 다만 55초의 불필요한 지연이 사용자 경험에 영향을 줄 수 있으며, 다수의 인스턴스가 동시에 DRAINING 상태인 경우(job 1018106: 5개 인스턴스) 지연이 수 분까지 늘어날 수 있다.