[DevOps] Nginx Log Aggregation & Dashboard

안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 lokipromtail에 대해서 정리를 해보도록 하겠습니다. 필자는 프로메테우스와 그라파나를 사용하다보니, 자연스럽게 Loki라는 제품에 대해서 접할 수 있었습니다. 그리고 로그를 좀 더 쉽게 수집하고 표현할 수 있다는 점에서 바로 적용을 해보기로 했습니다.

본 포스팅은 Loki를 처음 접하거나 간단하게 사용해 볼 수 있는 내용으로 구성했습니다.

Nginx에 관한 시리즈 포스팅은 아래에서 확인이 가능합니다.

1. Loki란 무엇인가요?

Loki는 Prometheus에 영감을 받아서 탄생한 클라우드 네이티브 인프라를 위한 로깅 서비스 입니다.

KubeCon Seattle 2018에서 Grafana Labs에서 오픈소스로 공개된 Loki는 Kubernetes에서 Prometheus에 대한 경험이 있는 사용자에게 최적화된 로깅 백엔드입니다. Loki는 뛰어난 로그 검색 및 시각화 기능을 Grafana 6.0에서 제공합니다.

Loki는 단일 로그 라인을 그대로 처리한다는 아이디어를 기반으로 만들어졌습니다. 이는 전체 텍스트 인덱싱을 하는 것이 아니라 Prometheus와 마찬가지로 동일한 label을 사용하여 관련 로그들을 그룹화한다는 것을 의미합니다. 이 방식은 훨씬 효율적이며 확장성이 좋습니다.

구성 요소

  • Loki
    • 메인 서버 구성 요소를 Loki라고 부르며 전달되는 로그들을 영구 저장하고 클라이언트의 LogQL 쿼리를 실행합니다.

Loki는 Components(querier, ingester, query-frontend, or distribute)로 구성이 됩니다.

  • Distributor

Distributor는 클라이언트(fluentd, fluent-bit, promtail)에서 들어오는 로그를 받아서 로그의 정확성을 검증하고 하나 이상의 Ingester에게 전달합니다.

  • Ingester

Ingester는 Distributors 로부터 로그를 수신하고 들어오는 데이터를 장기 저장소(DynamoDB, S3, Cassandra, etc.)에 저장을 합니다

  • Querier

Querier는 Ingester(내장 메모리) 및 장기 저장소(DynamoDB, S3, Cassandra, etc.) 에서 로그 쿼리 한 데이터를 가져온 후 중복을 제거 후 Grafana 또는 Query-Frontend 에게 데이터를 반환합니다.

  • Query-Frontend

쿼리 프론트엔드는 2020년 여름에 도입되었으며 분산 설정의 선택적 구성 요소입니다. 일종의 프록시 서비스라고 생각할 수 있습니다. Grafana에서 요청을 수신하고 일부 유효성 검사 및 캐싱을 수행한 다음 쿼리를 쿼리자에게 전달합니다.

2. Loki 설치

필자는 kubernetes를 운영하고 있기 때문에 helm을 통해서 설치하기로 했습니다.

loki stack helm cahrt

grafana/loki와 관련된 Helm Chart들을 살펴보면 5가지 방식으로 설치가 가능합니다.

  • grafana/loki : 현재 Grafana Loki에서 중점적으로 관리 및 업데이트하고 있는 Helm chart

  • grafana/loki-distributed : Microservice 형태로 Loki를 관리할 수 있도록 해주는 Helm chart
    -> Ingester, Querier, Index Gateway, Distributor, Query-Frontend, Ruler 등으로 구분되어 있음

  • grafana/loki-simple-scalable : 현재 Deprecated 되었지만 Loki를 아주 간단하게 관리할 수 있도록 도와주는 Helm chart
    -> Write와 Read, Nginx gateway로만 구분되어 있다.

  • grafana/loki-stack : 올인원 모놀리식 형태로 사용할 수 있는 Loki Helm chart

필자는 간단하면서도 내부용도로 사용하는 Loki를 구성하기 위해 올인원 방식으로 결정하였습니다.

  • 설치 버전 : v2.6.1
  • Loki의 Chart 레포지토리를 helm에 추가

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

Loki의 Helm Chart에서 다음 사항을 false 처리함으로써 미사용으로 처리합니다.

  • grafana.enabled=false
  • loki.persistence.enabled=false
  • promtail.enabled=false
  • Loki의 볼륨은 File System으로 관리 : 운영계일 경우 Loki : S3와 DynamoDB 혹은 Minio 등을 고려할 수 있겠지만 개발계에 로그와 모니터링 시스템을 구성할 예정이기 때문에 큰 상관이 없을 것이라 생각되어 파일 시스템으로 구성하되 최소한의 안전 장치로 PVC를 사용

필자의 구성은 Remote 서버의 Nginx 로그들을 Promtail을 통해서 Loki로 수집을 하고자 합니다. 따라서, 별도로 Cluster에는 Promtail이 필요 없기 때문에 미사용으로 표기를 합니다.

  • values 파일 변경
    $ helm upgrade --install loki grafana/loki-stack --create-namespace --namespace=monitoring --set grafana.enabled=false,promtail.enabled=false,loki.config.table_manager.retention_deletes_enabled=true,loki.config.table_manager.retention_period=336h,loki.persistence.enabled=false,loki.config.limits_config.max_query_series=100000,loki.config.frontend.max_outstanding_per_tenant: 4096,loki.config.query_range.parallelise_shardable_queries: true,loki.config.query_scheduler.max_outstanding_requests_per_tenant: 4096,loki.config.split_queries_by_interval: 15m,loki.config.max_query_parallelism: 32
  • loki 설정 옵션
grafana.enabled=false,
promtail.enabled=false,

loki.config.table_manager.retention_deletes_enabled=true,
loki.config.table_manager.retention_period=336h,
loki.persistence.enabled=false,

loki.config.limits_config.max_query_series=100000,
loki.config.frontend.max_outstanding_per_tenant: 4096,
loki.config.query_range.parallelise_shardable_queries: true,
loki.config.query_scheduler.max_outstanding_requests_per_tenant: 4096,

loki.config.split_queries_by_interval: 15m,
loki.config.max_query_parallelism: 32
  • Nodeport 타입으로 변경
$ kubectl edit svc loki -n monitoring
type : NodePort
  • 설치 검증
$ kubectl --namespace=monitoring get services
$ kubectl --namespace=monitoring get pods

3. Promtail 설치

Loki를 설치 했으면, Nginx가 설치되어있는 서버에 Promtail을 설치하여, 로그를 Loki로 전송할 수 있도록 해보겠습니다.

promtail official document

  • 설치 버전 : v2.7.3
  • binary download
$ mkdir /etc/loki
$ cd /etc/loki
$ wget https://github.com/grafana/loki/releases/download/v2.7.3/promtail-linux-amd64.zip
$ unzip promtail-linux-amd64.zip
$ chmod a+x promtail-linux-amd64
$ rm -rf promtail-linux-amd64.zip
$ mv promtail-linux-amd64 promtail
  • 설정 파일 download & 설정
$ wget https://raw.githubusercontent.com/grafana/loki/main/clients/cmd/promtail/promtail-local-config.yaml

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://xx.xxx.xx.xxx:32617/loki/api/v1/push

scrape_configs:
- job_name: nginx
  static_configs:
  - targets:
      - localhost
    labels:
      job: nginxlogs
      __path__:  /home1/irteam/apps/nginx-1.20.1/logs/access_log
  • service 등록
$ sudo vi /etc/systemd/system/promtail.service

[Unit]
Description=Grafana Loki Promtail
Documentation=https://github.com/grafana/loki
After=network-online.target

[Service]
User=root
Restart=always
ExecStart=/etc/loki/promtail --config.file=/etc/loki/promtail-local-config.yaml

[Install]
WantedBy=multi-user.target
  • service 시작
$ systemctl restart promtail
$ systemctl status promtail 

4. 그라파나 설정 및 대시 보드 구성

이제 Loki, Promtail이 모두 구성이 됐으니, 로그는 정상적으로 수집이 될 것입니다. 그러면 Grafana에서 해당 Datasource 연결을 통해서 데이터가 정상적으로 수집이 되는지 확인을 해보도록 하겠습니다.

grafana의 Datasource를 추가해주는 화면에서 Target URL에 Loki의 IP:Nodeport를 입력을 해줍니다. 그렇게 되면, 정상적으로 연동이 됩니다.

  • Grafana의 Explorer에서 LokiQL을 통해서 조회

Nginx에서 쌓이는 Access log가 동일하게 Loki에서 정상 수집됨을 확인 할 수 있습니다.

  • Grafana의 Dashboard 연동을 통해서 시각화

5. 마치며…

Nginx의 Access 로그는 서비스의 유입점이기 떄문에 굉장히 유용한 정보로 활용 될 수 있습니다. 이에 대한 로그를 빠르게 수집하고 시각화 하여 활용하게 되면 서비스의 안정화 혹은 사업적으로도 가치가 높습니다.

Loki와 Promtail에 대해서 간단하게 적용해 볼 수 있도록 포스팅을 정리해봤습니다. 추후에는 Loki의 쿼리 속도 개선에 대해서 정리를 해보도록 하겠습니다.

6. 참고

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다