카오스 엔지니어링 Microservices 탄력성 향상
카오스 엔지니어링 은 시스템의 내구성과 회복력을 테스트하고 개선하기 위해 의도적으로 장애를 발생시키는 실험적인 접근 방식입니다. Microservices는 서비스를 개발 및 배포하는 팀에게 매우 인기 있는 패턴이 되었습니다. Microservices를 사용하면 개발자는 더 작고 집중된 코드베이스로 작업할 수 있으며, 서비스를 배포하는 시기와 방법에 대해 더 많은 독립성을 확보할 수 있습니다. 이는 Monolith를 사용할 때보다 큰 장점입니다.
하지만 공짜 점심 같은 것은 없습니다. Monolith에서 Microservices로 전환한다고 해서 복잡성이 사라지는 것이 아니라 약간의 변화가 있을 뿐입니다. 개별 Microservices를 개발하는 것은 코드베이스가 작기 때문에 더 쉽지만, Production 환경에서 Microservices를 운영하는 것은 기하급수적으로 더 복잡해질 수 있습니다. Microservices로 구축된 시스템에는 Load Balancer, 방화벽 규칙 등 더 많은 호스트 및/또는 컨테이너가 실행되고 있을 가능성이 높습니다. Microservices마다 다른 목적(웹 서비스, Reverse Proxy, Load Balancing)으로 NGINX를 사용하고 있을 수도 있습니다. 서비스 수가 수십 개에서 수백, 수천 개로 늘어나면 시스템을 이해하고 동작을 예측하기가 더 어려워집니다. 게다가 서비스들은 모두 Monolith 내에서 모듈 간 호출이 아닌 네트워크를 통해 서로 통신합니다.
Microservices 기반 시스템이 정상적인 조건에서 설계된 대로 작동할 뿐만 아니라 환경의 예기치 않은 장애나 성능 저하를 처리할 수 있는지 어떻게 검증할 수 있을까요? 한 가지 좋은 방법은 카오스 엔지니어링 입니다. 카오스 엔지니어링 은 팀이 Production 환경에서 실행 중인 애플리케이션을 더 잘 관리하고 시스템의 탄력성을 높이는 데 도움이 될 수 있는 방법입니다.
목차
1. 카오스 엔지니어링 (Chaos Engineering)이란?
2. 가설 세우기
3. 폭발 반경, 규모, 중단 조건
4. 블랙홀 공격을 통한 종속성 검증
5. 결론
1. 카오스 엔지니어링 (Chaos Engineering)이란?
카오스 엔지니어링 은 시스템의 약점을 드러내기 위해 고안된 신중하고 계획된 실험으로 정의합니다. 우리가 자주 사용하는 비유로는 향후 감염을 예방하기 위해 잠재적으로 해로운 물질을 인체에 주입하는 예방 접종을 들 수 있습니다. 카오스 엔지니어링 실험에서는 시스템에 적극적으로 ‘실패를 주입’하여 탄력성을 테스트합니다. 이러한 실험은 가설을 세우고 실험을 수행한 후 가설의 유효성 여부를 확인하는 과학적 방법을 사용하여 수행합니다.
시스템에 주입할 수 있는 장애 유형에는 호스트 또는 컨테이너 종료, CPU 부하 또는 메모리 사용량 추가, 네트워크 지연 또는 패킷 손실 추가 등이 있습니다. 다른 장애 유형도 있지만, 실험에서 어떤 종류의 장애를 일으킬 수 있는지 대략적으로 알 수 있습니다.
2. 가설 세우기
카오스 엔지니어링 실험을 수행하는 첫 번째 단계는 가설을 세우는 것입니다. 가설은 우리가 주입하는 장애가 시스템에 미칠 것으로 예상되는 영향을 설명합니다. 우리는 시스템의 탄력성을 테스트하려는 것임을 명심하세요. 일반적으로 우리의 가설은 시스템이 우리가 주입하는 장애 유형에 대해 탄력성을 가질 것이라는 것입니다. 하지만 때때로 가설이 정확하지 않다는 사실을 발견할 수 있으며, 이때 배운 내용을 사용하여 시스템의 탄력성을 개선할 수 있습니다.
예를 들어, 다른 서비스에 REST API를 Expose하는 상태 비저장 HTTP 서비스가 NGINX에서 실행 중이라고 가정해 보겠습니다. Production 환경에서 이 서비스의 인스턴스를 10개의 호스트에서 실행하고 있는데, 이는 각 호스트의 CPU를 최대로 사용하지 않고 현재 부하를 처리하는 데 필요한 호스트 수이기 때문입니다. 의도적으로 호스트를 다운시켜 충분한 Redundancy를 구축했는지 적극적으로 테스트할 수 있습니다. 이 경우 우리의 가설은 “시스템이 호스트의 장애에 대해 탄력성이 있으므로 다른 서비스나 시스템을 사용하는 사람들에게는 아무런 영향이 없을 것이다”입니다. 그런 다음 실험을 수행하여 가설이 맞는지 여부를 확인할 수 있습니다.
3. 확산 반경, 규모, 중단 조건
실험을 계획할 때 염두에 두어야 할 세 가지 중요한 개념은 확산 반경, 규모, 중단 조건입니다. 각 개념이 무엇인지 자세히 살펴보겠습니다.
확산 반경은 실험을 실행하는 호스트(또는 컨테이너)의 비율입니다. 이는 Non Production 환경에서도 실험이 사용자에게 미칠 수 있는 잠재적 영향을 최소화해야 하므로 매우 중요한 개념입니다. 하나의 호스트 또는 컨테이너와 같이 작은 확산 반경으로 시작한 다음, 더 많은 것을 배우고 실험에 익숙해지면 확산 반경을 늘려나가는 것이 개념의 핵심입니다.
규모는 개별 호스트 또는 컨테이너에 가하는 부하 또는 서비스 중단의 양입니다. 예를 들어, NGINX를 실행하는 웹 서버에 대한 CPU 공격의 영향을 테스트하는 경우, 처음에는 CPU 부하(규모)를 20% 더 추가하는 것으로 시작하여 시간이 지남에 따라 이를 늘릴 수 있습니다. CPU 부하 증가가 응답 시간과 같은 서비스 지표에 미치는 영향을 관찰하여 성능이 허용되지 않는 수준이 되기 전에 시스템이 얼마나 큰 공격을 견딜 수 있는지 확인할 수 있습니다.
중단 조건은 실험을 중단하게 만드는 조건입니다. 시스템에 미치는 영향의 종류(또는 양)가 너무 커서 실험을 계속할 수 없을 정도인지 미리 파악해 두는 것이 좋습니다. 오류율이나 지연 시간이 증가하거나 모니터링 소프트웨어에서 생성된 특정 경고가 발생할 수 있습니다. 중단 조건은 원하는 대로 정의할 수 있으며, 이러한 정의는 실험마다 다를 수 있습니다.
확산 반경, 규모, 중단 조건을 통해 카오스 엔지니어링 실험을 안전하게 수행할 수 있습니다. 카오스 엔지니어링 실험을 계획할 때는 항상 시스템 사용자를 염두에 두어 사용자에게 부정적인 영향을 미치지 않도록 하는 것이 중요합니다. 이것이 바로 시스템의 탄력성을 높이고 더 나은 사용자 경험을 제공하기 위해 노력하는 이유입니다.
4. 블랙홀 공격을 통한 종속성 검증
Monolith에서 Microservices 로 전환할 때 증가하는 복잡성 유형 중 하나는 추가 종속성입니다. 시스템의 모든 비즈니스 로직을 포함하는 Monolithic 애플리케이션 대신 이제 서로 의존하는 여러 서비스가 있습니다. Microservices는 클라우드 제공업체의 API 또는 인프라의 일부로 사용하는 SaaS 서비스와 같은 다른 외부 서비스에도 종속될 수 있습니다.
이러한 외부 또는 내부 종속성이 실패하면 어떻게 될까요? 코드에 설정한 안전장치가 실제로 이러한 장애를 완화하나요? Timeout 및 재시도 로직과 같은 기능이 실제 운영 환경에서 시스템이 작동하는 방식에 맞게 잘 조정되어 있나요?
블랙홀 공격은 실패한 종속성을 처리할 수 있는지 테스트할 수 있는 좋은 방법입니다. 블랙홀 공격은 특정 호스트명, IP 주소 및/또는 포트에 대한 호스트 또는 컨테이너의 액세스를 차단하여 해당 리소스를 사용할 수 없을 때 발생할 수 있는 상황을 시뮬레이션합니다. 네트워크 또는 방화벽 관련 중단과 네트워크 파티션을 시뮬레이션할 수 있는 좋은 방법입니다.
외부 종속성의 경우, Twilio API를 사용하여 고객에게 SMS 메시지를 보내는 서비스를 운영한다고 가정해 봅시다. Twilio와의 통신이 언제든지 중단될 수 있다는 것을 알고 있으므로 Microservices가 대기열(Queue)에서 메시지를 읽고, Twilio API를 통해 Twilio로 성공적으로 전송된 후에만 Queue에서 메시지를 삭제하도록 설계했습니다. Twilio API를 사용할 수 없는 경우, 메시지는 저희 쪽에서 Queue에 대기하고(Kafka 또는 ActiveMQ와 같은 메시지 버스를 사용할 수도 있음), 결국 Twilio와의 통신이 재개되면 전송될 것입니다.
하지만 실제로 테스트하기 전까지는 Twilio에 대한 네트워크 연결이 끊어졌을 때 서비스가 실제로 어떻게 작동하는지 어떻게 알 수 있을까요? 서비스를 설계할 때 화이트보드에 그린 내용이 실제 Production에서 어떻게 작동하는지 어떻게 알 수 있을까요?
블랙홀 공격을 실행하여 해당 서비스의 Twilio API에 대한 액세스를 차단하면 실제로 어떻게 작동하는지 확인할 수 있습니다. 이를 통해 다음과 같은 많은 질문에 답할 수 있습니다: 메시지가 제대로 Queue에 들어가는가? 설정한 Timeout은 적절한가? 메시지 Queue가 증가해도 서비스가 계속 잘 수행되는가? 코드를 보고 이러한 질문에 대한 답을 추측하는 대신 실제로 실패를 주입하고 어떤 일이 발생하는지 확인할 수 있습니다.
이 경우 가설은 “네트워크 연결이 중단된 동안 메시지가 올바르게 Queue에 들어가고, 연결이 재개되면 메시지가 올바르게 전달된다.”일 수 있습니다. 블랙홀 공격을 실행하면 이 가설을 증명하거나 반증할 수 있습니다. 가설을 반증하면 시스템의 탄력성을 높이는 데 도움이 되는 몇 가지 사항을 배울 수 있습니다.
블랙홀 공격은 내부 종속성이 실패할 때 어떤 일이 발생하는지 확인하고 숨겨진 종속성을 발견하는 데에도 사용할 수 있습니다. 숨겨진 종속성은 흔히 발생하는 문제이며, 사건이 발생하기 전에 발견하는 것이 좋습니다. 숨겨진 종속성은 누군가 서비스에 새로운 종속성을 추가했지만 조직 내에서 문서화되거나 제대로 전달되지 않은 경우에 발생합니다. 예를 들어 서비스 A가 서비스 B에 종속되도록 업데이트되었지만 서비스 B를 운영하는 팀은 이를 알지 못합니다. 유지보수를 위해 서비스 B를 중단했는데 갑자기 서비스 A에 예기치 않은 중단이 발생하는 경우입니다. 서비스 A가 로그인 서비스처럼 중요한 서비스이거나 고객이 물건을 구매할 수 있는 서비스인 경우, 중단으로 인해 많은 비용이 발생할 수 있습니다. 서비스 종속성을 매핑하고 시각화하는 것이 어려울 수 있기 때문에 팀에서 이러한 문제를 겪는 것은 드문 일이 아닙니다.
서비스에 대한 블랙홀 공격을 주기적으로 실행하면 이러한 숨겨진 종속성을 드러내 관련 팀에서 이를 인지할 수 있습니다. 또한 외부 종속성에 대해 설명한 다른 이점도 얻을 수 있습니다. 종속된 서비스에 연결할 수 없게 되었을 때 서비스가 어떻게 반응하는지, 시간 초과 및 재시도가 적절하게 구성되었는지 등을 확인할 수 있습니다. Microservices 기반 분산 시스템은 네트워크 파티션을 어떻게 처리하나요? 블랙홀 공격을 통해 알아볼 수 있습니다.
5. 카오스 엔지니어링 결론
카오스 엔지니어링 을 정의하고 이를 통해 보다 탄력적인 Microservices 아키텍처를 구축하는 데 어떻게 도움이 되는지 보여드렸습니다. 또한 블랙홀 공격을 사용하여 서비스가 외부 및 내부 종속성 장애에 어떻게 대응하는지 살펴보는 방법에 대해서도 논의했습니다.
블랙홀 공격은 종속성 장애에 대한 서비스의 복원력을 확인하는 데 유용하지만, Microservices 환경에서 수행할 수 있는 다른 매우 유용한 실험도 있습니다. 호스트 종료, 지연 시간 또는 패킷 손실 추가, DNS 확인 중단, CPU 또는 메모리 사용량 추가 등은 모두 Microservices의 탄력성을 테스트하기 위해 할 수 있는 훌륭한 실험입니다.
NGINX Plus로 카오스 엔지니어링 을 사용해 보거나 테스트해 보려면 지금 30일 무료 평가판을 신청하거나 사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.