Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

npm에 새로 추가된 audit 기능

npm v6가 나오면서 npm audit이라는 기능이 추가되었다. 이는 사용하는 npm 모듈의 취약점을 검사해주는 Node Security Platform(보통 nsp 명령어로 사용한다)를 npm, Inc가 인수하면서 NSP의 데이터베이스를 이용해서 취약점을 점검해 주는 기능을 추가한 것이다. 이번에 npm audit이 npm v6뿐만 아니라 v5.10.0에도 추가되면서 6으로 올리지 않더라도 사용할 수 있게 되었다.

이제는 GitHub에서도 취약점 경고를 해주지만 Node 생태계에 특화된 NSP쪽이 데이터베이스가 좀 더 풍부하고 빠른 것으로 보인다.(GitHub이 어디의 데이터를 사용하는지 모르지만, GitHub은 JavaScript만 지원해야 하는 것은 아니라..)

npm audit

npm을 쓰면서 크게 불편을 느끼진 않아서 버전이 올라갈 때마다 달라진 기능을 일일이 보진 않지만 새로운 기능이 나와서 사용해 봤다.

일단 기존 npm이 5.6.0이라서 최신 버전 6.0.1로 업데이트를 했다.

$ npm -v
5.6.0

$ npm install -g npm
+ npm@6.0.1
added 156 packages, removed 37 packages and updated 17 packages in 134.362s

$ npm -v
6.0.1

현재 작업 중인 사이드 프로젝트에서 실행을 해봤다.

$ npm audit

                       === npm audit security report ===

# Run  npm install --dev nodemon@1.17.4  to resolve 1 vulnerability
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ deep-extend                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ nodemon [dev]                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ nodemon > chokidar > fsevents > node-pre-gyp > rc >          │
│               │ deep-extend                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/612                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ pkg [dev]                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ pkg > pkg-fetch > request > hawk > boom > hoek               │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ pkg [dev]                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ pkg > pkg-fetch > request > hawk > cryptiles > boom > hoek   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ pkg [dev]                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ pkg > pkg-fetch > request > hawk > hoek                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ pkg [dev]                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ pkg > pkg-fetch > request > hawk > sntp > hoek               │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘

[!] 5 vulnerabilities found - Packages audited: 6825 (2068 dev, 123 optional)
    Severity: 1 Low | 4 Moderate

결과가 보기 쉽게 나오고 의존성을 업데이트한 지가 그리 오래되지 않아서 많은 취약점이 나오진 않았다. 낮은 심각도의 취약점이 1개 중간 심각도의 취약점이 4개 발견되었다. nodemon에서 사용하는 deep-extend에서 취약점이 있고 nodemon@1.17.4로 업데이트하면 이 취약점을 해결할 수 있다고 나온다.

하단에 나오는 Manual Review는 취약점은 발견되었지만, 아직 패치가 존재하지 않아서 신경 써야 한다는 의미이다. 문서에 따르면 이렇기는 한지 위 결과에서 나온 pkg안에 포함된 hoek을 보면(hoek만 4개 나온 것은 hoek이 4개 포함되었기 때문이다.) Patched in에서 > 4.2.0 < 5.0.0 || >= 5.0.3라고 나와있다. 이는 4.2.0보다 크고 5.0.0보다 작은 버전이나 5.0.3이상인 버전에서는 패치되었다는 의미이다. 버그인지 데이터베이스 업데이트가 느린 것인지 모르지만 이미 패치가 되었는데 왜 Manual Review로 나오는지는 잘 모르겠다.

$ npm install

added 900 packages from 1012 contributors in 12.728s
[!] 5 vulnerabilities found [6825 packages audited]
    Severity: 1 Low | 4 Moderate
    Run `npm audit` for more detail

추가로 이제는 npm install을 할 때 취약점 검사도 함께 해주고 결과를 알려주므로 설치할 때 참고해서 볼 수 있다.(설치 시에 검사하지 않으려면 --no-audit 옵션을 사용해야 한다.) 그리고 audit 명령어는 npm-shrinkwrap.jsonpackage-lock.json 파일이 있어야만 사용할 수 있다. package-lock.json의 충돌이 귀찮아서 사용하지 않고 있다면 npm i --package-lock-only 등으로 package-lock.json을 만들어야 audit을 사용할 수 있다.

                       === npm audit security report ===


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Denial of Service                                            │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ http-proxy-agent                                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ karma [dev]                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ karma > log4js > mailgun-js > proxy-agent > http-proxy-agent │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/607                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


# Run  npm install --dev parcel-bundler@1.8.1  to resolve 1 vulnerability
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ deep-extend                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ parcel-bundler [dev]                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ parcel-bundler > chokidar > fsevents > node-pre-gyp > rc >   │
│               │ deep-extend                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/612                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


# Run  npm update log4js --depth 2  to resolve 16 vulnerabilities
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ karma                                                        │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ karma > log4js > slack-node > requestretry > request > hawk  │
│               │ > boom > hoek                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


# Run  npm install mocha@5.1.1  to resolve 2 vulnerabilities
SEMVER WARNING: Recommended action is a potentially breaking change
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ debug                                                        │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ mocha                                                        │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ mocha > debug                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/534                       │
└───────────────┴──────────────────────────────────────────────────────────────┘

npm 의존성을 업데이트한 지 좀 된 프로젝트에서도 한번 돌려봤다. 여기서는 훨씬 많은 취약점이 발견되었는데 그중 몇 개만 위에 올렸다. 위 결과를 보면 그냥 취약점을 보고해 주는 부분도 있고 상단에 어떤 명령어를 실행하면 취약점을 해결할 수 있는지까지 알려주고 있다. 그리고 모듈을 업데이트해서 취약점을 해결할 때 호환성이 깨진 업데이트가 있으면 SEMVER WARNING: Recommended action is a potentially breaking change라고 알려주고 있다.

위 결과를 보다가 전혀 사용해 보지 않은 옵션이 보여서 궁금해졌다.

  • npm install --devdevDependencies만 설치하라는 의미이다. 패키지가 지정되어 있어서 굳이 여기서 필요한가 싶지만... 이 --dev 옵션은 지금은 폐기되었고 --only={prod[uction]|dev[elopment]}와 같이 써야 한다.
  • npm update log4js --depth 2 같은 경우는 package.json의 버전 규칙에 따라 업데이트를 하지만 현재는 최상위 모듈만 업데이트하고 있다. --depth 옵션을 주면 해당 계층까지 검사해서 최신 버전으로 올려준다.

개발단계에서는 크게 신경 쓰지 않아도 되지만 프로덕션에 나가는 코드에서는 의존성 관리는 중요한 부분이므로 audit이 기본으로 포함되어 CI나 배포 전 단계에 검사하기가 좋아졌다.

2018/05/12 22:45 2018/05/12 22:45

[Book] Chaos Engineering

Chaos Engineering

Chaos Engineering Chaos Engineering - Building Confidence in System Behavior through Experiments - 8점
Casey Rosenthal
Lorin Hochstein
Aaron Blohowiak
Nora Jones
Ali Basiri


최근 인프라에 관심을 가지면서 인프라에 대한 접근방법에 대해서 많이 보고 있다. 각 도구나 기술 외에 최근 관심을 가지는 큰 화두 중 하나는 SRE(사이트 신뢰성 엔지니어링 참고)이고 다른 하나는 이 Chaos Engineering이다.

얼마 전 SRE 책을 보고 요즘 공부하고 있기는 하지만 대규모 시스템에서 마이크로 서비스 아키텍쳐가 상당히 복잡해져서 기존의 접근 방법으로 해결되지 않는 문제들을 해결하기 위해 Google의 해결방법은 SRE이고 Netflix의 해결방법은 Chaos Engineering이라고 생각하고 있다.(물론 이 책을 보다 보니 Netflix에도 SRE가 있었다.) 둘 다 실용적인 접근 방법이라고 생각해서 관심이 있고 Chaos Engineering은 Korea Chaos Engineering Community에도 참가하면서 배우고 있다.

Netflix에서 공개한 Principles of Chaos Engineering(한글 번역)와 넷플릭스 마이크로 서비스 가이드 - 혼돈의 제왕에도 잘 나와 있지만 좀 더 자세히 보고 싶어서 이 책을 읽었다. 원서이지만 72페이지로 양이 많지 않고 읽기에도 그리 어렵지는 않다.

이 책을 읽는다고 카오스 엔지니어링을 도입한다거나 실제로 어떻게 하는지 바로 알기는 어렵다. 이 책은 카오스 엔지니어링의 도구를 자세히 다루거나 실제로 실험하는 방법을 구체적으로 알려주는 책이라기보다는 Principles of Chaos Engineering를 더 자세하게 설명한 책에 가깝다. 그래서 카오스 엔지니어링의 원리를 좀 더 자세히 설명하고 넷플릭스가 해왔던 일을 추가로 소개하면서 조직 내에 카오스 엔지니어링을 도입하는 자세 등을 설명하고 있다. 각 도구의 사용법이나 실제 실험 설계 등은 더 공부해야겠지만 카오스 엔지니어링이 무엇이고 어떤 접근 방법인지 이해하는 데는 괜찮은 책이라고 생각한다. 카오스 엔지니어링의 도입을 고민할 때 참고하기 위해서 간단히 정리했다.

1부 소개

Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the system’s capability to withstand turbulent conditions in production. - Principles of Chaos Engineering

분산 시스템을 운영해 봤다면 예기치 않은 상황이 발생한다는 것을 알 것이고 모든 장애를 막을 수는 없지만, 최소한 문제가 생기기 전에 시스템에서 어느 부분이 약한지는 찾아낼 수 있다. 약한 점을 찾아내면 이를 고쳐서 장애가 발생하기 전에 막아서 시스템을 더 회복력 있고 신뢰성 있게 만들 수 있다.

Chaos Engineering is a method of experimentation on infrastructure that brings systemic weaknesses to light.

카오스 엔지니어링은 시스템의 취약 부분이 드러나게 만드는 인프라스트럭처의 실험 방법의 하나다. 카오스 엔지니어링은 서비스에 혼란을 주는 것이 아니라 복잡한 시스템에 필연적인 혼돈(chaos)를 표면에 드러나게 하는 것이다.

1장 왜 Chaos Engineering을 하는가?

Chaos Engineering is an approach for learning about how your system behaves by applying a discipline of empirical exploration.

카오스 엔지니어링은 경험적인 조사의 훈련을 적용해서 시스템이 어떻게 동작하는지 배우는 접근 방법이다. 카오스 엔지니어링을 적용하면 시스템의 회복성이 향상할 수 있다.

카오스 엔지니어링과 실패 주입(fault injection), 실패 테스트(failure testing)는 관심사와 도구가 크게 겹치지만, 카오스 엔지니어링이 다른 접근방법과 가장 다른 점은 새로운 정보를 생산하는 방법이다. 반면 실패 주입은 한 상태를 테스트하는 특정 접근방법이고 실패 테스트는 미리 생각한 방법으로 시스템을 깨뜨리지만 예상치 못한 것을 찾아내지는 않는다. 테스트는 단언문(asserrtion)을 만들어서 특정 상태의 출력이 true인지 false인지 결정하는 것이지만 실험은 새로운 지식을 생성하고 때로는 조사의 새로운 길을 제안한다는 것이 둘의 가장 큰 차이점이다.

현재 조직이 카오스 엔지니어링을 도입할 준비가 되어있는지 결정하려면 "시스템이 서비스 장애나 네트워크 지연 같은 리얼월드 이벤트에 회복성이 있는가?"라는 질문에 먼저 대답해 보아야 한다. 만약 이 대답이 "아니오"라면 카오스 엔지니어링을 적용하기 전에 이 부분부터 해결해야 한다. 먼저 취약한 부분을 수정한 뒤 카오스 엔지니어링을 적용하면 몰랐던 다른 취약점을 찾아낼 수 있을 것이다. 카오스 엔지니어링의 또 다른 핵심 요소는 모니터링 시스템이다. 모니터링 시스템으로 시스템의 현재 상태를 알 수 있고 이러한 모니터링이 없다면 실험의 결론을 얻어낼 수 없을 것이다.

2장 복잡도 관리

Complexity is a challenge and an opportunity for engineers.

소프트웨어 엔지니어는 보통 성능, 가용성, 장애 허용(fault tolerance) 세 가지 속성을 최적화한다. 여기서 성능은 지연이나 용량 비용을 최소화하는 것이고 가용성은 시스템이 응답하면서 다운타임을 피하는 것이며 장애 허용은 원치 않은 상태에서 시스팀에 회복하는 능력을 말한다. Netflix의 엔지니어는 기능 개발의 속도(velocity)라는 네 번째 속성도 고려한다. 속도는 엔지니어가 새롭고 혁신적인 기능을 고객에게 제공하는 속도를 얘기한다. 카오스 엔지니어링은 회복성 검증으로 팀과 시스템이 높은 속도, 실험, 신뢰성을 가질 수 있도록 지원한다.

전에는 아키텍트가 시스템의 모든 부분을 이해할 책임이 있었지만, 어느 정도 규모의 분산 시스템에서는 사람이 이 역할을 맡을 수 없을 정도로 너무 복잡해졌다. 마이크로 서비스 아키텍처에서는 사람의 이해 가능성을 희생시켜서 속도와 유연성을 얻었다. 이 이해 가능성의 부족이 카오스 엔지니어링에게는 기회가 되었다.

2부 카오스의 원리

The performance of complex systems is typically optimized at the edge of chaos, just before system behavior will become unrecognizably turbulent. - Sidney Dekker, Drift Into Failure

카오스 엔지니어링을 훈련으로 보고 있고 특히 실험적인 훈련으로 생각하고 있다. 이론적이고 예언적인 모델이 없으므로 시스템이 특정 상황에서 어떻게 동작할 것인지 이해하려면 반드시 경험적인 접근방법을 사용해야 한다.

상세 원리는 다음과 같다.

  • 안정된 상태에 대한 가설 세우기
  • 리얼월드 이벤트 변경하기
  • 프로덕션에서 실험하기
  • 지속해서 실행되도록 실험 자동화하기
  • 폭파 반경 최소화하기

3장 안정된 상태에 대한 가설 세우기

받아들일 수 있는 시스템 동작과 원치 않는 시스템 동작을 구분할 방법이 필요하다. 시스템의 정상적인 운영을 안정된 상태(steady state)라고 부른다. 서비스를 직접 확인해서 안정된 상태인지 확인해 볼 수 있지만, 차선책이 되어야 한다. 더 좋은 접근 방법은 시스템의 상태 정보를 제공하는 데이터를 수집하는 것이다. Netflix에서는 비디오 스티리밍을 시작하는 시간(SPS, start per second) 매트릭 정보를 수집하고 CPU 사용량 증가보다 SPS를 줄이는데 더 관심이 있다. 매트릭을 선택할 때는 "매트릭과 기반 구성의 관계", "데이터를 수집하는데 필요한 엔지니어링 노력", "매트릭과 시스템에서 진행 중인 동작 간의 지연 시간"의 균형을 고려해야 한다.

비즈니스 매트릭의 기댓값에 기반을 두고 시스템의 안정된 상태의 특징을 규정하는 모델을 개발하는 것이 우리의 목표이다. 카오스 실험을 할 때는 언제나 실험의 결과가 어떻게 되기를 기대하는지 가설을 염두에 두어야 한다. 매트릭을 수집하고 안정된 상태에 대해 이해를 했다면 실험의 가설을 정의하는데 이를 사용할 수 있다. 시스템에 다른 타입의 이벤트를 주입하면 안정된 상태의 동작이 어떻게 달라질지와 안정된 상태에서의 변화를 어떻게 측정할지 생각해 봐라.

4장 리얼월드 이벤트 변경하기

가용성에 대한 위협을 차단하는 것을 불가능하지만 완화할 수는 있다. 장애의 영향과 격리의 범위를 장애 도메인(faiulre domain)이라고 부른다. 시스템에 근본 원인 이벤트를 주입하면 리소스 공유로 인해 발생하는 장애 도메인이 드러난다. 보통 해당 리소스가 공유되어 있다는 것에 팀은 놀란다. 마이크로 서비스 아키텍처에서 가장 중요한 장애 도메인 중 하나가 "서비스" 그룹이다. 자신들의 서비스가 중요하지 않다고 생각하는 팀은 장애가 부적절하게 격리되었기 때문에 서비스 중단을 발생시킨다.

많은 팀이 중요 개발 단계에서 FIT(Failure Injection Testing)의 이점을 활용하고 있지만, 아직 광범위하고 잦은 이용을 하지는 않는다. Fit으로 회복성을 향상하는 강력한 도구를 갖게 되었지만, 아직 도입 문제도 남아있다.

5장 프로덕션에서 실험하기

우리 분야에서 프로덕션 환경에서 소프트웨어를 검증한다는 생각은 보통 조롱을 받게 된다. 전통적인 테스트에서 일반적으로 퍼진 생각은 가능한 한 프로덕션에서 먼 곳에서 버그를 찾는 것이 좋다는 것이다. 카오스 엔지니어링에서는 이 전략이 반대가 된다. 가능한 한 프로덕션 환경과 가까운 곳에서 실험하기를 원한다. 이상적으로는 모든 실험을 프로덕션 환경에서 직접 실행하는 것이다. 카오스 엔지니어링 실험을 실행할 때 시스템 전체 동작에 관심이 있다. 코드가 시스템의 중요한 부분이지만 시스템에는 코드 외에도 훨씬 많은 것이 있다. 마이크로 서비스 아키텍쳐에서 "상태"를 이야기 할 때는 보통 데이터베이스 같은 "상태를 가진 서비스"를 얘기한다.

소프트웨어 엔지니어가 배우기 가장 어려운 교훈 중 하나는 시스템의 사용자가 결코 원하는 대로 시스템을 사용하지 않는다는 것이다. 시스템의 신뢰를 실제로 만드는 유일한 방법은 프로덕션 환경에서 실제 받는 입력으로 실험해 보는 것이다. 시스템이 AWS나 Azure 같은 클라우드 환경에 배포되어 있다면 시스템이 의존하고 있지만, 완전히 이해하지는 못하는 외부 시스템이 존재한다. 회사의 데이터센터에서 시스템을 운영하고 있더라도 DNS, SMTP, NTP 등 프로덕션에서 의존하고 있는 외부 서비스가 여전히 있다. 카오스 실험을 프로덕션에서 직접 실행하지 않는다면 상태, 입력, 다른 사람의 시스템, 에이전트의 변경 등 이번 장에서 논의한 이슈는 모두 카오스 실험의 외부 유효성에 대한 잠재적인 위협이 된다.

시스템이 주입하려는 이벤트에 회복력을 가졌는지 자신감이 적당히 없어서 프로덕션에서 카오스 실험을 수행하는데 망설이고 있다면 시스템이 아직 카오스 엔지니어링 실험을 할 만하지 않다는 강력한 경고 신호이다. 카오스 엔지니어링의 주요 목적 중 하나는 시스템에서 취약한 부분을 찾아내는 것이다. 이미 취약한 부분이 있다고 생각한다면 시스템의 회복성을 향상하는데 집중해야 한다. 시스템에 회복성이 있다고 생각한다면 그때 카오스 실험을 실행해라. 시스템에 회복성이 있다고 자신감이 있을 때 조차도 실험이 취약한 부분을 드러내면서 너무 큰 손해를 끼칠까 봐 두려워서 카오스 엔지니어링 실험을 하기 주저할 수도 있다. 이는 합당한 걱정이고 우리가 씨름하고 있는 문제이다. 우리의 접근 방법은 다음 두 가지 방법으로 잠재적인 손해를 최소화하는 것이다.

  • 실험을 중단하기 쉽게 만든다.
  • 실험의 폭파 반경을 최소화한다.

미래에 시스템이 상당한 중단을 겪는 것을 막기 위해 작은 손해의 위험을 감수하는 것이 더 낫다.

6장 지속해서 실행되도록 실험 자동화하기

수동으로 실행하거나 일회성 실험을 하는 것도 첫 단계로 아주 좋다. 성공적으로 실행을 수행했다면 다음 단계는 지속해서 실행할 수 있도록 실험을 자동화하는 것이고 실험을 자동화하지 않으면 퇴화한다. 이상적으로는 실험을 카오스 카나리처럼 변경사항마다 실행해야 한다. 소프트웨어 엔지니어가 정기적으로 카오스 실험을 수동으로 실행하는 데 시간을 소비해서 개발 속도를 희생하지 않도록 해야 한다. 대신 새로운 카오스 실험을 만들고 자동으로 실행할 수 있는 장벽을 계속해서 낮추는 카오스 실험 도구와 플랫폼 개발에 투자하고 있다.

이러한 문제를 해결하려고 2016년 말에 카오스 자동화 플랫폼(Chaos Automation Platform, ChAP)을 런칭했고 ChAP를 지속적 배포 도구인 Spinnaker와 통합해서 마이크로서비스가 새로운 코드를 배포할 때마다 카오스 실험을 실행할 수 있게 되었다.

카오스 엔지니어링 실험 설계의 도전적인 부분은 프로덕션을 깨뜨린 것이 무엇인지 찾아내는 것이 아니다. 이 정보는 우리의 사건·사고 추적기의 데이터가 가지고 있다. 프로덕션을 깨뜨리지 말아야 하는 이벤트와 이전에는 프로덕션을 깨뜨린 적이 없는 이벤트를 찾아내는 것이 우리가 원하는 것이다. 그리고 이러한 것이 여전히 유효한지 검증하도록 실험을 계속해서 설계하고 있다.

7장 폭파 반경 최소화하기

프로덕션의 위험을 이해하고 완화하는 것은 카오스 엔지니어의 책임이다. 실험하기에 잘 설계된 시스템은 일부 고객만 약간의 불편을 겪도록 함으로써 프로뎍선이 크게 중단되는 일을 막을 것이다. 여러 면에서 실험으로 알 수 없고 예상치 못한 장애의 영향을 찾고 있으므로 의도치 않게 모든 것을 날려 버리지 않고 이러한 취약 부분을 찾아내는 것이 핵심이다.

가장 위험이 낮은 실험은 일부 사용자만 포함한다. 이를 달성하려고 디바이스의 일부나 작은 그룹에 클라이언트 디바이스의 기능을 검증하는 장애를 주입한다. 자동화된 실험이 성공하면 소규모 확산 실험을 실행한다. 소규모 확산 실험의 이점은 스레스홀드를 넘지 않아야 하므로 단일 요청의 폴백과 타임아웃을 검증할 수 있다는 것이다. 이는 일시적인 오류에 대한 시스템의 회복력을 검증할 수 있다. 다음 단계는 소규모 집중 실험을 실행하는 것이다. 이 실험의 모든 사용자 요청 라우팅을 오버라이딩해서 특정한 부분으로 트래픽을 바로 보낸다.

종료를 자동화하는 것을 강력하게 권장한다. 실험이 다른 원리에 따라 지속해서 실행되는 경우에 특히 필요하다.

우리는 모두가 사무실에 있고 일할 준비가 되어 있는 업무 시간에만 실험을 실행한다.

3부 실전 카오스

8장 실험 설계

과정을 정리하면 다음과 같다.

  1. 가설을 고른다.

    • 테스트할 가설이 무언인지 결정해야 한다.
  2. 실험의 범위를 선택한다.

    • "프로덕션에서 실험하기"와 "폭파 반경 최소화하기" 원리를 여기서 적용한다.
  3. 감시할 메트릭을 구분한다.

    • 실험의 결과를 평가하는데 사용할 메트릭을 선택해야 한다.
    • 메트릭을 이용해서 가능한 한 가설을 많이 조정해 봐야 한다. 예를 들어 "메인 데이터베이스가 실패해도 모든 것이 괜찮아야 한다."가 가설이라면 "괜찮다"를 정의해야 한다.
  4. 조직내에 알린다.

    • 프로덕션 환경에서 카오스 실험을 처음 시작할 때 조직내에 무엇을 언제 할 것이고 왜 하는지 알려주어야 한다.
  5. 실험을 실행한다.
  6. 결과를 분석한다.

    • 실험이 끝나면 수집한 메트릭을 사용해서 가설이 맞는지 확인한다.
  7. 범위를 넓힌다.

    • 소규모 실험에서는 발견하지 못한 시스템 영향이 드러날 수 있도록 실험의 범위를 넓힌다.
  8. 자동화한다.

9장 카오스 성숙도 모델

카오스 엔지니어링의 정의를 형식화해서 언제 하는지, 잘하고 있는지 어떻게 더 잘할 수 있는지를 알 수 있게 했다. 카오스 성숙도 모델(Chaos Maturity Model, CMM)은 조직 내 카오스 프로그램의 상태를 파악할 방법을 제공한다. CMM에는 정교함(sophistication)과 도입(adoption) 두 가지 메트릭이 있습니다. 정교함이 없다면 실험은 위험하고 신뢰할 수 없으면 유효하지 않을 수도 있다. 도입되지 않는다면 영향이 없을 것이다.

프로그램의 정교함을 이해하면 조직 내 카오스 실험의 유효성과 안전성을 알 수 있다. 정교함을 초급 단계, 간단한 단계, 고급 단계, 정교한 단계로 나눌 수 있다.

  • 초급 단계

    • 실험을 프로덕션에서 실행하지 않는다.
    • 과정을 수동으로 관리한다.
    • 결과가 비즈니스 메트릭이 아니라 시스템 메트릭에 반영된다.
    • "종료해라" 같은 간단한 이벤트를 실험 그룹에 적용한다.
  • 간단한 단계

    • 실험을 프로덕션과 유사한 트래픽으로 실행한다.
    • 알아서 서비스를 설정하고 실행을 자동화하고 수동으로 모니터링하고 실험을 종료한다.
    • 결과가 종합된 비즈니스 메트릭에 반영된다.
    • 네트워크 지연 같은 확장된 이벤트를 실험 그룹에 적용한다.
    • 실험을 정적으로 정의했다.
    • 도구가 실험과 제어의 비교 히스토리를 지원한다.
  • 정교한 단계

    • 실험을 프로덕션에서 실행한다.
    • 설정, 자동화된 결과 분석, 수동 종료를 자동화했다.
    • 실험 프레임워크가 지속적 배포 도구와 통합되어 있다.
    • 실험그룹과 제어 그룹 간에 비즈니스 메트릭을 비교한다.
    • 서비스 계층의 영향이나 조합된 장애 같은 이벤트를 실험 그룹에 적용한다.
    • 결과를 시간에 따라 추적한다.
    • 도구가 실험과 그룹의 비교를 인터렉티브하게 지원한다.
  • 고급 단계

    • 모든 환경의 각 배포 단계마다 실험을 실행한다.
    • 설계, 실행, 조기 종료가 완전히 자동화되어 있다.
    • 잡음을 줄이기 위해 프레임워크가 A/B나 다른 실험 시스템과 통합되어 있다.
    • 사용 패턴을 변경하거나 응답이나 상태를 변경하는 등의 이벤트를 포함한다.
    • 주요 변곡점을 찾기 위해 실험이 동적인 범위와 영향을 가진다.
    • 실험 결과에서 수익 손해를 산출할 수 있다.
    • 실험 결과에서 용량 예측을 할 수 있다.
    • 실험 결과가 서비스 용량에 따라 달라진다.

도입은 카오스 실험 커버리지의 깊이와 범위를 측정한다. 도입이 더 잘 되었다면 더 많은 취약점을 드러내고 시스템에 더 높은 신뢰성을 준다.

  • 그림자 속에 있는 단계

    • 연구 개발 부문의 프로젝트는 수용하지 못한다.
    • 일부 시스템만 포함한다.
    • 조직에서 인식이 없거나 낮다.
    • 초기 도입자가 가끔 카오스 실험을 실행한다.
  • 투자 단계

    • 실험이 공식적으로 받아들여졌다.
    • 실행에 파트타임 리소스를 전용으로 사용한다.
    • 여러 팀이 관심 있고 사용한다.
    • 일부 중요 서비스가 가끔 카오스 실험을 실행한다.
  • 도입 단계

    • 카오스 엔지니어링의 실행을 전담하는 팀이 있다.
    • 회귀 실험을 만들기 위해 문제의 응답이 프레임워크에 통합되었다.
    • 가장 중요한 서비스가 정기적으로 카오스 실험을 수행한다.
    • 문제의 응답이나 "게임 데이"로 가끔 실험 검증을 한다.
  • 문화적으로 기대하는 단계

    • 모든 중요 서비스가 자주 카오스 실험을 한다.
    • 중요하지 않은 대부분의 서비스가 자주 카오스를 사용한다.
    • 카오스 실험이 엔지니어 온보딩 과정에 포함되어 있다.
    • 시스템 컴포넌트는 참가하는 게 기본 동작이고 참가하지 않으려면 정당한 이유가 필요하다.
2018/05/09 03:29 2018/05/09 03:29