테스트 GitLab 인스턴스에서 카오스 생성하기
GitLab v19.4요약
Amazon Web Services의 CTO 인 Werner Vogels가 남긴 유명한 말처럼, 모든 것은 언제나 실패합니다. 개발자에게는 소프트웨어가 정상 동작하는 상황만큼이나 실패하는 상황을 고려하는 일이 중요합니다.
Amazon Web Services의 CTO 인 Werner Vogels가 남긴 유명한 말처럼, 모든 것은 언제나 실패합니다.
개발자에게는 소프트웨어가 정상 동작하는 상황만큼이나 실패하는 상황을 고려하는 일이 중요합니다. 그 차이가 극소수 사용자에게 500 오류가 산발적으로 나타나는 가벼운 문제로 끝날지, 아니면 모든 사용자에게 장시간 영향을 주는 전면 장애로 번질지를 가릅니다.
톨스토이의 문장을 빌리면, 행복한 서버는 모두 비슷하지만 실패하는 서버는 저마다의 방식으로 실패합니다. 다행히 이러한 실패 상황을 시뮬레이션할 방법이 있으며, 카오스 엔드포인트는 그 과정을 돕는 도구입니다.
현재 다음 상황을 시뮬레이션하는 엔드포인트가 네 가지 있습니다.
- 느린 요청.
- CPU를 많이 쓰는 요청.
- 메모리 누수.
- 예기치 않은 프로세스 종료.
카오스 엔드포인트 활성화#
당연한 이유로 이 엔드포인트는 production에서 기본적으로 활성화되어 있지 않습니다.
개발 환경에서는 기본적으로 활성화되어 있습니다.
시크릿 토큰으로 카오스 엔드포인트 접근을 보호해야 합니다. 무엇을 하는지 정확히 아는 경우가 아니라면 운영 환경에서 활성화하지 않습니다.
시크릿 토큰은 GITLAB_CHAOS_SECRET 환경 변수로 설정할 수 있습니다.
예를 들어 GDK를 사용한다면
다음 명령으로 설정할 수 있습니다.
GITLAB_CHAOS_SECRET=secret gdk start
secret은 사용하는 시크릿 토큰으로 바꿉니다.
카오스 호출#
카오스 엔드포인트를 활성화하고 애플리케이션을 재시작한 뒤에는 이 엔드포인트로 테스트를 시작할 수 있습니다.
기본적으로 카오스 엔드포인트를 호출하면 요청을 받은 웹 워커 프로세스가 이를 처리합니다. 예를 들어 Kill 동작을
호출하면 요청을 처리하던 Puma 워커 프로세스가 종료됩니다. Sidekiq에서 이러한 동작을 테스트하려면
각 엔드포인트의 async 파라미터를 true로 설정합니다. 그러면 카오스 프로세스가 Sidekiq 워커에서 실행됩니다.
메모리 누수#
애플리케이션의 메모리 누수를 시뮬레이션하려면 /-/chaos/leakmem 엔드포인트를 사용합니다.
요청이 끝난 뒤에는 메모리가 유지되지 않습니다. 요청이 완료되면 Ruby 가비지 컬렉터가 메모리 회수를 시도합니다.
GET /-/chaos/leakmem
GET /-/chaos/leakmem?memory_mb=1024
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50&async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
memory_mb |
integer | 아니요 | 누수시킬 메모리 양(MB)입니다. 기본값은 100 MB 입니다. |
duration_s |
integer | 아니요 | 메모리를 유지할 최소 시간(초)입니다. 기본값은 30초입니다. |
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 메모리 누수를 발생시킵니다 |
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10" \
--header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10&token=secret"
CPU 스핀#
이 엔드포인트는 지정한 기간 동안 코어 하나를 100% 로 사용하려고 시도합니다.
Rack 서버 구성에 따라 요청이 미리 정해진 시간(보통 60초) 후 타임아웃될 수 있습니다.
GET /-/chaos/cpu_spin
GET /-/chaos/cpu_spin?duration_s=50
GET /-/chaos/cpu_spin?duration_s=50&async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
duration_s |
integer | 아니요 | 코어를 사용할 시간(초)입니다. 기본값은 30초입니다 |
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 CPU를 소비합니다 |
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60" \
--header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60&token=secret"
DB 스핀#
이 엔드포인트는 지정한 기간 동안 코어 하나를 100% 로 사용하면서 DB 요청을 번갈아 실행하려고 시도합니다. 동시 실행 시 다른 스레드로 실행을 양보하는 상황을 모델링하는 데 사용할 수 있습니다.
Rack 서버 구성에 따라 요청이 미리 정해진 시간(보통 60초) 후 타임아웃될 수 있습니다.
GET /-/chaos/db_spin
GET /-/chaos/db_spin?duration_s=50
GET /-/chaos/db_spin?duration_s=50&async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
interval_s |
float | 아니요 | 각 DB 요청 사이의 간격(초)입니다. 기본값은 1초입니다 |
duration_s |
integer | 아니요 | 코어를 사용할 시간(초)입니다. 기본값은 30초입니다 |
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 작업을 수행합니다 |
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60" \
--header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60&token=secret"
슬립#
이 엔드포인트는 CPU 스핀 엔드포인트와 비슷하지만, 백엔드 서비스로의 네트워크 호출처럼 프로세서 밖에서 일어나는 활동을 시뮬레이션합니다. 지정한 duration_s 동안 대기합니다.
CPU 스핀 엔드포인트와 마찬가지로 duration_s가 설정된 한도를 넘으면 요청이 타임아웃될 수 있습니다.
GET /-/chaos/sleep
GET /-/chaos/sleep?duration_s=50
GET /-/chaos/sleep?duration_s=50&async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
duration_s |
integer | 아니요 | 요청이 대기할 시간(초)입니다. 기본값은 30초입니다 |
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 대기합니다 |
curl "http://localhost:3000/-/chaos/sleep?duration_s=60" \
--header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/sleep?duration_s=60&token=secret"
Kill#
이 엔드포인트는 KILL 시그널을 사용해 워커 프로세스가 예기치 않게 종료되는 상황을 시뮬레이션합니다.
이 엔드포인트는 KILL 시그널을 사용하므로 프로세스에 정리나 종료 절차를 수행할
기회가 주어지지 않습니다.
GET /-/chaos/kill
GET /-/chaos/kill?async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에 시그널을 보냅니다 |
curl "http://localhost:3000/-/chaos/kill" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/kill?token=secret"
Quit#
이 엔드포인트는 QUIT 시그널을 사용해 워커 프로세스가 예기치 않게 종료되는 상황을 시뮬레이션합니다.
KILL과 달리 QUIT 시그널은 코어 덤프 기록도 시도합니다.
자세한 내용은 core(5)를 참고합니다.
GET /-/chaos/quit
GET /-/chaos/quit?async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
async |
boolean | 아니요 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에 시그널을 보냅니다 |
curl "http://localhost:3000/-/chaos/quit" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/quit?token=secret"
가비지 컬렉터 실행#
이 엔드포인트는 요청을 처리하는 워커에서 GC 실행을 트리거하고, 해당 워커 ID와 GC 통계를 JSON으로 반환합니다. 주로 Puma를 독립 실행 모드로 운영할 때 유용합니다. 그렇지 않으면 요청을 처리하는 워커를 미리 알 수 없기 때문입니다.
엔드포인트:
POST /-/chaos/gc
요청 예시:
curl --request POST "http://localhost:3000/-/chaos/gc" \
--header 'X-Chaos-Secret: secret'
curl --request POST "http://localhost:3000/-/chaos/gc?token=secret"
응답 예시:
{
"worker_id": "puma_1",
"gc_stat": {
"count": 94,
"heap_allocated_pages": 9077,
"heap_sorted_length": 9077,
"heap_allocatable_pages": 0,
"heap_available_slots": 3699720,
"heap_live_slots": 2827510,
"heap_free_slots": 872210,
"heap_final_slots": 0,
"heap_marked_slots": 2827509,
"heap_eden_pages": 9077,
"heap_tomb_pages": 0,
"total_allocated_pages": 9077,
"total_freed_pages": 0,
"total_allocated_objects": 14229357,
"total_freed_objects": 11401847,
"malloc_increase_bytes": 8192,
"malloc_increase_bytes_limit": 30949538,
"minor_gc_count": 71,
"major_gc_count": 23,
"compact_count": 0,
"remembered_wb_unprotected_objects": 41685,
"remembered_wb_unprotected_objects_limit": 83370,
"old_objects": 2617806,
"old_objects_limit": 5235612,
"oldmalloc_increase_bytes": 8192,
"oldmalloc_increase_bytes_limit": 122713697
}
}