Skip to main content

클라우드 엔지니어를 위한 97가지 조언

ghdwlsgur
Blog Owner

이 책은 작년 중순 지인으로부터 추천받아 읽어 보게 된 책인데 제목 그대로 클라우드 엔지니어에게 피와 살이 되는 내용들로 구성되어 있어 블로그에도 남길까 한다. 목차 이름 또한 해당 단락을 압축하여 한 문장으로 지은 듯한 느낌이 들고 97가지의 목차가 있다. 각 조언을 목차로 구성하고 조언에 관한 내용을 스토리로 구성하여 읽으면서도 지루할 틈이 없었다.

책 내용은 잠시 뒤로하고 문득 내가 왜 엔지니어로 일하고 있을까라는 생각을 다시 한 번 하게 된다. 개발에 이어서 AWS를 통한 인프라 진입까지 내가 엔지니어로 직무를 희망하게 된 건 아마 시스템에 대한 이해가 무지한 코린이 시절 윈도우를 사용하면서 겪은 트러블을 해결하기 위해 많은 시간을 할애한 덕분이 아닐까 생각이 든다. 애초에 나는 매뉴얼은 그저 매뉴얼대로만 참고하거나 흐름만 살펴본 뒤 이것 저것 클릭하면서 진행하였는데 이러니 당연히 에러를 많이 만날 수 밖에. 트러블 슈팅을 하기 위해 애플리케이션 단에만 머무르는 것이 아니라 시스템을 이해하기 위해 물리 및 네트워크 계층까지 자연스레 공부를 하게 되었다.

호기롭게 플랫폼을 개발하여 사업을 해보겠다는 꿈은 어느새 클라우드 엔지니어로 성장하고 성공하고 싶다는 꿈으로 자연스레 바뀌었던 것 같다.


아마도 내겐 이 도서가 성공한 클라우드 엔지니어로 가기 위한 길잡이 역할이 되지 않을까하여 97가지 조언 중 의미있는 조언들만 모아 정리하고자 한다.

  • 관리형 서비스를 사용하자, 제발
  • 서비스를 생각하지 말고 기능을 생각하라
  • 컨테이너는 마법이 아니다
  • 여러분의 CIO는 단 한 번의 플랫폼 재구축을 원한다
  • 분산 시스템 시각화를 연습하라
  • 확장할 요소를 알아야 한다
  • 쿠버네티스를 사용하지 않아도 괜찮다
  • 클라우드 프로세싱은 속도가 전부가 아니다
  • 사람들이 클라우드에 올바른 기대를 갖도록 돕자
  • 프로덕션에 SSH하지 말기
  • 클라우드 환경이 온프레미스에 있는 것처럼 다루자
  • 신원을 확인하지 않으면 정보 보안 권한을 획득할 수 없다
  • 의심될 때는 테스트하라
  • 단일 의존성은 절대 안 된다
  • 게임 데이로 인프라를 테스트하라
  • 시각화와 대시보드로 모니터링을 개선하라
  • SRE의 모든 R을 다시 살펴보기
  • 리스크 관리를 위해 체크리스트를 사용하라
  • DNS가 모든 문제의 원인: 증명하고 개선할 방법
  • 모델 의존성을 모니터링하라
  • 개발 환경이라는 것은 존재하지 않는다
  • 탄력성과 확장성이 핵심이다
  • 신뢰할 수 있는 시스템은 우연히 만들어지지 않는다
  • 삽질은 무엇이며 SRE가 집착하는 이유
  • 더 적게 일하도록 노력하자
  • 모든 것은 0과 1이다
  • 반복에 대비하라
  • 거대한 재작성을 피하자
  • 빌어먹을 짐! 난 클라우드 엔지니어지 회계사가 아니라고!
  • 인프라를 소프트웨어처럼 취급하자
  • 클라우드에서도 네트워크가 기초다
  • 비용이 아닌 여러분 조직에 집중하자
  • 클라우드 엔지니어링은 컨테이너가 아닌 문화다
  • 시스템을 계속 동작하게 하는 것의 중요성
  • 문서를 읽어라, 다시 읽어라
  • 계속해서 호기심을 가지자

이 중 내게 크게 와닿은 스토리는 두가지가 있는데 그 중 하나는 DNS가 모든 문제의 원인: 증명하고 개선할 방법이다. 이 단락 스토리의 주인공은 깃랩 디벨로퍼 에반젤리스트인 마이클 프리드리히다. 웹 사이트에 접근할 수 없다면 DNS 문제일까? 클라이언트가 방화벽이나 프록시 뒤에서 콘텐츠를 받으려고 하는 특정한 장소와 연관되어 있을 수 있다. 더 깊이 있는 분석(수사)이 필요하다. 고객이 연락할 때마다 형사가 되기는 어려운 일일 것이다.

고객이 연락할 때마다 형사가 되기는 어려울 일일 것이다.

이 문장에 매우 동감한다. 사실 서비스를 제일 잘 이해하고 있는 것은 고객일 것인데 문제가 발생할 때마다 문제 해결을 위해서 많은 시간이 필요하기도 하며 내 관리 범위 밖에서 발생하는 문제들도 내게 해결책을 제시하는 고객들도 있기 마련인데 매우 난처하다.

마이클 프리드리히는 문서와 구글이 당신의 최고 친구다라고 하며 다른 사람이 말하는 '빌어먹을 매뉴얼을 좀 읽어"는 잊으라고 한다. 문서는 항상 첫 번째 진입점이 되어야 하며 친절한 개발자가 문제 해결 항목을 작성해 두었을 수도 있고, 직면한 문제를 설명한 페이지 링크를 찾을 수도 있다.

아래는 마이클 프리드리히의 조언들이다.

  • 같은 팀의 동료를 찾고 도움을 요청하라.
  • 동료에게 현재 진행 사항을 모두 공유하라.
  • 사고의 흐름에 따라서 발생하는 문제들을 기록하자.
  • 가능하다면 문제를 처리하고 있는 여러분의 화면을 공유하고 짝으로 디버깅을 진행하라.
  • 네트워크 경로를 함께 분석하고 DNS 추적에 대해 더 많이 알아가자.
  • 문제를 격리하고 여러 부분으로 나누어 영향받을 대상을 줄이는 전략을 적용하자.
  • 화려한 도구에 의존하지 말자.
  • find, grep, sed, awk를 셸에서 사용하는 것에 익숙해지자.

find, grep, sed, awk를 셸에서 사용하는 것에 익숙해지자.

위 명령어를 깊게 파헤치는 내용들도 포스팅해봐야겠다.

  • 프로덕션에서 무엇인가 수정해야 한다면 변경 사항을 문서화하고 팀원들에게 문제를 알려라.
  • 이 시간 동안에는 다운타임 모니터링과 알람 수준을 조절해서 온콜이 쏟아지는 것을 피하자.
  • VM, 컨테이너, CI/CD 작업에서 서로 다른 리눅스 배포판을 사용하는 것을 계속 연습하자.
  • 배포될 때마다 분산 모니터링과 관측성을 최우선으로 해야 한다.
  • 필요한 메트릭, 트레이스, 상태만 확인하자.
  • 모든 것을 수집하지 말자.

모든 것을 수집하지 말자.

이 문장도 크게 와닿았는데 모든 로그를 수집하여 모니터링에 활용하게 되면 물론 다양한 메트릭을 구축할 수는 있겠지만 로그는 계속해서 쌓이고 모든 로그가 모니터링에 활용되는 것은 아니기 때문에 비효율적이게 된다. 모니터링 또는 트러블 슈팅에 활용할 로그만 수집해도 로그를 쌓는데 들어가는 스토리지 비용은 엄청 감소하게 된다.

  • 전략을 문서화하고 팀 내 전파하자.
  • 사고와 장애를 학습 기회로 삼아라.
  • 여러분의 환경을 카오스 테스팅으로 실전 테스트하는 전략을 개발하라.

사고와 장애를 학습 기회로 삼아라.

난 트러블 슈팅하는 과정을 모두 기록하고 왜 문제가 일어났는가에 대한 의구심 해결을 학습 목표로 정하고 이 과정에서 만나는 문제들을 샅샅이 파헤치는데 이러한 기록들이 내가 성장하는 데 엄청 큰 비료가 된다. 이 기록의 공유를 통해 팀원과의 시너지를 도모하고 다음 번에 동일한 상황이 발생했을 경우에 더 빠른 대응과 신속한 조치를 가능하게 하기도 한다.


마지막 스토리는 전에 내가 전혀 듣지도 알지도 못했던 내용이기에 신선한 충격으로 다가왔다. 이 스토리의 주인공은 ASX 컨설팅 주식회사 이사인 윌 딘이다. 목차 제목은 클라우드 환경의 사이드 채널과 은닉 통신으로 먼저 사이드 채널이 무엇인가에 대해 알아보자.

사이드 채널(side-channel) 공격은 시스템 그 자체를 직접 대상으로 하지 않고 시스템을 처리하는 과정에 유출된 정보를 악용하는 공격이다. 전력, 전자기장, 음향, 열, 타이밍의 분석이 공격 가능한 사이드 채널이다. 역사적으로 사이드 채널 공격은 주로 암호화 시스템을 노려 왔다. 하이퍼바이저와 클라우드 컴퓨팅의 도입으로 최근 연구는 대체로 CPU 캐시 타이밍 기술을 사용하는 가상 머신 간 사이드 채널 공격에 집중하고 있다. 사이드 채널 공격은 일반적으로 느리고 단편의 데이터 복구만 가능함에도 암호 키를 탈취하여 네트워크로 연결되지 않은 협력 시스템 간의 은닉 채널을 생성하는 복잡한 공격이 퍼블릭 클라우드에서도 가능하다고 알려졌다.

2009년 캘리포니아 대학교와 메사추세츠 공과대학교의 연구자들이 아마존 EC2에 공격 대상 가상 머신과 동일한 물리 호스트에 공격자 가상 머신을 위치시키는 기술을 시연하는 논문을 발표, 동일 호스트에 배치된 가상 머신 간의 비밀 채널을 하드디스크와 메모리 버스의 경합 타이밍을 이용해서 저대역폭의 비밀 채널 만들기 등 기본적인 사이드 채널 공격 등을 선보임

2017년에는 오스트리아의 그라츠 공과대학교에서 CPU 캐싱 타이밍을 이용한 45Kbps 대역폭의 부분적인 비밀 채널 생성 방법을 발표, TCP 스택을 은닉 채널상에 구현해서 채널을 통해 뮤직비디오를 스티리밍하는 시연을 블랙햇 아시아에서 선보였다.

해결책

퍼블릭 클라우드에서 민감한 워크로드를 구동하는 경우 모든 주요 IaaS 업체에서는 전용 하드웨어를 사용할 수 있으며 전용 하드웨어를 사용해서 공격자가 사용자의 가상 머신과 동일한 서버에 존재할 가능성을 없앨 수 있다.

조직은 퍼블릭 클라우드를 사용하는 시스템에서 사이드 채널 및 은닉 통신 공격 위협에 반드시 주의해야 한다. 그리고 이러한 위협을 수용할 것인지 또는 단독 테넌시 하드웨어 사용에 추가적인 비용을 지불할 것인지를 결정해야 한다.

인텔 커피 레이크 및 스카이레이크 프로세서에서 부채널을 악용해 민감한 데이터를 훔치는 연구에서도 공격자는 피해자 프로세스의 메모리 액세스로 인한 대역폭 용량의 포화로 발생한 악성 프로세스와 관련된 메모리 액세스의 지연을 측정할 수 있었으며 비록 스파이 프로세스가 개인 캐시인 L1-L2에서는 누락되게 되므로 마지막 캐시 레벨인 LLC 슬라이스에 로드하여 링 경합을 발생시켜 LLC의 메모리 로드의 반복적인 지연 시간을 부채널로 사용함으로써 취약한 EdDSA 및 RSA 구현에서 키 비트 누출하고 공격 대상 사용자가 입력한 키 입력의 정확한 타이밍을 추출하여 암호를 재구성할 수 있습니다.

이로 미루어 볼 때 개인 캐시 영역인 L1-L2에는 접근할 수 없고 대부분의 부채널 공격은 접근이 가능한 마지막 캐시 레벨인 LLC를 통해 채널을 구성하여 씨크릿 정보를 재구성하거나 탈취하는 것을 알 수 있습니다.


이를 이해하기 위해서는 캐시가 동작하는 원리를 정확하게 이해할 필요가 있어 캐시가 동작하는 아주 구체적인 원리에서 잘 설명된 글을 정독 후 내용을 정리하였습니다.

CPU의 속도에 비해서 하드는 너무 느리기 때문에 하드와는 소통하지 않습니다. CPU는 램과 소통하는데 우리가 어떤 프로그램을 실행할 때 그 데이터는 램으로 이동하고 CPU는 그 데이터를 가져옵니다. 하지만 램도 CPU에 비하면 많이 느리기 때문에 CPU 내부나 근처에 캐시메모리를 만들어 그곳에 데이터를 저장합니다. 캐시 메모리는 램에 비하면 용량이 작습니다. 그렇기 때문에 중요하다고 판단되는 데이터만 저장해서 사용합니다.

cache1

캐시메모리는 레벨 1부터 레벨 3까지 단계를 나누어 사용합니다. 레벨 1캐시는 CPU가 가장 먼저 접근하는 메모리로 속도가 가장 빠르지만 용량은 작습니다. 레벨 3 캐시는 용량이 큰 대신에 속도는 느립니다. CPU는 우선 L1 캐시에 데이터를 요청하고 여기에 없으면 L2 캐시에 데이터를 읽습니다. 여기에도 없으면 레벨 3 캐시에 데이터를 읽어고 여기에도 없으면 RAM에 있는 데이터를 읽게 됩니다.

cache2

컴퓨터에 있는 기억장치는 하드, 램, 캐시, 레지스터가 있습니다. 레지스터는 CPU 내부에서 데이터를 일시적으로 저장하는 장소로 속도가 가장 빠른 메모리입니다.

cache3

아래로 내려갈 수록 속도는 빠르지만 용량이 작고 가격도 비싸집니다. 레지스터 종류에는 프로그램 카운터, 메모리 주소 레지스터, 메모리 버퍼 레지스터, 명령어 레지스터가 있습니다.


CPU Cache 특성

  • 메인 메모리는 CPU에 비해 느리다.
  • 캐시 버퍼는 대게 자주 사용하는 데이터이다.
  • 모든 데이터 액세스는 캐시를 거칩니다.
  • 캐시는 OS와 소프트웨어에 투명합니다.

L1 및 L2 캐시 계층은 비공개이지만 마지막 레벨 캐시는 슬라이스로 나뉘어져 있고 여러 코어에서 공유하며 해시 함수의 경우 물리적 주소를 이 나뉘어진 슬라이스에 매핑합니다. 공격자는 이 특성을 유용해서 사이드 채널을 구축합니다.

즉, 캐시 공격은 메모리 액세스의 타이밍 차이를 악용한 공격입니다.

공격자는 콘텐츠가 아닌 피해자가 액세스한 캐시 세트를 알고 있으며 마지막 레벨 캐시가 공유되므로 CPU 코어 전체에서 작동하고 공유 메모리이므로 메모리 중복 제거가 필요하지 않습니다.

공격 과정은 다음과 같습니다.

사이드 채널을 사용하여 공격자는 먼저 캐시를 차지 및 점유하고 피해자는 자신도 모르게 공격자가 이미 점유한 캐시에 데이터를 로드합니다. 공격자는 캐시 세트에 피해자가 데이터를 로드하였는지 확인하기 위해 캐시를 지속적으로 확인하고 로드한 데이터를 갈취하여 씨크릿 정보를 탈취하게 됩니다.

cache4