MSA 모니터링을 구축해보자 ! - 설치
개요
평소에 관심있었던 분야중에 모니터링 이었는데 이번 스터디를 통해서 많이 찾아보고 공부하게 되어서 구축하는 과정을 정리하게 됐다!
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가 정상적으로 접속되는지 확인합니다.
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를 검색해서 클릭합니다.
Prometheus server URL을 작성합니다. Kubernetes 기준으로 다음과 같이 설정합니다.
http://prometheus-kube-prometheus-prometheus.${namespace}.svc:${servicePort}
정상적으로 연결되었다면 성공입니다!
Tempo
Grafana Data Source에서 Tempo를 검색해서 클릭합니다.
Grafana와 Tempo를 연결하기 위해서 query-frontend Service URL을 설정합니다.
아래 Tempo Architecture 입니다.
정상적으로 연결되었다면 성공입니다!
Loki
Grafana Data Source에서 Loki를 검색해서 클릭합니다.
Tempo와 마찬가지로 query-frontend Service URL을 작성합니다.
아래 Loki Architecture 입니다.
정상적으로 연결되었다면 성공입니다!
후기
여러 오픈소스를 설치하고 설정하다보니 뇌정지가 중간중간 왔던것 같다. 모니터링 도구들 설치만 하는데도 벌써부터 진이 빠진다.
유튜브나 다른 유료 강의를 통해서 모니터링 공부를 하고있는데 건드려선 안될 영역을 건드린 느낌이 든다.