여름동안 한국전자통신연구원(이하 etri)에서 단기 인턴을 하며 여러 서버들의 상태를 모니터링 할 수 있도록 프로메테우스 확장을 연구하고 적용시키는 역할을 맡았어요. 연구실 내의 메인 서버에만 프로메테우스가 구축되어있었고, 모든 서버는 스토리지 시스템까지만 구축되어 있는 상태였어요. 이 글은 프로메테우스를 확장하고, 각 서버 데이터를 라벨링해서 그라파나에서 그룹화 하여 모니터링할 수 있도록 helm이용한 방법을 기록할겁니다.
프로메테우스 기본 설치 및 세팅
- 프로메테우스 기본 설치
helm을 이용한 기본적인 프로메테우스입니다. 이 옵션은 다양한 블로그에서 찾아볼 수 있는데,
저는 https://github.com/PresentJay/lightweight-kubernetes-sandbox-cli 를 참고했어요.
helm upgrade kube-stack-prometheus-0 prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--install \
--no-hooks \
--version 39.11.0 \
- 프로메테우스 api허용
이 설정은 백단 api에서 프로메테우스에 값요청을 해야한다고 해서 열어놨었어요. 백단에서 필요한거 아니면 열어두지 않는게 좋을것같네요.
\--set prometheus.prometheusSpec.enableAdminAPI=true
- 프로메테우스 볼륨 연결
확장을 위해 ReadWriteMany로 설정했습니다. 안하면 확장하는 단계에서 문제가 생길 수 있으니 조심!
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=스토리지 클래스이름
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.accessModes[0]=ReadWriteMany
여기까지는 확장이 아닌 기본적인 설치 및 옵션들이었습니다. 물론 설명들을 참고해서 요구사항에 맞게 설정하시면되요
확장을 위한 중앙 프로메테우스 설정
아래의 사진처럼 각 서버의 프로메테우스들의 데이터를 중앙에서 모으는 방식으로 구성했어요. 각 서버의 프로메테우스에 데이터라벨링을 붙혀서 데이터조회를 할 때 분류될 수 있도록 하는게 중요합니다.
대부분 글을 보면 yaml파일을 수정하여 확장하는 글들이 많았는데 적용할 팀의 프로메테우스가 helm으로 세팅되어있어서 확장을 위해서는 helm패키지를 수정해야했고, deployment와 helm의 yaml파일 포맷 차이가 조금 있어서 helm으로 할 경우는 아래의 방법들로 쉘을 통해 추가할 수 있어요.
- job(exporter) scaping 설정
job_name를 설정해야해요. 이건 각 job의 이름을 설정해주는 거에요. 각 서버의 이름을 설정하는 거라고 생각하면 될 것 같습니다.
--set prometheus.prometheusSpec.additionalScrapeConfigs[0].job_name="서버이름"
- 데이터를 받아올 서버ip 설정
데이터를 pull받을 서버의 ip주소와 metric 수집기(node-exporter)포트를 입력해야해요.
--set prometheus.prometheusSpec.additionalScrapeConfigs[0].static_configs[0].targets[0]="서버ip:포트" \
labels까지는 yaml파일에 맞춰서 추가하고, class(key)와 "6반"(value)은 직접 선언해서 사용하면 되요.
- job label 설정
평균이나 합계를 측정하기 위해서 라벨링을 위한 그룹화가 필요할 때도 있어요. 모니터링할 서버가 많다면 라벨링이 더욱 중요할 겁니다.
--set prometheus.prometheusSpec.additionalScrapeConfigs[0].static_configs[0].labels.class="6반"
--set prometheus.prometheusSpec.additionalScrapeConfigs[0].static_configs[0].labels.grade="1힉년"
labels까지는 yaml파일에 맞춰서 추가하고, class(key)와 "6반"(value)은 직접 선언해서 사용하면 됩니다.
- 프로메테우스 확장(상위 프로메테우스 설정)
중앙으로 데이터를 모을 떄 하위 -> 상위 방식과 상위 -> 하위방식이 있는데, 중앙 프로메테우스의 포트를 열고, 하위에서 데이터를 push하는 방식으 로 설정했어요. 상위에서 하위데이터를 pull하는 방식도 가능하겠죠? 저는 중앙의 포트를 어차피 열어야해서 push방식을 사용하기 때문에 아래 설정을 통해 url을 사용가능하게 해야해요.
--set prometheus.prometheusSpec.enableRemoteWriteReceiver=true
- 프로메테우스 확장(하위 프로메테우스 설정)
상위로 push해야하니까 열어둔 url을 적어주었어요. 상위 프로메테우스:포트번호뒤에 /api/v1/write를 사용하면 일정시간마다 데이터를 전송해줘요.
--set prometheus.prometheusSpec.remoteWrite\[0\].url="메인 서버프로메테우스ip:포트번호/api/v1/write"
이렇게하면 프로메테우스의 설정은 끝났어요. 한쪽으로 모으고, 라벨링도 해서 promql을 사용할 때 라벨을 이용해 사용하면 훨씬 짧아져서 편할거에요.
굳이 Central이 필요한 이유?
프로메테우스로 오기전 각 서버의 metric 수집기가 일정시간마다 수집을 하고 데이터를 지우는데 프로메테우스가 재시작되거나 비정상 종료되면 데이터에 공백이 생겨요. 한 프로메테우스가 너무 많은 targets로부터 데이터를 받으면 traffic문제가 발생해서 종료되면 그동안의 데이터에 공백이 생길거에요. 하지만 tree구조로 시스템을 구축한다면 traffic이 적절히 분단될 수 있겠죠. 하지만 이걸론 최하위의 프로메테우스가 종료되는 문제는 해결되지 않아요
하지만 위 사진처럼 최하위 프로메테우스를 이중으로 pull하면 한쪽이 종료되더라도 나머지 프로메테우스가 데이터를 수집하고 있기 때문에 데이터에 공백이 생기는 걸 방지할 수 있어요.
마무리하며...
그라파나 얘기도 하려했는데, 딱히 기존이랑 다른게 없더라구요. 그래도 라벨링한 부분을 생각하면 통계치를 내려할 때 서버ip가 아닌 라벨로 선택할 수 있어서 직관적이기도하고, promql을 쓰기도 편해져서 좋은것같아요.
helm으로 깔다보니까 deployment부분에서 수정이 안되서 여기저기 찾아보면서 적용된 부분들을 글에 적어놓고, 어떻게 설계할지 고민을 정말 많이 하고 결정했는데 확실히 체감했는지는 아직 잘 모르겠어요... 나중에 더 공부하면 깨닫기를...!!