ddps-lab / cloud-usage

MIT License
1 stars 1 forks source link

전날 사용한 인스턴스 리포트에 스팟 인스턴스 사용량 추적을 위한 고도화 작업 진행 #40

Closed Kim-Yul closed 8 months ago

Kim-Yul commented 9 months ago

이전에 #38 이슈를 이어서 스팟 인스턴스 사용과 관련한 전반적인 내용을 트래픽합니다.

스팟 인스턴스 사용량을 추적하기에 앞서, 살펴보아야 할 사항이 있으며 스팟 인스턴스 사용량 추적을 위해 스팟 리퀘스트의 로그를 확인해야 합니다. 연구실 내 DDD 실험이나 추가적으로 진행할 실험, Spot 사용 일반화 등을 고려하여 안정성 높은 리포트 제작을 위해 이 내용을 이 이슈에서 트래픽합니다.

현재 살펴볼 사항은 DDD 실험 (1월 31일 자)의 CloudTrail 로그와 현재 진행 중인 실험 모니터링입니다.

Kim-Yul commented 9 months ago

현재 실행 중인 실험 준비 과정(멀티 스팟 인스턴스 안정성 실험 준비)과 관련하여 로그 추적

현 이슈에서는 짧게 멀티 스팟 sps 실험이라고 잠시 부르겠습니다. (실험의 이름이 명확하지 않아 명명 되는대로 바꿔 부르겠습니다.) 현재 daily instance usage report 를 모니터링 하던 와중, ap-south-1 리전에서 에러가 발생하였고, 이 부분을 추적하였습니다. 실험과 관련된 오류이기에 이곳에서 트래픽하는 것이 옳다고 생각하여 우선 이곳에서 진행하겠습니다.

멀티 스팟 sps 실험 과정 중 ap-south-1 리전에서는 총 2번의 인스턴스 실행이 있었으며 각각 개수는 6개와 50개입니다.

그 중 에러와 관련이 있는 것은 스팟 50개 요청입니다. 스팟 50개를 한 번에 요청할 시 리포트에서 인스턴스 아이디를 가져오는 항목에 다음과 같은 내용이 생성됩니다.

image

기존에는 인스턴스 아이디가 있는 일반적인 로그는 다음과 같습니다.

image

차이점을 확인해보시면, 50개의 요청이 너무 많이 인스턴스 아이디를 모두 기록하기에 사이즈가 너무 크다는 것이 이유로 responseElements too large 와 함께 인스턴스 아이디를 수집할 수 없습니다. 이에 현재 슬랙에서는 인스턴스 아이디를 읽기 위해 확인하는 instancesSet 을 확인할 수 없어 일부의 사용량만 기록된 채 다음 리전으로 넘어간 것을 확인할 수 있습니다.

image

50개의 인스턴스는 실제 run -> terminate 되어 정보를 수집하였다고 하여 해당 정보를 확인하기 위해 로그를 추적하였고, DescribeSpotInstanceRequests 이벤트를 통해 50개의 인스턴스의 스팟 요청을 확인할 수 있었습니다.

image

즉, Run 이벤트에서 사이즈가 커 인스턴스 아이디를 수집하진 않았지만, 정상적으로 스팟 요청이 들어갔고 이후 Terminate 까지 된 것을 확인하였습니다.

image

DescribeSpotInstanceRequests 이벤트의 경우 RunInstances 이벤트 1초 후에 실행되었으며 모두 같은 시간대로 로그가 기록되어 있습니다. 또한, RunInstances 이벤트에서 특정 값을 통해 스팟 요청을 몇 개 보냈는지 확인이 가능합니다.

다음은 50개의 스팟 요청을 보냈을 때의 로그와 6개의 스팟 요청을 보냈을 때의 로그입니다.

image image

위 부분을 통해 스팟 로그 추적이 가능할 것으로 판단됩니다. 해당 이슈에서는 이 부분에 정확한 사용량 추적을 위해 스팟 요청 과정 탐색 -> 코드 구현 -> 모니터링 과정으로 진행하겠습니다.

우선 위의 에러 사항을 확인하였기에 같은 에러가 또 발생하지 않도록 예외처리 진행해두겠습니다. 이후 코드 구현 과정에서 예외처리한 부분을 실제 구동가능하도록 수정하겠습니다.

위 과정 모니터링 중에서 성규님 로그가 필요할 것으로 생각되어 매일 실행한 로그 전달 받아 분석 및 추적 진행하겠습니다!

Kim-Yul commented 9 months ago

로그 추적 진행 중입니다. 현재 cloudtrail로 로그 추적중입니다. 콘솔 상으로 비슷한 환경을 재현하여 로그를 확인하고 있는데, 이에 어려움이 존재합니다. 일단 성규님이 진행하신 실험과 완전히 비슷한 상황이 유도되지 않고, run 이후 terminate 없이 인스턴스가 꺼지는 경우를 발견하지 못하였습니다. 그래서 경환님께 요청을 드려 성규님이 실제 사용하신 환경 코드를 전달 받았습니다. 이 실험 환경에서 t2.medium 으로 인스턴스 1개만 켠 뒤 3분 동안의 cloudtrail 로그 확인하도록 하겠습니다. 이후 다시 로그 추적 결과 코멘트 달도록 하겠습니다.

Kim-Yul commented 9 months ago

로그 추적 결과

Spot 실험 재현

이전에 진행하였던 스팟 실험을 재현하여 로그를 확인하였습니다. 실험 재현을 위해 다음과 같이 진행하였습니다.

로그 분석

현 로그는 Terminate 한 시간을 구하기 위해 분석하였습니다. 위 실험은 스팟 요청을 할 때 스팟 정보와 함께 스팟 캔슬 시간을 보냈습니다. 이 경우 스팟 캔슬 시간에 의해 인스턴스가 강제로 종료되는 것을 확인하였습니다. 이럴 경우에는 cloud trail 내에 인스턴스 종료와 관련된 이벤트인 TerminateInstances 를 확인할 수 없습니다. 대신 위와 같이 스팟 캔슬 시간 정보를 확인할 수 있는 방법을 찾기로 하였고, 찾는 과정은 다음과 같습니다.

스팟 캔슬 시간 : RequestSpotInstances 이벤트

해당 이벤트에는 스팟 인스턴스 생성 요청 시 보내는 정보가 기입되어 있습니다. 그중에서도 스팟 요청 후에 사용자가 지정한 시간까지 요청이 지속되는 validUntil 값을 정할 수 있습니다. 이 값을 3분으로 지정하면, 스팟 요청 3분 후 스팟 요청이 캔슬 되는 형식입니다. 요청이 캔슬되면서 실행된 스팟 인스턴스가 종료됩니다.

image

위의 시간 값은 unix timestamp 값으로 저장되어 있습니다. 이 값을 종료 시간으로 저장하게 되면 현재 메세지에서는 인스턴스 실행 중 으로 뜨는 것이 사용량과 함께 실행된 정보를 반환할 수 있습니다.

코드구현 아이디어

스팟 리퀘스트 요청 시 스팟 요청 캔슬의 정보도 함께 보내게 되면서 Terminate 이벤트 없이 인스턴스가 종료됩니다. 이때 해당되는 이벤트가 없기 때문에 이전까지는 종료 시간을 수집하지 못하였습니다. 위의 이벤트를 통해 스팟 캔슬 시간을 찾게 된다면 아래와 같은 방법으로 종료 시간을 수집하고자 합니다.

코드 구현 부분

image

위 코드는 인스턴스가 시작된 정보는 있으나 멈춘 정보는 찾을 수 없을 떄 발생하는 예외처리 코드입니다. 위 에러처리 부분에 새로 함수를 호출하여 코드를 구현하고자 합니다.

1. API로 DescribeSpotInstanceRequests 찾기

image

현재 인스턴스 아이디를 user name으로 하여 cloudtrail api에 검색합니다. 검색하는 함수는 이전에 작성된 코드를 재사용합니다. 이때, DescribeSpotInstanceRequests 이벤트를 받아옵니다.

image

인스턴스 아이디를 통해 검색한 정보에는 DescribeSpotInstanceRequests 이벤트가 유일하기 때문에 검색된 결과에서 해당되는 이벤트를 뽑아 이 이벤트 내에 있는 정보를 수집합니다.

2. 스팟 리퀘스트 아이디 찾아내기

image

찾아낸 이벤트에서 스팟리퀘스트 아이디 정보만 받아옵니다.

3. API로 RequestSpotInstances 찾기

image

스팟 리퀘스트 아이디를 resource name으로 api 검색을 하게 되면 RequestSpotInstances 이벤트를 찾을 수 있습니다. 이 이벤트에 찾고 싶었던 validUntil 값을 찾을 수 있습니다.

image

이 값을 가져와서 종료 시간으로 기록합니다.

코드 구현 과정 중 중요한 사항

모든 과정은 try 안에서 구현합니다. 모든 과정에서 예외 발생 시 종료 시간을 구할 수 없다고 가정하여 기존의 시간을 계산하는 원래 코드를 실행하게 합니다. 종료 시간을 구할 수 있을 수도 있으니 이 부분은 모니터링을 통해 다듬어가겠습니다.


브랜치 충돌 등의 이유로 이전 코드 머지 후 진행하고 싶습니다. 따로 구현하다가 머지 후에 풀리퀘 올리겠습니다.

Kim-Yul commented 8 months ago

추가 진행 사항

대부분의 작업을 구현하긴 하였으나 DDD 와 같은 실험은 예외적으로 람다로 인스턴스 추적이 어렵습니다. 람다로 실제 진행해본 결과 타임아웃이 발생하는 것을 확인했습니다. 이와 관련하여 DDD 실험 당일인스턴스 패턴을 파악하여 예외처리할 수 있는 방향을 추가로 추적하도록 하겠습니다. 예외처리가 가능할지 cloudtrail 로그 파악을 우선 진행하도록 하겠습니다.

Kim-Yul commented 8 months ago

대규모 실험의 사용량 메세지

Instance 실행 시간이 3초 이내인 경우

일반적인 대규모 실험, 예를 들어 DDD 실험의 경우 대부분의 인스턴스가 3초 이내에 중지된 것을 확인하였습니다. 이런 경우 메세지로 띄우지 않고 압축하여 실험을 위한 n개의 인스턴스가 3초 이내로 실행되었습니다. 라는 메세지를 띄웁니다.

또한, 실험에서 Instances가 생성되었지만, Terminate를 찾지 못한 경우 이는 spot requests 요청 취소시간에서 찾을 수 없습니다. 이때의 User Name이 InstanceLaunch 인 경우 실험의 일부로 생각하여 0초 실행된 것으로 가정합니다.

Query 갯수가 많아 TimeOut 발생

DDD 실험의 경우 15min limit 일지라도 TimeOut이 발생합니다.

위 TimeOut 대처를 고민 중입니다.

  1. 람다 멀티 스레드 설정
  2. 인스턴스에서 실행하게 설정

CloudTrail에서 받아오는 로그에서는 대규모 실험의 인스턴스인지 아닌지 판별이 불가능합니다. 또한, 쿼리를 받아온 상태에서 분류하는 것 역시 그 분류하는 시간을 소모하기 것이기 때문에 람다 TimeOut 가능성이 매우 높습니다. 현재의 경우 TimeOut이 발생하면 아예 슬랙으로 메세지를 보내지 않고 있기에 대처 방안을 고민하고 있습니다.

위의 내용을 반영하면 생성될 메세지 형식

image

고민 사항

현재 ec2에서 위의 변경 사항이 잘 진행되는 것을 확인하였습니다. 그러나 람다에서는 TimeOut이 발생하고 있어 어떻게 해결할지 고민하고 있습니다. 최대한 비용 효율적인 측면을 고려하겠습니다.

Kim-Yul commented 8 months ago

대규모 실험일 때의 메세지 전달 방식

자체적으로 실행 시간을 5분으로 설정합니다. 5분이 지났음에도 사용량 측정이 남은 경우 이미 측정된 내용만 슬랙으로 전달하며 측정이 중단되었다는 메세지를 덧붙입니다.

마지막 DDD 실험의 사용량 메세지

1월 30일 인스턴스 사용량 메세지

image

1월 31일 인스턴스 사용량 메세지

Screenshot 2024-03-12 at 12 19 57

측정 중단으로 결정한 이유

ec2 내에서 코드를 돌려 로그를 확인한 결과,

이를 람다에서 실행하면 TimeOut이 발생하므로 적절하지 않다고 생각하여 방안으로 고려한 끝에 미팅을 통해 측정 중단으로 결정하였습니다.

바로 코드를 커밋하여 코드 리뷰 후 목요일에 머지하겠습니다. 그동안은 람다에 반영하여 이틀 간 에러가 발생하는지 모니터링 진행하겠습니다. 이후 해당 이슈 마무리하겠습니다.

Kim-Yul commented 8 months ago

작업 추가

모니터링 중 일반적으로 사용한 인스턴스가 실험에 사용된 것처럼 예외가 되어 이 예외에서 제외할 방법을 구상하고 있습니다.

image

InstanceLaunch 에 의해 실행된 인스턴스의 시간을 구하지 못할 경우 실험에 사용한 인스턴스인 것처럼 예외처리한 것은 제가 의도한 바가 맞지만, 지금 도쿄 리전에서 사용된 인스턴스는 사용자가 인스턴스를 Terminate 한 이후 spot requests에 의해서 생성된 인스턴스입니다. 그렇기 때문에 실험 때 발생하는 로그와 차이점이 있을 것이라 생각하였고, key의 존재 여부로 차이가 발생하는 것 같아 해당 코드만 작업하고 있습니다. 오늘 작업해서 모니터링 및 코드리뷰 후 이상 없으면 예정대로 해당 이슈 마무리 하겠습니다.

Kim-Yul commented 8 months ago

해당 이슈 #42 를 끝으로 작업 마무리하여 클로즈합니다. 추후 에러 발생 시 새로운 트래킹으로 진행합니다.