• ELK + Kafka 로그 시스템 알아보기 (1) :: 마이구미
    AWS 2021. 8. 19. 22:10
    반응형
    이 글은 ELK + Kafka + Filebeat 를 통한 로그 시스템을 알아본다.
    기본적인 흐름을 구성하고 다룰 것이고, 단계로 보면 입문 정도라고 볼 수 있다.
    글의 예제는 Docker 를 기반으로 진행되기에, Docker 의 개념이 필요하다.
    예제 - https://github.com/hotehrud/log-system

     

    예제는 github 코드를 clone 하고 docker-compose 를 통해 실행하면 동작된다.

    실습을 위한 Github 예제에는 기본적인 명령어 팁들이 있다. (README.md)

    혹시 실습이 잘 진행되지않으면, docker logs -f 컨테이너이름 을 통해 에러 여부만 잘 파악하면 큰 어려움이 없을 것이다.

     

    글은 다음과 같은 순서로 진행할 것이다.

    각 개념에 대해서는 상세히 다루지 않을 것이고, 큰 그림에 초점이 맞추었다.

     

    1. ELK
    2. ELK + Filebeat
    3. ELK + Filebeat + Kafka

     

    나타내는 순서는 히스토리를 의미하는 것으로 2, 3번은 예제를 통해 확인할 수 있다.

    최종 결과물은 3번에 맞추어져있다.

    무엇을 의미하는지 알아보자.

     

    ELK Stack 은 Elasticsearch + Logstash + Kibana 를 뜻하는 용어이다.

    Elastic 회사에서 제공하는 제품 구성이다. (https://www.elastic.co/kr/)

     

    Logstash

    데이터를 수집하고 변환하여 Elasticsearch 에 전송한다.

    input, filter, output 으로 구성된 데이터 수집 파이프라인이다.

     

    Elasticsearch

    데이터 검색 및 분석을 담당하는 엔진이다.

     

    Kibana

    Elasticsearch 에 저장된 데이터를 시각화해주는 웹 인터페이스이다.

     

     

    각 서버의 로그들을 logstash 에서 로그를 수집 및 변환하여 Ship 역할로 Elasticsearch 로 전송한다.

    그리고 Elasticsearch 데이터 기반으로 Kibana 에서 시각적으로 보여준다.

     

    위 그림의 구성은 docker-elk 를 통해 확인할 수 있다.

     


     

    시간이 흘러 Elastic 에서는 사용자 요구사항들을 적용하여 Beats 를 추가하였다.

    ELK + Beats 를 합친 용어로 Elastic Stack 이라고 불린다.

     

     

    Beats

    경량 데이터 수집기로 로그 파일을 저장하고 데이터 Ship 역할로 Logstash 로 전송한다.

    적은 메모리 사용으로 리소스 절감이 가장 큰 장점이라고 한다.

     

    Logstash 는 다양한 로그를 수집 및 변환하여 Elasticsearch 전송한다.

    그리고 Elasticsearch 데이터 기반으로 Kibana 에서 시각적으로 보여준다.

     

    예제를 통해서 확인해보자. https://github.com/hotehrud/log-system

    코드는 최종 결과물인 3번을 위한 것임으로, tag 명 "filebeat" 를 checkout 해야한다.

     

    $ git checkout tags/filebeat

     

    docker-elk 를 기반으로 app, filebeat 를 추가했다.

    app 은 Node.js 기반 웹 서버, 로그 저장을 위한 filebeat 를 의미한다.

     

    app 예제 코드 (자세한건 Github 참고)

    const logDir = `${appRoot}/logs`;

     

    웹 서버의 로그는 최상위 루트의 logs 디렉토리에 저장된다.

    * morgan 기반으로 웹 서버 접근 시 로그는 req.log 와 날짜별 rotate 파일에 기록된다.

     

    Dockerfile (filebeat)

    ARG ELK_VERSION
    
    FROM docker.elastic.co/beats/filebeat:${ELK_VERSION}
    COPY filebeat.yml /usr/share/filebeat/filebeat.yml
    USER root
    RUN mkdir /var/log/server
    RUN chown root:filebeat /usr/share/filebeat/filebeat.yml
    USER filebeat

     

    로그가 저장되는 파일 경로를 위해 /var/log/server 디렉토리를 생성한다.

     

    docker-compose.yml

    ....
    
    app:
        build:
          context: ./app
        volumes:
          - log-volume:/app/logs
        ports:
          - "3000:3000"
    
      filebeat:
        build:
          context: ./filebeat
          args:
            ELK_VERSION: $ELK_VERSION
        volumes:
          - log-volume:/var/log/server
        networks:
          - elk
        depends_on:
          - logstash
    
    networks:
      elk:
        driver: bridge
    
    volumes:
      elasticsearch:
      log-volume:

     

    웹 서버의 로그는 app/logs 에 저장된다.

    filebeat 는 도커 이미지에서 /var/log/server 디렉토리를 생성한다.

    볼륨 컨테이너 log-volume 를 통해 로그 수집 경로를 공유하게한다.

    멀티 컨테이너 환경에서의 각 컨테이너간 네트워크 공유를 위해 networks 로 연결해준다.

     

    filebeat.yml

    filebeat.inputs:
      - type: log
        enabled: true
        paths:
          - /var/log/server/req.log
        fields:
          topic: req-log
    
    output.logstash:
      hosts: ["logstash:5044"]

     

    paths 에 설정된 경로를 지켜보게 된다.

    30초(디폴트)마다 모니터링을 통해 설정된 output 경로인 logstash 에 전송하게 된다.

    logstash.conf

    input {
      beats {
        port => 5044
      }
    }

     

    도커 컨테이너 실행 후 localhost:3000 에 접근하면 웹 서버 로그를 쌓인다.

    쌓인 로그는 localhost:5601 키바나를 통해 확인할 수 있다.

     


     

    이번에는 Elastic Stack(ELK + Beats) 에서 Kafka 를 연동하는 것이다.

    Kafka 를 도입하는 많은 이유 중 하나는 트래픽이 몰리면 Logstash, Elasticsearch 만으로는 부하를 견디기 힘들다고한다.

    *일반적으로 최소 주키퍼 3대, 카프카 3대로 구성한다고 하는데 그림이나 예제에서는 각 1대로 구성하였다.

     

    Kafka

    Pub-Sub 모델을 가지는 분산 메시징 플랫폼이다.

    기존 메시징 시스템처럼 Broker 가 Consumer 에게 직접 메시지를 전송하는 방식이 아니다.

    Kafka 는 Consumer 가 Broker 로부터 직접 메시지를 가져가는 방식이다.

     

    • Producer - 메시지 발행 ex) filebeat
    • Consumer - 메시지 구독 ex) logstash
    • Broker - Kafka 서버
    • Topic - 저장되는 데이터를 구분하는 용도 ex) DB 테이블
    • Zookeeper - Kafka 서버 관리

     

     

    이전 단계에서는 Filebeat 에서 Logstash 로 데이터를 전송했다.

    Kafka 를 추가함으로써, Filebeat 는 Kafka 로 데이터를 전송하고 Logstash 에서 Kafka 에 있는 데이터를 가져가게 된다.

    이전 단계와 비교해서 역할이 달라졌기 때문에 Filebeat output 과 Logstash input 수정이 필요하다.

     

    filebeat.yml

    output.kafka:
      hosts: ["kafka:9092"]
      topic: 'log'
      partition.round_robin:
        reachable_only: false
      required_acks: 1
      compression: gzip
      max_message_bytes: 1000000

     

    topic 을 명시하고 output 을 Kafka 로 정의한다.

     

    logstash.conf

    input {
      kafka {
        bootstrap_servers => "kafka:9092"
        topics => ["log"]
      }
    }

     

    "log" 라는 topic 명을 구독하여 메시지를 가져와서 Elasticsearch 에 전송하고 Kibana 를 통해 시각화해준다.

     

    기본적인 흐름을 다뤄보았다.

    추후 실제로 서비스에 적용해보면서 새롭게 얻는 경험과 지식들을 다음 편으로 남겨보도록 예정이다.

     

    잘못된 내용이 있다면, 댓글로 남겨주시면 감사히...

     

    참고 링크 

    kafka-docker https://github.com/wurstmeister/kafka-docker

     

    Elastic Stack https://blog.eunsukim.me/posts/build-logging-system-with-docker-elk-filebeat-nodejs

    Elastic Stack + kafka https://investment-engineer.tistory.com/6?category=979835

    Filebeats vs Logstash https://sabarada.tistory.com/46

     

    반응형

    댓글

Designed by Tistory.