JuHyung Son

View Original

클라우드 네이티브 프로메테우스 가이드

쿠버네티스 환경에서 뭔가를 개발해 본 사람이라면 프로메테우스를 한번 쯤은 봤을겁니다. 프로메테우스는 모니터링과 알람을 위한 툴로, 모니터링 스택에 꼭 들어가는 오픈소스이고 요즘엔 메트릭 수집의 표준 스택이 되었습니다. 최근에 모니터링 스택에서 독보적인 지위를 누리고 있어 떠오르는 별처럼 보이지만, 사실 2012년에 Sound Cloud에서 개발되어 2016년에 CNCF 프로젝트에 들어가게 된 오래된 프로젝트입니다.

프로메테우스

프로메테우스는 크게 프로메테우스 서버, exporter, alertmanger로 구성됩니다. 

  1. 서버는 메트릭을 수집해 타임시리즈 DB에 저장, Promql로 데이터를 보내주는 역할을 합니다.

  2. exporter는 모니터링하고자 하는 대상의 메트릭을 서버가 가져갈 수 있게 모아두는 역할을 합니다. 주목할 점은 exporter가 직접 데이터를 보내는 것이 아니라 메트릭을 수집하며 프로메테우스 서버가 당겨가길 기다린다는 점입니다.

  3. alert manager는 말그대로 알람을 관리합니다. 알람 설정을 저장하고 알람을 감지합니다.

프로메테우스의 아키텍쳐에서 가장 눈여겨 봐야할 것은 서버가 exporter의 데이터를 pull 해간다는 것입니다. Exporter는 단지 /metrics 엔드포인트를 가진 http 서버일 뿐입니다. 이 구조로 프로메테우스 서버는 트래픽에 대한 고려없이 많은 대상을 모니터링할 수 있게 됩니다. 프로메테우스 서버가 수집한 데이터는 TSDB에 저장되며 promql을 사용해 쿼리를 보낼 수 있습니다.

프로메테우스 사용방식

먼저 쿠버네티스 환경이 아닌 일반적인 환경에서 프로메테우스를 사용하는 방법을 봅시다. 프로메테우스의 가장 기본적인 모니터링 기능을 위해서는 exporter와 프로메테우스 서버가 배포되어야 합니다. exporter는 모니터링할 대상(어플리케이션, 노드)에 배포되고 프로메테우스 서버는 모니터링을 진행할 노드에 배포됩니다. 프로메테우스 서버가 어떤 exporter 들에서 데이터를 당겨올지는 설정파일에 정의합니다. Config 링크

모든 서버들에 어플리케이션마다 exporter를 실행하고 그 exporter의 주소를 config에 넣어 매번 재실행해주어야 하니 아주 번거롭습니다.

그럼 클라우드 네이티브 환경에서는 어떻게 하는지 봅시다. 일단 클라우드 네이티브한 환경의 정의는 좀 복잡하지만, 간단하게 모든 것을 쿠버네티스 위에서 운영한다고 합시다.(참고) 쿠버네티스 환경에서는 보통 프로메테우스 오퍼레이터를 사용하여 운영합니다. 보통 오퍼레이터는 관리자 혹은 사용자가 수동으로 해야하는 것들을 자동으로 해주는 하나의 컴포넌트입니다. 그럼 프로메테우스 오퍼레이터는 온프레미스 환경에서 수동으로 해줘야했던 것들을 자동으로 해준다고 생각하면 됩니다. 새 어플리케이션에 exporter를 붙이고 config를 수정해주는 것과 같은 것이죠. 이것만으로 프로메테우스를 운영하는 수고는 엄청나게 줄어듭니다.

쿠버네티스에서 프로메테우스 설치는 여러가지 방법이 있겠지만, 공식 헬름 차트를 통해 설치하고 관리하는 것이 좋습니다. (링크) 헬름 차트는 여러가지 버전이 배포되고 있고 알아서 오퍼레이터를 설치해주기 때문에 따로 오퍼레이터를 설치하지 않아도 됩니다. 심지어 오퍼레이터 웹페이지도 있죠. (링크)

헬름 차트로 프로메테우스를 설치하면 ServiceMonitor, PodMonitor라는 CRD도 설치가 됩니다. 이 CRD는 쿠버네티스에서 프로메테우스를 편하게 사용하는데 핵심적인 역할을 합니다. ServiceMonitor는 말그대로 서비스들의 모니터링을 설정하는 crd이고 PodMonitor는 파드를 모니터링하는 설정입니다. 이 설정들만 kubectl 을 통해 생성하면 프로메테우스 서버를 건드릴 일 없이 모니터링 타겟이 추가됩니다.

See this content in the original post

쿠버네티스 클러스터에 새로운 파드를 띄웠고 파드안에 exporter 역할을 하는 컨테이너가 있다면,파드와 함께 서비스 모니터만 띄우면 됩니다. 그러면 프로메테우스 오퍼레이터가 이 CRD를 보고 프로메테우스의 config를 바꾸어 다시 로딩하고, 프로메테우스는 이 파드의 exporter의 메트릭을 수집하게 됩니다. 서비스가 달린 파드라면 서비스모니터를 사용하고 서비스 없이 파드로만 구성되어있다면 파드 모니터링을 사용하게 됩니다.

프로메테우스는 꽤 오래된 프로젝트라 조금 아쉬운 면이 몇 개 있습니다. 그 중 하나는 데이터 저장방식인데요. 특히 쿠버네티스 위에서 사용할땐 여러가지 방법으로 세팅할 수 있습니다. 프로메테우스는 기본적으로 메모리 혹은 프로세스가 떠 있는 노드의 디스크에 데이터를 저장합니다. 하지만 데이터를 무한정 저장할 수는 없으니, 특정 용량이나 특정 기간까지의 데이터만 저장하고 오래된 데이터는 삭제하는 방식을 사용하고 있습니다..

먼저 쿠버네티스 환경에서 메모리에 데이터를 저장하는 방식은 굳이 보지 않아도 안좋은 방법입니다. 파드가 어떤 이유로 재실행되면 그동안의 데이터가 모두 날라갈 뿐더러 많은 양의 데이터를 저장하기도 힘듭니다. 또한 노드의 디스크를 쓰는 방식 역시 좋지 않습니다. 파드는 재실행될 수 있지만, 항상 같은 노드에서만 스케줄링이 되어야 합니다. 만약 노드에 문제가 생기면 역시나 그동안의 데이터를 다 날려버리는거죠. 

결국 데이터를 어떻게 안전하게 관리하느냐가 쟁점인데요. 온프레미스 환경에서 데이터를 비교적 안전하게 관리하려면 Longhorn 과 같은 블록 스토리지를 사용할 수도 있고 클라우드를 사용할 수 있다면 EBS와 같은 클라우드 서비스가 제공하는 블록 스토리지를 사용할 수도 있습니다. 그런데 이 두 방법으로도 해결하지 못하는 문제는 데이터 저장 용량에 한계가 있다는겁니다. 큰 디스크를 설치하거나 클라우드에 큰 스토리지를 요청해 받을 수도 있지만, 어쨋든 용량은 한정되어 있고 큰 용량을 사용하면 처음부터 괜히 비용만 많이 쓰게 됩니다. 

또 다른 큰 문제는 확장성입니다. 만약 모니터링해야하는 타겟들이 많아지고 프로메테우스에 들어가는 쿼리들도 많아지면 프로메테우스 서버는 부하가 걸리게 됩니다. 아쉽게도 프로메테우스는 왜인지는 모르겠지만, 확장성에 취약하게 만들어졌습니다. (아마 10년전에 만들어져서?) 그런데 하나의 프로메테우스로는 모자라 두개의 프로메테우스가 필요하다면 어떻게 될까요. 두개의 프로메테우스 서버는 쿼리를 처리하는 일은 반으로 줄겠지만, 메트릭은 중복으로 수집하게 됩니다. db에 똑같은 데이터가 두개씩 쌓이죠. 각각의 서버가 서로 겹치지 않는 메트릭을 수집하게 해야합니다. 쿠버네티스 환경에서 자동으로 오토스케일링되며 타겟도 알아서 나누기란 쉽지 않아보입니다.

이런 프로메테우스를 현대 소프트웨어 환경에서도 잘 쓸 수 있도록 한 것이 타노스 입니다. 고가용성과 장기간 데이터 보존이 가능한 프로메테우스 셋업이라고 홍보하고 있죠. 타노스 역시 CNCF 프로젝트에 들어가게 되었는데 왜 프로메테우스를 개선해 2.0으로 만들지 않고 타노스가 나왔는지는 모르겠네요. 타노스는 프로메테우스의 기능을 쪼개서 쿼리 처리, 메트릭 수집, 데이터 저장 하는 컴포넌트를 분리하고 데이터는 오브젝트 스토리지에 저장하게 해 효율적인 비용으로 데이터를 장기간 쌓을 수 있도록 했습니다. 타노스에 대한 자세한 소개는 다음 포스트에서 하는 것으로 하고 여기서는 타노스가 프로메테우스를 쿠버네티스 환경에서 사용하기 아주 좋게 만들었다. 정도로만 소개하겠습니다.