최근 사이드 프로젝트로 진행하는 잔디일기 운영과 GitHub PR 코드 리뷰 자동화를 위한 LLM 운영 등을 Kubernetes 클러스터에서 진행하다 보니, 각 서비스들이 원활하게 작동하는지 지속적으로 확인할 필요성을 느끼게 되었다.
특히 클러스터 내 여러 서비스들이 자원 사용량이나 상태에 따라 성능이 저하되거나 오류가 발생할 수 있기 때문에, 안정성과 성능을 유지하기 위해 모니터링이 필수적이라고 생각하게 되었다.
이로 인해 Kubernetes 환경에 적합한 Prometheus와 Grafana를 활용한 모니터링 솔루션을 구축해보기로 했다.
*운영 환경은 Rocky Linux 9이다.
Prometheus는 데이터를 수집하고, Grafana는 이를 시각적으로 보여주는 역할을 한다.
간단하게 kube-prometheus-stack을 사용하여 설치해보자.
1. Helm 설치
Kubernetes 환경에서 Helm을 통해 패키지를 관리할 수 있다. 먼저 Helm을 설치한다.
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
2. kube-prometheus-stack 설치
Helm을 사용하여 Prometheus와 Grafana가 구성되어 있는 kube-prometheus-stack을 설치한다. monitoring 네임스페이스를 지정해서 설치한다.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring
제대로 설치된 것을 확인할 수 있다.
[jjaegii@k8s-master01 prometheus]$ k get po -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-monitoring-kube-prometheus-alertmanager-0 2/2 Running 0 115s
monitoring-grafana-794d759b84-2gv7n 3/3 Running 0 2m
monitoring-kube-prometheus-operator-597d5b5b76-x4kvk 1/1 Running 0 2m
monitoring-kube-state-metrics-789bc5f8f4-cksq6 1/1 Running 0 2m
monitoring-prometheus-node-exporter-kwdz9 1/1 Running 0 2m
monitoring-prometheus-node-exporter-zrcvs 1/1 Running 0 2m
prometheus-monitoring-kube-prometheus-prometheus-0 2/2 Running 0 115s
3. Grafana 서비스 수정
Grafana에 접속해야하나, ClusterIP로 되어있다. 이를 NodePort로 변경해 외부에서 접속할 수 있게 해주자.
[jjaegii@k8s-master01 prometheus]$ k get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 7m50s
monitoring-grafana ClusterIP 10.106.137.107 <none> 80/TCP 7m54s
monitoring-kube-prometheus-alertmanager ClusterIP 10.111.82.66 <none> 9093/TCP,8080/TCP 7m54s
monitoring-kube-prometheus-operator ClusterIP 10.104.13.255 <none> 443/TCP 7m54s
monitoring-kube-prometheus-prometheus ClusterIP 10.107.73.253 <none> 9090/TCP,8080/TCP 7m54s
monitoring-kube-state-metrics ClusterIP 10.103.37.116 <none> 8080/TCP 7m54s
monitoring-prometheus-node-exporter ClusterIP 10.103.240.187 <none> 9100/TCP 7m54s
prometheus-operated ClusterIP None <none> 9090/TCP 7m49s
[jjaegii@k8s-master01 ~]$ k edit svc -n monitoring prometheus-grafana
# 변경 전
ports:
- name: http-web
port: 80
protocol: TCP
targetPort: 3000
selector:
app.kubernetes.io/instance: monitoring
app.kubernetes.io/name: grafana
sessionAffinity: None
type: ClusterIP
# 변경 후
ports:
- name: http-web
nodePort: 30080
port: 80
protocol: TCP
targetPort: 3000
selector:
app.kubernetes.io/instance: monitoring
app.kubernetes.io/name: grafana
sessionAffinity: None
type: NodePort
4. Prometheus 서비스 수정
Grafana와 Prometheus를 연동해야하나, ClusterIP로 되어있다. 이것도 NodePort로 변경해 외부에서 접속할 수 있게 해주자.
[jjaegii@k8s-master01 ~]$ k edit svc -n monitoring monitoring-kube-prometheus-prometheus
# 변경 전
ports:
- name: http-web
port: 9090
protocol: TCP
targetPort: 9090
- appProtocol: http
name: reloader-web
port: 8080
protocol: TCP
targetPort: reloader-web
selector:
app.kubernetes.io/name: prometheus
operator.prometheus.io/name: monitoring-kube-prometheus-prometheus
sessionAffinity: None
type: ClusterIP
# 변경 후
ports:
- name: http-web
nodePort: 30090
port: 9090
protocol: TCP
targetPort: 9090
- appProtocol: http
name: reloader-web
nodePort: 31080
port: 8080
protocol: TCP
targetPort: reloader-web
selector:
app.kubernetes.io/name: prometheus
operator.prometheus.io/name: monitoring-kube-prometheus-prometheus
sessionAffinity: None
type: NodePort
변경 후 확인
[jjaegii@k8s-master01 prometheus]$ k get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 19m
monitoring-grafana NodePort 10.106.137.107 <none> 80:30080/TCP 19m
monitoring-kube-prometheus-alertmanager ClusterIP 10.111.82.66 <none> 9093/TCP,8080/TCP 19m
monitoring-kube-prometheus-operator ClusterIP 10.104.13.255 <none> 443/TCP 19m
monitoring-kube-prometheus-prometheus NodePort 10.107.73.253 <none> 9090:30090/TCP,8080:31080/TCP 19m
monitoring-kube-state-metrics ClusterIP 10.103.37.116 <none> 8080/TCP 19m
monitoring-prometheus-node-exporter ClusterIP 10.103.240.187 <none> 9100/TCP 19m
prometheus-operated ClusterIP None <none> 9090/TCP 19m
5. Grafana 접속
위 단계가 완료되면 Grafana에 접속하여 대시보드를 확인할 수 있다. Grafana의 초기 비밀번호는 Kubernetes secret에 저장되어 있다. 다음 명령어로 비밀번호를 확인할 수 있다.
kubectl get secret --namespace monitoring monitoring-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
6. Grafana에 로그인
http://<Node_IP>:<NodePort>
를 통해 Grafana에 접근하고, 위에서 확인한 비밀번호로 로그인한다. 참고로 id는 admin이다.
로그인 후
7. Prometheus 연동 테스트
Grafana에서 Prometheus에 연결이 잘 되는지 테스트해보자.
Add new connection을 선택 후
Prometheus를 선택한다
해당 부분에 프로메테우스 서버의 URL을 넣고
Save & test 버튼을 누른다.
아래처럼 나오면 성공적으로 연결된 것이다.
8. 플러그인 설치
Kubernetes 모니터링에 필요한 플러그인들을 설치해보자.
dashboard에서 new -> import를 클릭하자.
그리고 https://grafana.com/grafana/dashboards/?pg=docs-grafana-latest-dashboards 에서 Kubernetes Metrics All-in-one 검색하고, JSON 파일을 다운받고 업로드 해주면 아래와 같은 화면을 볼 수 있다.
Prometheus-1을 선택한 후 Import 버튼을 클릭하면 아래와 같이 대시보드를 확인할 수 있다.
이와 같이 Kubernetes / Views / Global, kube-state-metrics-v2, Node Exporter Full 을 설치하면 된다.
*Kubernetes Metrics All-in-one : Kubernetes 클러스터의 모든 주요 메트릭을 한 번에 볼 수 있도록 통합된 대시보드를 제공하는 플러그인
*Kubernetes / Views / Global: Kubernetes 클러스터에 대한 전반적인 글로벌 뷰를 제공하는 대시보드 플러그인
*kube-state-metrics-v2: Kubernetes 클러스터의 상태 정보를 제공하는 Prometheus 메트릭 수집기 플러그인
*Node Exporter Full: 시스템 하드웨어와 운영체제 수준의 메트릭을 수집하는 Prometheus Exporter 플러그인