오픈소스 도전기(feat. Clymene 프로젝트, 공개SW 개발자 대회)

안녕하세요, 모니터링솔루션파트 allen입니다.

저는 약 2년 반 정도 열정을 가지고 오픈소스 개발을 하면서 다양한 어려움을 겪었습니다. 그러나 이제는 그만두어야 할 때라는 결심을 하게 되었습니다. 그동안 제가 겪었던 희노애락(喜怒愛樂)에 대해 말씀드리려 합니다.

오픈소스 개발을 하시거나, 하고 싶은 분들 중에서도 저와 같은 어려움을 느끼는 분들이 많을 것이라고 생각합니다. 제 이야기가 다른 개발자분들의 오픈소스 활동에 조금이나마 도움이 되기를 바랍니다.

오픈소스의 시작 - 아이디어

오픈소스 생태계에 기여를 하는 방법은 다양합니다. 개인적으로 직접 개발한 오픈소스를 많은 사람들이 사용하는 상상을 하며, 처음부터 손수 시작하고 싶다는 생각을 항상 했습니다. 그러나 이미 다양한 오픈소스들이 존재하기 때문에, 오픈소스 개발 과정 중에 아이디어를 얻는 것이 가장 어려웠습니다. 일반적으로 다른 사람들은 업무나 별도의 스터디를 통해 불편한 점을 해결하는 과정에서 아이디어를 얻는 것 같습니다.

저는 프로메테우스(Prometheus)의 원격 쓰기(Remote Write) 기능을 사용해서 여러 쿠버네티스(Kubernetes) 클러스터를 모니터링하는 모니터링 시스템을 구축해 보면서 프로메테우스의 몇 가지 단점을 알게 되었습니다. 그리고 이 단점들을 해결하고자 오픈소스를 시작하게 되었습니다.

call out
프로메테우스의 원격 쓰기(Remote write)는 송신자에서 수신자에게 데이터를 손실 없이 실시간으로 안정적으로 전파할 수 있도록 설계되었습니다. 원격 쓰기 기능을 사용하면 송신자가 전송한 데이터를 수신자 프로메테우스의 UI를 통해 데이터를 모니터하거나 PromQL을 사용하여 데이터를 조회할 수 있습니다. 원격 쓰기 구성을 튜닝하려면 원격 쓰기 튜닝(https://prometheus.io/docs/practices/remote_write/)을 참고합니다.
 

그림 1. 프로메테우스를 이용한 다중 클러스터 모니터링 시스템 예시

 

첫 번째, 프로메테우스의 원격 쓰기는 불필요하게 많은 리소스를 소모한다.

관측 대상 클러스터에서 실행되는 프로메테우스는 데이터를 수집해서 백엔드의 프로메테우스로 전송하는 역할을 합니다. 그러나 프로메테우스는 태생적으로 데이터 전송을 위해 개발된 것이 아니기 때문에 원격 쓰기 기능을 이용하더라도 시계열 데이터베이스 역할에 필요한 리소스를 소모합니다. (현재는 프로메테우스의 에이전트(Agent) 모드가 도입되었지만, 당시에는 없었습니다.)

 

두 번째, 프로메테우스는 스케일 아웃(scale-out)이 불가능하다.

기본적으로 프로메테우스는 단일 노드 아키텍처를 채택하고 있어, 스케일 업(Scale-up)만 가능합니다. 따라서, 모든 데이터는 단일 노드에 저장되어야 합니다. 이는 물리적 또는 가상 머신의 리소스 사용량이 한계에 도달하면 추가적인 성능 향상이 어려워집니다. 같은 이유로 데이터 샤딩(Sharding)을 할 수 없기 때문에, 데이터를 여러 노드에 분할 저장하거나 복제하는 기능을 제공하지 않습니다. 이에 따라 데이터를 저장하는 단일 노드에 장애가 발생하면 데이터 유실이 발생할 수 있습니다.

문제 분석

첫 번째 문제인 프로메테우스의 원격 쓰기 기능으로 발생하는 불필요한 리소스 소모 문제를 해결하기 위해, 프로메테우스 프로세스가 실행되어 데이터를 수집한 후 백엔드로 전송할 때 내부에서 동작하는 각 스레드의 동작을 분석하여 필요한 부분만 선별하도록 하였습니다. 

그림 2. 프로메테우스 스레드 별 동작

Config: 사용자가 작성한 설정 파일을 읽고 내용을 관리합니다. 프로메테우스는 설정 파일을 실행 중에 다시 읽는 리로드(Reload) 기능이 존재하여 스레드로 관리되고 있습니다.
 

Service Discovery: 설정 파일을 읽어 들여 시계열 데이터를 수집해야 하는 엔드포인트(Endpoint)를 찾고, 쿠버네티스 파드(Pod) 등의 증가로 새로운 관측 대상이 추가된다면 실행 중에 새로운 엔드포인트를 찾아주는 역할을 하는 스레드입니다.
 

Endpoint Scrape: Service Discovery를 통해 찾은 엔드포인트에 HTTP 요청으로 시계열 데이터를 주기적으로 수집하는 스레드 입니다. 

※ HTTP 응답으로 전달된 시계열 데이터의 raw 데이터를 프로메테우스에서 사용하는 형태로 파싱하면서 CPU를 많이 사용하고, CPU를 많이 사용되는 것을 방지하기 위해 한번 파싱한 데이터를 메모리에 캐싱합니다.
 

WAL(Write Ahead Logging): DBMS에서 많이 사용되는 아키텍처로 데이터베이스의 원자성(Atomicity)과 내구성(Durability)을 보장하기 위해 중요한 역할을 합니다. 변경 사항을 순차적으로 로그에 기재하고 특정 시간 후에 데이터를 블록화합니다. 
 

WAL Watcher: WAL 아키텍처의 일부로 WAL에 적재된 데이터를 TSDB에 적재합니다. 원격 쓰기 옵션이 켜져 있는 경우 원격 쓰기가 함께 실행됩니다.
 

TSDB: 시계열 데이터베이스의 핵심 부분으로 데이터를 수집, 저장, 처리하는 데 사용됩니다. 일부 데이터를 메모리에 보관합니다. 높은 쓰기 처리량과 효율적인 데이터 조회를 제공합니다.
 

Query: 프로메테우스의 쿼리 방식인 PromQL을 전달받아 처리하고 TSDB를 통해 데이터를 조회합니다.

 

스레드 별로 동작을 분석한 결과, 프로메테우스의 Config, Service Discovery, Endpoint Scrape 스레드만 분리하여 데이터를 엔드포인트에서 수집한 후에 백엔드로 데이터를 전송하는 방식을 도입한다면, 관측 대상에서 실행되는 프로메테우스의 원격 쓰기 기능 중 필요한 부분만 활용하여 보다 적은 리소스를 소모하는 시계열 데이터 수집 에이전트로 개발할 수 있다고 판단했습니다. 


두 번째 문제인 프로메테우스의 스케일 아웃이 불가한 아키텍처를 개선하기 위해서는 다양한 방법이 있을 수 있지만, 스케일 아웃이 가능한 다양한 데이터베이스에 적재할 수 있도록 저장 부분을 추상화하여 설정을 통해 저장소를 변경할 수 있도록 설계했습니다(유사한 오픈소스인 ThanosCortex는 그림 2의 프로메테우스의 스레드를 프로세스로 분리하여 스케일 아웃을 구현했습니다).

				
					type Factory interface {
   Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error


   CreateMetricWriter() (metricstore.Writer, error)


   CreateLogWriter() (logstore.Writer, error)
}

				
			
				
					type Writer interface {
   WriteMetric(metric []prompb.TimeSeries) error
}
				
			

위의 인터페이스 구현체는 Cortex, 엘라스틱 서치(Elasticsearch), Gateway(자체 컴포넌트), InfluxDB, 카프카(Kafka), Loki(로그만 사용 가능), OpenTsdb, 프로메테우스, TDengine으로 Agent를 통해 수집한 데이터를 다양한 데이터베이스에 저장할 수 있습니다. 따라서, 이미 사용 중인 데이터베이스를 지원하는 경우 해당 데이터베이스에 시계열 데이터를 저장하고 사용할 수 있으므로, 프로메테우스의  새로운 쿼리 언어인 PromQL을 배우지 않아도 됩니다.

오픈소스의 구현 - Clymene 프로젝트

문제 해결을 위한 설계와 몇 가지 추가적인 아이디어를 통해 오픈소스인 Clymene 프로젝트를 릴리스하게 됩니다. Clymene 프로젝트는 시계열 데이터 수집과 로그 수집, 두 가지 파이프라인을 가지고 있으며, 라인업 별로 세 가지의 컴포넌트가 존재합니다.

그림 3. Clymene 프로젝트 아키텍처 예시 1

에이전트(Agent)
데이터를 수집하는 컴포넌트입니다. 시계열 데이터를 수집하는 clymene-agent와 로그를 수집하는 clymene-promtail이 있습니다. 이러한 컴포넌트는 데이터를 수집하여 저장소에 저장하고, 수집한 데이터를 다른 컴포넌트에게 전달할 수 있습니다. gRPC/HTTP로 게이트웨이 컴포넌트에 전달하거나, 카프카를 사용해 데이터를 적재하여 인제스터(Ingester) 컴포넌트에게 데이터를 전달할 수 있습니다.

 

게이트웨이(Gateway)
Clymene 프로젝트의 컴포넌트로부터 gRPC/HTTP로 데이터를 전달받아 데이터를 처리하는 컴포넌트입니다. 시계열 데이터를 처리하는 clymene-gateway와 로그를 처리하는 promtail-gateway 컴포넌트가 있습니다. 다른 게이트웨이 컴포넌트에게 데이터를 전달하거나, 카프카와 저장소에 데이터를 적재할 수 있습니다.

 

인제스터(Ingester)
카프카에 적재된 데이터 처리하는 컴포넌트로 시계열 데이터를 처리하는 clymene-ingester와 promtail-ingester 컴포넌트가 있습니다. 게이트웨이 컴포넌트에 데이터를 전달하거나, 다른 카프카에 적재할 수 있으며, 저장소에 데이터를 적재할 수 있습니다.
 

추가 아이디어 – 합성 쓰기(Composite Write)
합성 쓰기는 수집하거나, 전달받은 데이터를 이기종의 저장소에 동시에 저장하는 기능입니다. 합성 쓰기를 이용해 수집한 데이터를 다른 리전으로 전달할 수 있습니다.

그림 4. Clymene 프로젝트 아키텍처 예시 2

파이프라인 별로 존재하는 컴포넌트를 블럭처럼 조립하여 다양한 아키텍처 구성이 가능합니다. 또한 합성 쓰기 기능을 이용해 유연하게 파이프라인을 구성할 수 있습니다. Clymene 프로젝트의 백엔드 컴포넌트는 모두 확장 가능한 아키텍처로 설계되었습니다. 따라서, 부하에 따라 스케일을 조정하여 고가용성의 아키텍처 구성이 가능합니다.

오픈소스의 꽃 - 홍보

계속 혼자서 개발하다 보니, 지체되는 경향이 있고 보다 많은 개발자분이 관심을 두고 함께 개발해 주기를 바라는 마음이 간절했습니다. 그리고 불현듯, “세상에서 제일 잘 만든 프로그램은 제일 많이 팔린 프로그램”이라는 말이 떠올랐습니다. 그 말은 즉, 가장 유명한 프로그램이 가장 잘 만든 프로그램이라고 생각이 들었습니다. 사실 깃허브(GitHub)에 검색을 해보면 오픈소스는 정말 많지만, 우리가 알고 있는 오픈소스는 극소수라는 것이 체감되었습니다. 이런 이유로 열심히 개발한 오픈소스를 알리려고 다방면으로 노력했습니다. 어떤 노력이 있었는지 소개하겠습니다.

공식 문서

개발에서 문서화는 매우 중요한 요소입니다. 문서화를 통해 해당 개발 구현체의 기능을 명확히 정리하고 사용 사례와 같은 설명을 제공해 다른 사용자들의 접근 가능성과 사용성을 높일 수 있기 때문입니다. 또한, 문서화는 사용자들이 해당 개발 구현체를 효과적으로 활용할 수 있는 기본 발판이 되어줍니다. 

오픈소스 개발을 진행하면서 실제 개발하는 시간만큼 문서화에 시간을 투자했습니다. 공식 문서의 존재는 홍보에도 큰 도움이 되었습니다.

그림 5. Clymene 프로젝트 공식 문서

SNS 홍보와 오프라인 발표

릴리스 할 때마다 가능한 많은 SNS에서 홍보를 했습니다. 다양한 사용 사례에 대한 글을 작성하여 사용자들에게 알리기 위해 노력했습니다. 스팸으로 간주되어 필터되는 경우도 많았고, 욕설을 받는 어려움도 있었습니다. 그래도 조금씩 성과를 얻을 수 있었습니다. 

첫 번째로, 깃허브의 스타 개수가 조금씩 늘어나는 것을 확인할 수 있었습니다, 한번 홍보를 할 때마다 5개 미만의 스타가 증가하는 것을 볼 수 있었습니다. 두 번째로, 오픈소스 프로젝트를 오프라인에서 소개할 수 있는 기회를 얻어 발표를 진행할 수 있었습니다.

처음 발표한 곳은 한국 쿠버네티스 코리아 그룹으로, 23년 2월 밋업에서 “오픈소스 Clymene-project를 이용한 k8s 모니터링 시스템 구축”이라는 제목으로 발표했습니다. 다양한 회사에서 많은 분이 참여해 주셔서 긴장되었지만, 처음 오프라인에서 제가 개발한 오픈소스를 소개한다는 것에 큰 설렘을 가지고 발표를 진행했습니다. Clymene 프로젝트를 시작하게 된 아이디어에 대해 생각보다 큰 관심을 주셨고, 프로메테우스를 사용하면서 비슷한 경험을 하신 분들이 많았습니다. Clymene 프로젝트를 이용해서 다중 쿠버네티스 클러스터의 모니터링 시스템 구축 방법에 대해 소개했습니다. 

사진 1. 한국 쿠버네티스 코리아 그룹 밋업에서의 발표 모습

 다음으로 발표한 곳은 아파치 드루이드(Apache Druid) 그룹입니다. 23년 3월 밋업에서 “오픈소스 Clymene-project와 Druid를 이용하여 모니터링 시스템을 구축하는 방법”이라는 제목으로 발표했습니다. Clymene 프로젝트는 프로메테우스 생태계의 다양한 Exporter를 이용해서 아파치 드루이드에 데이터를 적재할 수 있습니다. Clymene 프로젝트와 아파치 드루이드를 이용해서 모니터링 시스템을 구축하는 방법에 대해 소개했습니다.

사진 2. 아파치 드루이드 밋업에서의 발표 모습

공개SW 개발자대회

더 많은 곳에 Clymene 프로젝트를 소개하고자, 매년 진행되는 과학기술정보통신부 주최, 정보통신산업진행원 주관의 공개SW 개발자대회에 출품했습니다. 1차 서면 평가와 2차 오프라인 발표 평가를 진행하고 기능 검증, 라이선스 검증 과정을 통해 심사가 진행되었습니다. 홍보하고 싶은 마음에 출품하였으나, 운이 좋게도 입상할 수 있었습니다. 오픈소스 대회에 생각한 것보다 정말 많은 개발자분이 참여하신 것을 보고, 저 또한 다시 한번 개발에 대한 열의를 불태울 수 있었던 것 같습니다.

사진 3. 2022년 공개SW개발자대회

오픈소스의 끝

2년 반 정도 정말 열정을 가지고 Clymene 프로젝트와 함께했던 것 같습니다. 홍보하면서 기회를 얻은 발표 자리에서 느낀 설레임과 공개SW개발자대회 입상 시 느낀 기쁨들은 정말 이루말로 표현할 수 없을 정도로 벅찬 기쁨과 설렘이었던 것 같습니다. 그런데도 서두에서 말씀드렸던 것과 같이 이제는 놓아주어야 할 때가 온 것 같은 생각이 들곤 합니다. 그 이유로는 처음 시작할 때와는 다르게 프로메테우스 진영에서도 Clymene 프로젝트와 같은 생각을 했고 에이전트 모드를 릴리스했습니다. 내부적인 로직도 데이터 전송 실패에 대한 로직을 제외하고는 유사하게 구현되어 있다 보니, 프로메테우스의 원격 쓰기 대비해서 리소스 소모량이 압도적으로 적었던 Clymene-agent이지만, 현재 프로메테우스 에이전트 모드와 비교하면 유사하게 리소스를 소모합니다. 사실상 Clymene 프로젝트의 가장 큰 장점을 잃어버린 것 같았습니다. 또한 유사한 상황이라면 사용자들은 당연히 기존에 사용하던 것을 그대로 사용하는 쪽을 택하게 되는 것 같습니다.

더해서, 시계열 데이터를 스케일 아웃이 가능한 타 데이터베이스에 저장하는 것에 대해 설계 당시에 예상했던 것보다 사용자분들의 니즈가 없는 것 같습니다(분명 필요한 경우가 있으리라 생각하지만, 극소수에 불과한 것 같습니다). 스케일 아웃이 필요한 경우 Thanos나 Cortex를 이용해서 백엔드를 구성하여 사용하는 쪽을 택하는 것 같습니다.

이런 이유로 이제는 Clymene 프로젝트를 놓아주어야 하나 생각을 하고 있습니다. 하지만, 그동안 함께한 세월과 희로애락이 있기 때문에 쉽게 놓아주지 못하고 있습니다. 마지막으로 시계열 데이터와 로그 수집 파이프라인을 구성할 수 있는 오픈소스답게 시계열 데이터와 로그를 잘 정제하여 기계학습을 통해 의미 있는 데이터를 만들어 낸다면 어떨까? 라는 아이디어를 구현해 볼 생각입니다.

끝으로

오픈소스 프로젝트를 개발하면서 직접 겪은 희로애락을 가감 없이 공유해 봤습니다. 앞으로도 언제든지 재미있는 오픈소스 주제가 있다면 열정을 쏟을 각오가 되어 있습니다. 개발자로서 오픈소스를 향한 갈증이 항상 있기 때문입니다. 언제든지 재미있는 주제가 있다면 이야기 나눌 수 있으면 좋겠습니다. 그리고 앞으로도 건강한 개발할 수 있으면 좋겠습니다. 감사합니다.

참고

카카오톡 공유 보내기 버튼

Latest Posts

제5회 Kakao Tech Meet에 초대합니다!

Kakao Tech Meet #5 트렌드와 경험 및 노하우를 자주, 지속적으로 공유하며 개발자 여러분과 함께 성장을 도모하고 긴밀한 네트워크를 형성하고자 합니다.  다섯 번째

테크밋 다시 달릴 준비!

(TMI: 이 글의 썸네일 이미지는 ChatGPT와 DALL・E로 제작했습니다. 🙂) 안녕하세요, Kakao Tech Meet(이하 테크밋)을 함께 만들어가는 슈크림입니다. 작년 5월에 테크밋을 처음 시작하고,