[Issue]
- CPU 사용률이 낮아져서 Scale In이 되는 상황에 해당 EC2에 Client가 사용 중인 경우
- Scale In 이벤트 발생 시 위 상황에서 세션이 강제 종료되는 것을 방지하는 것이 목적
우선 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시간으로 지정
되어있다고 가정해 보면 예상되는 시나리오는 아래와 같습니다.
- Scale In 이벤트 발생 직후 ~ 30분 : ELB를 통한 연결(연결1, 연결2)이 유지되며 EC2에 직접 연결(연결3)이
있다면 이 또한 유지됩니다.
- 30분 이후 ~ 1시간 : ELB를 통한 연결은 유효하지 않고, EC2에 직접 연결의 연결만 유지됩니다.
- 1시간 이후 : EC2가 종료되며, 결과적으로 ELB를 통한 연결 및 EC2의 직접 연결 모두 유지가 안됩니다.
이런 상황에서 해결할 수 있는 방법은 ELB Deregistration delay 시간을 충분하게 설정할 수 있습니다.
- Deregistration delay 시간은 각 타겟에서 활성화된 요청을 처리할 수 있는 충분한 시간을 주기 위해
타겟에서 Deregistration을 지연하는 기능입니다.
- 기본 300초(5분)으로 설정되며, 최대 3600초(1시간)까지 지정 가능합니다.
- ELB는 Deregistration이 시작되면, 대상으로 새로운 요청을 전송하는 것은 중지되며 기존 세션만 유지합니다.
또는 Lifecycle Hook 타임아웃 시간을 충분하게 설정할 수 있습니다.
- Default는 3600초(1시간) 이지만 최대 7200초(2시간)으로 지정할 수 있습니다.
- 최대 2시간 안에 세션 종료가 보장된다면, 가장 Good
- Deregistration delay를 3600초(1시간)으로 설정하면, 1시간 + 2시간 = 최대 3시간 후에 EC2가
종료될 수 있습니다.
마지막으로 Lambda를 활용해서 활성 세션 확인 여부에 따라 Lifecycle Hook 타임아웃 시간을 연장하거나
완료시킬 수 있습니다.
- Lambda를 이용한 Lifecycle 자동화 예시는 아래 링크에서 확인 가능합니다.
https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-lifecycle-hook-lambda.html
- Lifecycle Hook 타임아웃 시간이 임박했지만, 더 긴 시간이 필요하다면 RecordLifecycleActionHeartbeat API를
이용해서 연장할 수 있습니다.
- Lifecycle Hook 타임아웃 시간이 남았지만, 활성화된 세션이 없어 EC2를 종료해도 괜찮으면 CompleteLifecycleAction API를
이용해서 완료시킬 수 있습니다.
- 마지막으로 Lifecycle Hook 타임아웃 시간이 종료되면 활성화된 세션이 있어도 강제로 종료합니다.