DevOps/Observability

MSA 모니터링을 구축해보자 ! - 설치

journalctl 2025. 1. 29. 23:03

개요

관심만 있다고 했는데요?

 

평소에 관심있었던 분야중에 모니터링 이었는데 이번 스터디를 통해서 많이 찾아보고 공부하게 되어서 구축하는 과정을 정리하게 됐다!

DataDog, AWS Cloudwatch, New Relic, Dynatrace 등 다양한 상용 모니터링 도구들이 있지만 비용 문제가 크게 화제되고 있어 오픈소스로 구축한 모니터링 도구들이 떠오르고 있다. (관리가 쉬운만큼 비용을 지불해야겠지?)

이번 스터디에서는 LGTM + Opentelemetry 기반을 사용하여 오픈소스 도구들로 진행할 예정이다!

오픈소스 목적
Grafana 모니터링 대시보드
Loki Log
Tempo Trace
Prometheus Metric
Alloy Collector
Opentelemetry Instrumentation

💡 Kubernetes 환경에서 설치를 진행하며 각 오픈소스의 설치는 Helm Chart를 사용합니다.

설치

Grafana 설치

먼저 Helm Repo를 등록합니다.

$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm repo update
$ helm repo list

NAME                    URL
grafana                 https://grafana.github.io/helm-charts

 

개인적으로 helm chart를 다운로드 받아서 수정하는걸 좋아하기 때문에 최신 차트를 다운로드 받습니다.

$ helm pull grafana/grafana
$ tar xvfz grafana-8.8.2.tgz
$ cd grafana-8.8.2

 

취향에 맞게 values.yaml 파일을 수정해서 배포를 진행합니다. (기본 설정에서 Ingress 설정만 바꿔서 배포했습니다.)

$ vim vaules.yaml
$ helm install grafana . -f values.yaml -n monitoring --create-namespace
$ kubectl get po,ing -n monitoring # 설정한대로 잘 배포되었는지 확인

NAME                                                         READY   STATUS    RESTARTS   AGE
pod/grafana-5d56c6fcf7-p2qgh                                 1/1     Running   0          6d23h

NAME                                CLASS   HOSTS                   ADDRESS     PORTS   AGE
ingress.networking.k8s.io/grafana   nginx   grafana.local.example   localhost   80      6d23h

 

초기 패스워드를 따로 설정하지 않았기 때문에 아래 명령어를 통해서 획득합니다.

$ kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

 

설정한 Ingress로 Grafana가 정상적으로 접속되는지 확인합니다.

Grafana 대시보드 화면

 


Prometheus 설치

먼저 Helm Repo를 등록합니다.

$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm repo list

NAME                    URL
prometheus-community    https://prometheus-community.github.io/helm-charts
grafana                 https://grafana.github.io/helm-charts

Helm Chart를 다운로드 받아서 수정합니다.

$ helm pull prometheus-community/kube-prometheus-stack
$ tar xvfz kube-prometheus-stack.tgz
$ cd kube-prometheus-stack

Prometheus 아래 설정을 true로 설정한 후 배포를 진행합니다.

 

❕Prometheus에서 Metric을 수집하는 방법에는 Pull-based, Push-based 두 가지 방법을 모두 지원합니다.

Collector를 통해서 Prometheus에 Push 하기 위해서는 Web API를 허용해야 합니다.

$ vim values.yaml
{prometheus.prometheusSpec.enableRemoteWriteReceiver} = 'true' # 해당 설정을 true 변경

$ helm install prometheus . -f values.yaml -n monitoring
$ kubectl get po -n monitoring

NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0   2/2     Running   0          6d23h
grafana-5d56c6fcf7-p2qgh                                 1/1     Running   0          6d23h
prometheus-kube-prometheus-operator-6554949884-z8q9b     1/1     Running   0          6d23h
prometheus-kube-state-metrics-675db84765-kbmg7           1/1     Running   0          6d23h
prometheus-prometheus-kube-prometheus-prometheus-0       2/2     Running   0          6d23h
prometheus-prometheus-node-exporter-fbz4g                1/1     Running   0          6d23h
prometheus-prometheus-node-exporter-zgzvf                1/1     Running   0          6d23h

Loki 설치

앞서 등록한 Grafana Repo를 사용해서 차트를 다운로드 받습니다.

$ helm pull grafana/loki-distributed
$ tar xvfz loki-distributed-0.80.0.tgz
$ cd loki-distributed-0.80.0

 

추가적으로 설정할 부분이 없어서 기본 설정으로 설치를 진행했습니다.

노드별로 자동으로 로그 수집을 하기 위해서는 Promtail를 Daemonset으로 배포한 후 Loki Instance에 Push 하도록 설정해주시면 됩니다.

$ helm install loki . -f values.yaml -n monitoring
$ kubectl get po -n monitoring

NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0   2/2     Running   0          6d23h
grafana-5d56c6fcf7-p2qgh                                 1/1     Running   0          6d23h
loki-loki-distributed-distributor-58bd46cc7-kc628        1/1     Running   0          6d23h
loki-loki-distributed-gateway-67686fdf98-vtwqw           1/1     Running   0          6d23h
loki-loki-distributed-ingester-0                         1/1     Running   0          6d23h
loki-loki-distributed-querier-0                          1/1     Running   0          6d23h
loki-loki-distributed-query-frontend-7dd49cd98c-fqzln    1/1     Running   0          6d23h
prometheus-kube-prometheus-operator-6554949884-z8q9b     1/1     Running   0          6d23h
prometheus-kube-state-metrics-675db84765-kbmg7           1/1     Running   0          6d23h
prometheus-prometheus-kube-prometheus-prometheus-0       2/2     Running   0          6d23h
prometheus-prometheus-node-exporter-fbz4g                1/1     Running   0          6d23h
prometheus-prometheus-node-exporter-zgzvf                1/1     Running   0          6d23h

Tempo 설치

앞서 등록한 Grafana Repo를 사용해서 차트를 다운로드 받습니다.

$ helm pull grafana/tempo-distributed
$ tar xvfz tempo-distributed-1.18.1.tgz
$ cd tempo-distributed

 

Tempo 설정 중에서 otlp 관련 설정을 확인하고 배포를 진행합니다. (아래 설정을 통해서 otlp.http, otlp.grpc 포트를 open 합니다.)

$ vim values.yaml
{.traces.otlp.http.enabled} = 'true'
{.traces.otlp.grpc.enabled} = 'true'

$ helm install tempo . -f values.yaml -n monitoring
$ kubectl get po,svc -n monitoring

NAME                                                         READY   STATUS    RESTARTS   AGE
...
pod/tempo-compactor-74c77b67df-78c8x                         1/1     Running   0          6d23h
pod/tempo-distributor-7487dfb65d-9n9kl                       1/1     Running   0          6d23h
pod/tempo-ingester-0                                         1/1     Running   0          6d23h
pod/tempo-ingester-1                                         1/1     Running   0          6d23h
pod/tempo-ingester-2                                         1/1     Running   0          6d23h
pod/tempo-memcached-0                                        1/1     Running   0          6d23h
pod/tempo-querier-65f7958849-scbs2                           1/1     Running   0          6d23h
pod/tempo-query-frontend-846ddcf78f-9wvvp                    1/1     Running   0          6d23h

NAME                                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                         AGE
...
service/tempo-compactor                                 ClusterIP   10.96.158.193   <none>        3100/TCP                                        6d23h
service/tempo-distributor                               ClusterIP   10.96.96.73     <none>        3100/TCP,9095/TCP,4318/TCP,4317/TCP,55680/TCP   6d23h
service/tempo-distributor-discovery                     ClusterIP   None            <none>        3100/TCP,4318/TCP,4317/TCP,55680/TCP            6d23h
service/tempo-gossip-ring                               ClusterIP   None            <none>        7946/TCP                                        6d23h
service/tempo-ingester                                  ClusterIP   10.96.101.232   <none>        3100/TCP,9095/TCP                               6d23h
service/tempo-ingester-discovery                        ClusterIP   None            <none>        3100/TCP,9095/TCP                               6d23h
service/tempo-memcached                                 ClusterIP   10.96.135.215   <none>        11211/TCP,9150/TCP                              6d23h
service/tempo-querier                                   ClusterIP   10.96.189.160   <none>        3100/TCP,9095/TCP                               6d23h
service/tempo-query-frontend                            ClusterIP   10.96.79.41     <none>        3100/TCP,9095/TCP                               6d23h
service/tempo-query-frontend-discovery                  ClusterIP   None            <none>        3100/TCP,9095/TCP,9096/TCP  

Alloy 설치

Collector는 Grafana에서 제공하는 Alloy를 사용했습니다. Opentelemetry Collector를 사용해도 무방합니다 !

 

앞서 등록한 Grafana Repo를 사용해서 차트를 다운로드 받습니다.

$ helm pull grafana/alloy
$ tar xvfz alloy-0.10.1.tgz
$ cd alloy

 

OTLP를 사용하여 Receiver로 전달받기 위해 특정 포트를 open 하도록 설정합니다. Alloy 설정을 Graph로 보기 위해서 Ingress도 설정하였습니다.

$ vim values.yaml
{.alloy.extraPorts}
  extraPorts:
    - name: "grpc"
      port: 4317
      targetPort: 4317
      protocol: "TCP"
    - name: "otlp"
      port: 4318
      targetPort: 4318
      protocol: "TCP"

$ helm install alloy . -f values.yaml -n monitoring
$ kubectl get po,ing -n monitoring

NAME                                                         READY   STATUS    RESTARTS   AGE
pod/alloy-7z7hk                                              2/2     Running   0          6d23h

NAME                                CLASS   HOSTS                   ADDRESS     PORTS   AGE
ingress.networking.k8s.io/alloy     nginx   alloy.local.example     localhost   80      6d23h
ingress.networking.k8s.io/grafana   nginx   grafana.local.example   localhost   80      6d23h

Grafana Data Source 구성

Prometheus

Grafana Data Source에서 prometheus를 검색해서 클릭합니다.

Home > Connections > Add new connection

 

Prometheus server URL을 작성합니다. Kubernetes 기준으로 다음과 같이 설정합니다.

http://prometheus-kube-prometheus-prometheus.${namespace}.svc:${servicePort}

Settings > Connection

 

정상적으로 연결되었다면 성공입니다!

Settings > Save & test

 


Tempo

Grafana Data Source에서 Tempo를 검색해서 클릭합니다.

Home > Connections > Add new connection

 

Grafana와 Tempo를 연결하기 위해서 query-frontend Service URL을 설정합니다.

Settings > Connection > URL

 

아래 Tempo Architecture 입니다.

Tempo Architecture -  https://grafana.com/docs/tempo/latest/operations/architecture/

 

정상적으로 연결되었다면 성공입니다!


Loki

Grafana Data Source에서 Loki를 검색해서 클릭합니다.

Home > Connections > Add new connection

 

Tempo와 마찬가지로 query-frontend Service URL을 작성합니다.

Settings > Connection > URL

 

아래 Loki Architecture 입니다.

Loki Architecture -  https://grafana.com/docs/loki/latest/get-started/architecture/

 

정상적으로 연결되었다면 성공입니다!


후기


여러 오픈소스를 설치하고 설정하다보니 뇌정지가 중간중간 왔던것 같다. 모니터링 도구들 설치만 하는데도 벌써부터 진이 빠진다.

유튜브나 다른 유료 강의를 통해서 모니터링 공부를 하고있는데 건드려선 안될 영역을 건드린 느낌이 든다.