Cloud

[Observability] Loki와 Promtail을 이용한 로그 모니터링 아키텍쳐

Omoknooni 2024. 7. 12. 22:43

서버를 운영하게 되면 로그는 자연스럽게 발생한다. 이러한 로그들은 양도 많을 뿐더러 관리하는 서버의 수가 많아지면 그 내용들을 일일히 직접 확인하기란 어려울 따름이다. 그래서 로그 수집과 가시화 시스템을 구축하여 로그들을 모니터링하게 된다. 

 

이번에는 Loki와 Promtail, Grafana를 이용해 로그를 모니터링하는 아키텍쳐를 구축해보도록 한다.

 

Loki & Promtail

Like Prometheus, but for logs

 

 

Loki는 오픈소스 타입의 로그 모니터링 도구로, 로그를 Label을 통해 그룹화해 처리한다. Prometheus가 Metric을 수집하는데에 목적을 두었다면, Loki는 로그를 수집하는데에 목적을 둔 도구로 볼 수 있다.

로그 라인의 메타데이터(Label)를 인덱싱해, 그 Label 단위로 로그 메시지를 압축시킨 뒤 chunk단위로 저장해 스토리지 사용량을 더 줄일 수 있게 된다. 

 

 

Loki는 LogQL이라는 query language를 이용한다. 이는 Prometheus의 PromQL과 유사한 구조로, 이를 사용할 줄 알면 큰 어려움없이 LogQL도 사용할 수 있다.

 

Promtail은 로그를 수집하는 에이전트로, 로그를 수집해 Loki로 로그를 전송하는 역할을 맡는다. Loki는 Promtail 외에도 Fluentd, logstash와도 같이 사용할 수 있도록 지원한다. 

Promtail은 수집한 로그 데이터를 Push해주는 방식으로 Loki에 전달한다.

 

Loki-Promtail-Grafana 아키텍쳐는 ELK stack과 비교될 수 있다.

ELK stack과 비교하면 Loki 아키텍쳐는 다음과 같은 장점이 존재한다.

  • 사용과 구축이 비교적 간단하다
  • 저장공간과 CPU, 메모리 리소스를 적게 먹는다
  • 쿠버네티스 환경에 친화적이다

 

다만, 다음과 같은 점은 ELK stack에 비해 단점으로 작용한다.

  • 로그 검색 기능
    • 앞서 이야기 했듯이 메타데이터를 바탕으로 색인화를 하고 로그 본문을 색인화하지 않기 때문에 ElasticSearch같이 복잡한 쿼리와 빠른 검색속도에 밀리게 된다.

 

 

Loki 아키텍쳐 구축

k8s 클러스터에 배포된 파드에서 발생하는 로그들을 수집해 가시화해주는 Grafana-Loki-Promtail 아키텍쳐를 구축해보도록 한다.

간단하게 클러스터를 하나 구축한 뒤 Nginx 서비스를 배포 후, 이 파드들에서 발생하는 로그들을 Grafana-Loki-Promtail 아키텍쳐로 수집 후 가시화 해보기로 한다.

 

먼저 grafana helm 저장소를 추가해준다. 

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

 

 

 

다음으로 먼저 Nginx 서비스를 배포하도록 한다.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test-nginx
  name: test-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-nginx
  template:
    metadata:
      labels:
        app: test-nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
          - containerPort: 80
          
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc
  name: nginx-svc
spec:
  ports:
  - name: 8080-80
    nodePort: 31080
    protocol: TCP
    targetPort: 80
    port: 80
  selector:
    app: test-nginx
  type: NodePort

 

 

이어서 앞서 추가한 grafana 저장소의 loki-stack을 설치해준다. 해당 value 파일에는 Loki와 promtail 외에도 다른 요소들도 구성은 되어있는 상태이다. 기본적으로 Loki, Promtail 이외 것들은 disable되어있다.

helm install loki-stack grafana/loki-stack -n monitoring

 

 

그리고 grafana를 설치한다. value 파일을 받아 admin과 port부분을 약간 수정해준다. (grafana를 nodeport로 지정해 간단하게 내용을 확인하기 위함)

helm show values grafana/grafana > grafana.yml

helm install grafana grafana/grafana -f grafana.yml -n monitoring

 

 

이어서 Grafana에 접속 후, 좌측 패널에 Connections > Data Sources에서 앞서 생성한 Loki를 연결해준다. 

 

 

Loki의 접속 URL을 작성 후 Save하면 Test connection이 진행되고 저장된다.

 

 

+) grafana/loki-stack의 내용 중 loki의 버전에 이슈가 있는 것을 발견했다. loki-stack value 파일을 사용하는 경우, helm install 이후 loki의 버전을 수정해주어야한다.

이 글에서는 간단하게 Loki 아키텍쳐를 구성하기 위해 loki-stack을 사용했으나, loki와 promtail을 각각 별도로 install하도록하자

kubectl edit statefulset loki-stack -n monitoring

image: grafana/loki:2.6.1 => grafana/loki:2.9.7

 

 

kubelet Readiness probe failed: HTTP probe failed with statuscode: 503 · Issue #12566 · grafana/loki

Describe the bug deploy loki-stack using helm chart, enable loki, promtail, grafana, loki pod describ: Warning Unhealthy 35m (x2 over 35m) kubelet Liveness probe failed: HTTP probe failed with stat...

github.com

 

 

그리고 대시보드에서 이 Data Source를 가져와 쿼리를 작성한다. 쿼리를 작성 후 Run Query로 결과를 패널에서 확인할 수 있다. 

아래는 Label Filter로 다른 namespace에 존재하는 nginx 파드의 로그를 가져온 것이다. 

 

 

이렇게 Grafana에 Loki를 연결해 클러스터 내의 파드 로그를 가져와 보았다. 검색능력은 ElasticSearch보다 떨어지는 경향을 보이나 로그의 메타데이터를 Label로 저장해 쿼리에서 호출하는 것으로 간단하게 로그를 검색할 수 있는 것을 볼 수 있다. 

또한 ElasticSearch보다 훨씬 간단하게 구축할 수 있고, 많은 엔지니어들에게 친숙한 Grafana 대시보드와도 잘 연계가 되어있기에 꽤나 매력있는 모니터링 도구로 생각된다.

 

다음에는 이 Loki의 구조를 딥하게 알아보고 오브젝트 스토리지와의 연계도 진행해보도록 한다.

 

 

우아한형제들에서 Loki 아키텍쳐에 대한 설명과 도입과정을 잘 설명한 글이 있으니 읽어보도록 한다.

 

따끈따끈한 전사 로그 시스템 전환기: ELK Stack에서 Loki로 전환한 이유 | 우아한형제들 기술블로그

안녕하세요. 클라우드모니터링플랫폼팀의 이연수입니다. 우아한형제들의 모니터링시스템 구축 및 관리, 운영을 하고 있습니다. 작년부터 올해 초까지 팀에서 전사 로그 시스템을 전환을 진행

techblog.woowahan.com