[Issue]

우선 Scale In 이벤트 발생 시 ELB 및 Lifecycle Hook 동작 방식을 먼저 이해해야 합니다.

종료 대상 EC2가 정해지면, 해당 EC2가 ELB 타겟에서 제거 작업(Deregister)이 먼저 선행됩니다. Deregistration 작업이 요청되면 ELB는 더 이상 새로운 요청을 해당 타겟으로 전달하지 않고, 이미 생성된 커넥션이 종료될 때(Connection Draining)까지 특정 기간(Deregistration delay)만큼 기다립니다.

만약 Deregistration delay 기간이 지나면 ELB를 거쳐 설정된 커넥션은 강제로 종료 됩니다. (이때, 종료되는 커넥션은 ELB를 통해 생성된 커넥션으로 Client에서 EC2로 다이렉트로 생성된 요청이 아닙니다.)

Deregistration delay 작업은 Auto Scaling Lifecycle Hook과 독립적으로 동작을 합니다.

  1. ASG(Auto Scaling Group)를 통해 Sacle In 작업 시작
  2. 종료될 EC2 선정
  3. ELB에 해당 EC2 Deregistration 요청 전달
  4. ELB는 설정된 시간 동안 타겟 분리 보류, 타겟은 Draining 상태
  5. ELB는 설정된 시간이 지난 후 타겟 분리 완료, 타겟은 Unused 상태
  6. AGS는 Terminating:Wait 상태로 진입 (Lifecycle Hook 이벤트 발생)

따라서 Lifecycle Hook에 의해서 Terminating:Wait으로 진입할 때는 이미 ELB를 통해 만들어진 커넥션은 종료된 이후입니다.

하지만 이때, 해당 EC2는 종료되지 않았기 때문에 ELB를 경유하지 않고 직업 생성된 커넥션은 존재하게 됩니다.(EX: EC2 Public IP를 통해 ssh 접속 등)

예를 들어서 Flow를 보면 Flow 1. Client - 연결 1 - ELB - 연결 2 - 타겟(EC2) Flow 2. Client - 연결 3 - 타겟(EC2)

이때, 등록 취소 지연 시간(Deregistration delay)은 Flow 1과 관련이 있고, Lifecycle Hook 타임아웃 시간은 Flow 2와 관련이 있습니다.

예를 들면 ELB Deregistration delay 시간이 30분, Lifecycle Hook 타임아웃 시간이 1시간으로 지정 되어있다고 가정해 보면 예상되는 시나리오는 아래와 같습니다.

이런 상황에서 해결할 수 있는 방법은 ELB Deregistration delay 시간을 충분하게 설정할 수 있습니다.

또는 Lifecycle Hook 타임아웃 시간을 충분하게 설정할 수 있습니다.

마지막으로 Lambda를 활용해서 활성 세션 확인 여부에 따라 Lifecycle Hook 타임아웃 시간을 연장하거나 완료시킬 수 있습니다.