2021년 12월 말부터, 2022년 3월 말에 이르기까지 3개월 동안 진행했던 프로젝트가 끝났다. 수습 기간 이후에 특정한 목표를 가지고 장기간 진행하여, 기간 내에 끝을 낸 프로젝트는 처음이라 회고 글을 적고자 한다.
프로젝트의 목표와 기술 스택
사내에서 운영되는 애플리케이션과, API들을 Amazon Kubernetes(EKS) 환경 위로 이전하기 시작했다. EKS 환경 위에서 애플리케이션에서 만드는 로그들을 일괄적으로 Fluent Bit, Fluentd로 수집하여 Elasticsearch와 S3으로 보냈는데,
- 사용자 로그와 시스템 로그가 분리되지 않아 Elasticsearch에 부담이 간다.
- 사용자 로그의 파싱이 기존 로그의 형식처럼 파싱되지 않아 개발자들이 보기에 불편하다.
- 한 로그가 여러 개의 로그로 나뉘어 인식된다.
- 기존에는 로그 수집 프로그램 → SQS를 통해 메시지 큐로 로그를 보내 로그를 안정적으로 수집하였는데, 현재의 EKS 위의 로그 수집 체계에는 외부 버퍼가 없다.
는 문제점이 있었다.
따라서 나의 목표는
- 사용자 로그와 시스템 로그를 분리
- 사용자 로그를 각 로그별로 합치고 파싱
- 외부 버퍼(메시지 큐) 연결
작업을 수행하는 것이었다.
로그 수집 프로그램
EKS 환경 위에서 Fluent Bit, Fluentd 가 세팅되어 있었지만, 기존에 사내에서 로그를 수집하던 프로그램은 Logstash였다. 그래서 3개의 로그 수집 프로그램 중에 뭘 사용할지 선택할 수 있는 상황이었는데, Logstash의 경우 메모리를 1G 가까이 소모하고, Fluentd의 경우 200mb, Fluent Bit가 25mb를 소모하기 때문에 가장 경량화된 버전인 Fluent Bit로 원하는 기능들을 구현할 수 있는지 테스트를 했었고, 구현이 되었기 때문에 메모리 대비 성능을 따져 Fluent Bit를 선택했다.
사용자 로그, 시스템 로그 분리
Fluent Bit에서는 특정 위치에 있는 로그에 태그를 붙여, 해당 태그의 로그만 특정 필터를 적용하거나 특정 아웃풋으로 내보낼 수 있다. 따라서 사용자 로그인 app, exception 로그와 시스템 로그(Fluent Bit에서는 워커 노드의 /var/log/containers 하위에 쌓인다)에 별도의 태그를 붙이고 로그를 처리했다.
쿠버네티스
쿠버네티스 환경은 이미 서버에 세팅이 되어 있었지만, EKS 환경 위에서 로그를 수집하는 Fluent Bit 애플리케이션을 만들기 위해서는 쿠버네티스의 작동 원리와 쿠버네티스 환경 위에서 파드를 생성하는 방법을 알아야 했다. 다행히 쿠버네티스 공식 문서의 한국 번역이 잘 되어 있어서 도움을 많이 받았지만, 사내의 도서 구매 지원으로 <쿠버네티스 인 액션>, <쿠버네티스 완벽 가이드>를 구매해 애플리케이션을 만드는 데 필요한 여러 설정 파일이 어떤 역할을 하는지, 애플리케이션에서 남기는 로그를 Fluent Bit에서 받아오기 위해서는 폴더 마운트를 어떻게 해야 하는지, 쿠버네티스의 메타데이터 어떤 정보를 메타데이터로 받아올 수 있는지 등등을 알 수 있었다.
공식문서와 깃허브
Fluent Bit의 경우 공식 문서의 도움을 가장 많이 받았다. Tail input, Kubernetes FIlter, Kinesis Output 파트를 10~20번은 읽은 것 같다. 두세 번만 보고서도 필요한 기능을 다 파악하고 짠짠 하고 완벽한 설정을 해냈다면 매우 좋았겠으나, 7-8개월 차인 신입은 매번 같은 문서를 봐도 새로운 게 보였다.
Fluent Bit 공식 깃허브의 이슈를 검색하는 것도 굉장히 도움이 되었다. 이슈에는 내가 겪은 문제점들을 그대로 경험한 과거의 사람들이 남긴 글과, 해결 방법이 있었다. 막히는 부분이 있어도 포기하지 않고 계속 사람들이 인터넷에 남긴 흔적을 검색하고, 공식 문서와 깃허브 이슈를 정독한 결과, 오픈 소스인 Fluent Bit에 원하는 기능이 없거나 제대로 기능이 작동하지 않을 때의 해결책을 알 수 있었다.
답이 없는 경우엔 내가 직접 깃허브 이슈에 해당 문제를 제보하기도 했다. 회사에서 오픈 소스를 사용하면서 몇몇 기능이 안 된다고 글을 올리는 것에 대해 많은 생각이 들었는데, 언젠가는 나도 Fluent Bit 같은 오픈 소스에 기여하고 싶다.
정규식, 파싱
Fluent Bit는 쿠버네티스에서 로그가 쌓이는 기본 경로가 아니면 쿠버네티스 메타정보를 읽어오지 못하는 문제점이 있는데(2022.02 기준), 생성되는 애플리케이션 파드에 쿠버네티스 파드, 네임스페이스와 같은 항목을 환경변수로 세팅해두고 이를 로그 파일 이름 혹은, 로그 자체에 추가하면 해당 정보를 정규식을 사용해 파싱할 수 있다. 덕분에 개발자들이 키바나에서 로그를 조회할 때 편하게 애플리케이션의 컨테이너 네임이나 네임스페이스 정보를 추가할 수 있었다.
- Fluent Bit에서 특정 경로의 로그 파일 받아와 쿠버네티스 메타데이터 추가하기
- Remove last n characters using Regex & Fluent Bit
- Using Lua filter to find if log matches a pattern, and remove last n characters.
메시지 큐(버퍼) 연결
처음에는 기존에 사내에서 사용하는 SQS를 사용하기 위해 방법을 찾아봤는데, Fluent Bit/Fluentd용 오픈 소스 SQS output 플러그인이 존재하나 제대로 작동하지 않았다.
대안으로 Kinesis Data Streams, Kinesis Firehose를 알아보았는데, 처음엔 이 둘의 개념도 굉장히 헷갈렸으나 각 잡고 둘의 특성과 차이점을 정리하자 머릿속에 팀 내에 두 서비스의 차이점도 잘 설명할 수 있는 정도가 되었다. (Kinesis Data Streams는 실시간으로 메시지를 수집할 수 있는 스트리밍 서비스이고, Consumer가 데이터를 읽어올 수 있다. 샤드로 메시지를 처리할 수 있는 용량을 확장할 수 있다. 반면 Kinesis Firehose는 최소 60초 단위로 로그를 받아올 수 있는 배치성 데이터 처리 서비스이며, 목적지(S3, Amazon Elasticsearch, Http... ) 등으로 데이터를 바로 보낸다.)
Kinesis Data Stream이 실시간으로 로그를 처리하긴 좋았으나, 비용 문제로 Kinesis Firehose를 써야 하나 싶었는데, 팀 내에서 실시간 로그 수집을 중요하게 여겨 Kinesis Data Streams를 사용하게 되었다.
주의할 점은, Fluent Bit의 경우 aws-for-fluent-bit 이미지로 Kinesis Data Stremas/ Firehose output을 사용할 수 있지만, 현재(2022.03 기준, 이미지 버전 2.23.2 기준)으로도 로그 수집이 완벽하게 되지는 않고 중복/손실이 있을 수 있다는 것이다.
따라서 다음에는 카프카를 도입해 로그 수집 시 데이터 손실이나 중복이 없도록 개선해 나가고 싶다.
배우거나 얻은 점
정말 많은 것들을 배웠다... 일단 일에 임하는 자세를 혼나면서...ㅋㅋㅋ 많이 배웠다. 너무 기본적일 수도 있지만, 작업하면서 정리했던 것들을 공유해보자면,
- 시간을 들여 무언가를 찾아보고 해결책을 알아내, 적용하는 자세와 방법
- 확신 없는 것에 너무 매달리지 말고, 빨리 확인하고 넘어가야 일을 빨리 할 수 있다는 것
- 추측하지 말고 확실히 로그를 보거나, 물어봐서 원인을 파악할 것.
- AWS 환경에서는 AWS 개발자 문서를 가장 우선하고 관련된 모든 문서를 찾아볼 것.
- 내가 할 수 있는 일을 확실히 알고 먼저 테스트한 후 다른 분께 질문/요청하기.
- 앞의 작업부터 확실히 다 하고 뒤의 작업으로 넘어가야 한다는 것
- 문제가 생기면 팀 내 공유와 논의가 무엇 보다 우선되어야 한다는 것
- 공유할 때는, 상대가 잘 파악할 수 있도록 그림이나 아키텍처, 코드를 첨부할 것
- 작업할 때 개별 작업만 볼 것이 아니라 전체적인 흐름과 구조를 볼 것
- 무언가 오류 메시지가 뜨고, 그걸 해결할 때에는 이게 확실히 뭘 의미하는지 알아보고, 어떤 영향을 미치는지, 부작용은 없는지 찾아볼 것
- 무언가 문제가 있으면 충분한 검색과 서칭을 통해 해결책과 대안을 제시할 수 있을 것
- 무언가를 처음 해볼 때는 충분한 시간을 들여 체크리스트를 만들고 확인하여 일을 두세 번 하지 말 것.
나의 시간뿐 아니라 다른 사람의 시간도 소모된다.
프로젝트 기간의 노력과 삽질을 통해, 적어도 사내에서는 내가 Fluent Bit를 제일 잘 안다... 고 말할 수 있을 것 같다. 아직 모르는 것도 많고, 써본 것만 알고, 구글링에 많이 의존해야 되지만 그래도 그간 노력을 꾸준히 했으니까. 시간을 들여 부딪히고 두드려 보았으니까.
프로젝트 중에 Kinesis Firehose와 Kinesis Data Streams가 로그를 충분히 처리할 수 있나? 하고 테스트를 해보는데, 어떤 깃허브 이슈를 통해 수십 가지의 조건으로 테스트를 해 보고 이슈를 공유한 사람을 보면서 ‘와 나도 저렇게까지 해 봐야겠다.’ 하고 20, 30가지 이상의 조건으로 테스트를 해 봤다. 덕분에 해당 환경에 대해서는 확실히 특정 조건에선 어떻다고 말할 수 있게 되었다.
또한, 새로운 것을 배우는 건 때로는 두렵지만 재밌을 수 있고, 원하는 목표물을 만들고 나면 뿌듯하다는 걸 알게 되었다. 자바를 1도 모르는데, 이번 프로젝트에서 '로그를 찍는 애플리케이션'을 만들기 위해서 자바+스프링부트로 조건에 따라 3개의 다른 로그를 파일로 남기는 애플리케이션을 만들기 위해 유튜브와 공식문서 등을 보면서 아예 모르는 영역을 배웠다. 하루 이틀 만에 할 수 있었으면 좋았겠으나..ㅎㅎ 일주일은 걸린 것 같다. 다행히 시간이 지날수록, 원하는 바에 가까이 구현할 수 있었고, 원하는 기능이 구현되면 너무너무 뿌듯했다.
쿠버네티스에 대해서도 흥미가 생겨, 쿠버네티스 스터디를 모집해 기초부터 차근차근 시작해 나갈 예정이다. 먼저 도커부터 시작하기로 했다. ㅎㅎ 언젠가 CKA도 딸 수 있기를!
그리고 이 모든 것들을 알려준 사수님께 무한 감사하다. 이렇게 배운 것들을 체득하고 다음 프로젝트는 더 빨리, 잘 해낼 수 있었으면 좋겠다. 회사에 어엿한 1인으로 기여하고 싶다.
마무리
이번에 개발자나 엔지니어는 무엇보다 ‘호기심이 있어야 하는구나’ 하는 걸 느꼈다. 호기심이 있어야 문제가 생겼을 때 궁금증을 가지고 원인을 파악하고, 팀 내에서 커뮤니케이션 할 때도 상황의 겉뿐만 아니라 근본적인 원인을 이해할 수 있을 것이다. 사실 나에겐 아직 부족한 항목인데, 의식적으로 무언가를 마주할 때 ‘왜?’ 하는 물음을 항상 가져야겠다.
이 프로젝트를 마무리하면서 9개월 차가 되었다. 벌써 9개월이나 되었다니.. ㅎㅎ 시간이 참 빠르고 무섭기도 하다. 1년, 2년 차 엔지니어가 되었을 때 난 어떤 사람이 되었을까? 그때가 되어 과거를 회고하면 부끄러움은 있을지언정 후회는 없는 사람이 되고 싶다. 아쉬운 점을 밑바탕으로 성장하되 매 순간 최선을 다한 사람이기를.
'회고' 카테고리의 다른 글
4~5월 회고 (2) | 2022.06.06 |
---|---|
2022.3월 회고 (6) | 2022.03.31 |
2022.2월 회고 (1) | 2022.02.28 |
2022.1월 회고 (0) | 2022.01.31 |
버터나이프크루 3기 활동, 빅시스터 회고 (1) | 2021.12.20 |