http://blog.logicwind.com/efk-setup/

 

중앙 로그 수집을 위해 Eleastcsearch, Fluentd, Kibana를 이용해 EFK 스택을 구축해보도록 합니다.

 

 

 

1. 앞선 글

 

중앙 로그 수집을 위해 로그 수집기를 알아봤습니다: 2020.10.28 - [Programming] - LogStash vs Fluentd - 어떤 것을 선택해야 할까

 

LogStash vs Fluentd - 어떤 것을 선택해야 할까

이 글은 다음 글을 번역한 글입니다: Logstash vs Fluentd — Which one is better! Logstash vs Fluentd — Which one is better ! When it comes to collecting and shipping logs to Elastic stack, we usu..

smoh.tistory.com

 

Fluentd를 사용해보고자 했지만 미뤄졌던 일이 이제야 사용해 볼만한 기회가 찾아와 좀 더 자세히 포스팅하기로 했습니다.

 

EFK 스택은 기존 ELK 스택의 변형입니다. 기존 로그 수집 미들웨어인 Logstash 대신 Fluentd를 사용한 스택입니다. Elasticsearch, Logstash, Fluentd, Kibana에 대한 설명은 이 글에서 다루지 않도록 하겠습니다.

 

이 글의 예시는 Visual Studio의 dotNet5.0을 이용해 예시 프로젝트를 만들고 그 프로젝트의 로그를 fluentd를 통해 elasticsearch로 보낸 뒤 kibana에서 확인하는 과정으로 진행하도록 하겠습니다.

 

해당 내용은 다음 git 저장소에서 확인할 수 있습니다: FluentdTester

 

GitHub - smoh-dev/FluentdTester: https://smoh.tistory.com/415

https://smoh.tistory.com/415. Contribute to smoh-dev/FluentdTester development by creating an account on GitHub.

github.com

 

 

 

2. 테스트용 프로젝트 생성.

 

VisualStuio를 열고 dotNet 5.0을 사용해 WebAPI 프로젝트를 생성합니다. 프로젝트는 HTTPS를 지원하지 않도록 설정하였으며 Docker 지원은 체크해 생성합니다.

 

 

로그를 남기기 위해 Serilog를 사용하도록 합니다. NuGet 패키지 관리자를 열어 Serilog, Serilog.Sinks.File, Serilog.Formatting.Elasticsearch 패키지를 설치합니다.

 

 

Serilog는 로그를 남기기 위함이며 Serilog.Sink.File은 로그를 파일에 쓰기 위함이고 Serilog.Formatting.Elasticsearch는 로그 형식을 Elasticseach에 맞게 남겨주는 데 사용합니다.

 

새 컨트롤러를 생성해 Get요청이 오면 로그를 남기도록 코드를 작성합니다.

 

using Microsoft.AspNetCore.Mvc;
using Serilog;
using Serilog.Core;
using Serilog.Formatting.Elasticsearch;

namespace FluentdTester
{
    [Route("api/[controller]")]
    [ApiController]
    public class LogController : ControllerBase
    {
        private readonly Logger logger;
        public LogController()
        {
            logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .Enrich.FromLogContext()
                .Enrich.WithProperty("Service", "LogTester")
                .WriteTo.File(new ElasticsearchJsonFormatter(), "logs/fluentd-test.log", rollingInterval: RollingInterval.Day)
                .CreateLogger();
        }
        // GET: api/log/test
        [HttpGet("test")]
        public IActionResult Get()
        {
            logger.Debug(string.Format("This is sample log."));
            return Ok();
        }
    }
}

 

다음은 편의를 위한 코드 수정입니다. Production 환경에서도 swagger에 접속할 수 있도록  Startup.cs 파일을 수정합니다.

 

// Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "FluentdLogTester v1"));
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}

 

이제 도커 이미지로 빌드해 봅시다. 자동으로 생성된 Dockerfile을 우클릭 해 Docker 이미지 빌드를 클릭합니다.

 

 

정상적으로 빌드되는지 확인합니다. 해당 방식으로 이미지를 빌드하면 자동으로 latest 태그가 설정되어 빌드가 됩니다.

 

 

 

3. fluentd 추가하기.

 

앞서 작성한 프로그램이 로그를 남기면 fluentd는 그 로그파일을 읽어 Elasticsearch로 로그를 전송하는 역할을 담당하게 될 겁니다. 이렇게 로그 파일을 추적해 로그를 전송하는 방식은 fluentd의 "tail" Input Plugin을 사용합니다. 자세한 내용은 공식 홈페이지를 참고해 주시기 바랍니다: Fluentd - tail

 

로그를 읽어 들이는 Input Plugin이 있으면 반대로 읽은 로그를 Elasticsearch로 전송하는 기능도 있습니다. 다행히도 별도의 구현을 할 필요 없이 바로 Elasticsearch로 로그를 보낼 수 있도록 Elasticsearch Output Plugin을 제공해주고 있습니다. 자세한 내용은 공식 홈페이지를 참고해 주시기 바랍니다: Fluentd - elasticsearch

 

이제 tail과 elasticsearch를 사용할 수 있도록 fluentd의 설정 파일을 작성하도록 하겠습니다.

 

#/fluentd/conf/fluent.conf
<source>
  @type tail
  path /app/logs/fluentd-tester/*.log
  pos_file /app/logs/td-agent/logtest.log.pos
  tag logtest
  <parse>
    @type json
  </parse>
</source>
<match *.**>
  @type copy
  <store>
    @type elasticsearch
    host elasticsearch
    port 9200
    logstash_format true
    logstash_prefix fluentd
    logstash_dateformat %Y%m%d
    include_tag_key true
    type_name access_log
    tag_key @log_name
    flush_interval 1s
  </store>
  <store>
    @type stdout
  </store>
</match>

 

앞서 작성한 프로그램의 로그를 읽어 elasticsearch로 전송하는 설정 파일입니다. 다음으로는 이 설정 파일과 elasticsearch 플러그인을 사용할 수 있도록 fluentd 이미지를 빌드하는 dockerfile을 작성합니다.

 

# /fluentd/dockerfile
FROM fluentd:v1.9.1-debian-1.0
COPY /conf/* /fluentd/etc/
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "4.3.3"]
USER fluent

 

이제 이 dockerfile을 사용해 fluentd 이미지를 빌드해 줍니다.

 

$ docker build . -t my-fluentd:0.0.1

 

** 여기서는 conf 파일을 포함하는 이미지를 미리 빌드해서 사용합니다. 

** 만약 docker-compose에서 새로 빌드하고자 한다면 dockerfile의 "COPY /conf/* /etc/"를 사용할 수 없으므로 별도로 conf 파일을 옮겨주는 작업이 필요합니다. 

 

 

 

4. 배포를 위한 docker-compose 작성.

 

이 글은 간단한 테스트를 위한 글이므로 테스트 프로그램, fluentd, Elasticsearch, Kibana 모두 한 docker-compose 파일 내에 작성해 배포하도록 진행하겠습니다.

 

version: '3.9'

volumes:
  test-logs:

services:
  fluentd-tester:
    image:  fluentdtester:latest
    volumes:
        - test-logs:/app/logs
    depends_on:
        - "fluentd"
    expose:
        - "8080"
    ports:
        - "8080:80"

  fluentd:
    image: my-fluentd:0.0.1
    user: root
    volumes:
      - test-logs:/app/logs/fluentd-tester
    depends_on:
      - "elasticsearch"
    ports:
      - "24224:24224"
      - "24224:24224/udp"

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
    environment:
      - "discovery.type=single-node"
    expose:
      - "9200"
    ports:
      - "9200:9200"

  kibana:
    image: kibana:7.10.1
    depends_on:
      - "elasticsearch"
    ports:
      - "5601:5601"

 

내용은 간단합니다. 앞서 빌드한 이미지인 fluentdtester:latest와 my-fluentd:0.0.1 그리고 elasticsearch와 kibana를 실행시킵니다. fluentd-tester와 fluentd 서비스는 test-logs라는 이름의 볼륨을 이용해 데이터를 공유하도록 해주었습니다.

 

이를 통해 fluentd-service에서 작성한 로그파일에 fluentd가 접근해 tail로 로그파일을 elasticsearch로 전송합니다.

 

다음 명령어를 통해 docker-compose를 실행시켜봅시다.

 

$ docker-copmpose up -d

 

 

정상적으로 컨테이너들이 실행된 것을 확인할 수 있습니다.

 

 

 

5. 동작 확인.

 

컨테이너가 정상적으로 실행되었다면 이제 테스트 로그를 남겨봅시다. 다음 주소로 이동해 swagger를 사용해 로그를 남깁시다.

 

http://localhost:8080/swagger/index.html

 

 

정상적으로 로그가 남았음을 확인하고 싶다면 컨테이너에 접속해 /app/logs 폴더에 들어가 확인해보시면 됩니다.

 

이제 키바나에 접속해 인덱스 패턴을 생성해야 합니다. 다음 주소로 접속해 인덱스 패턴을 생성합니다.

 

http://localhost:5601/app/management/kibana/indexPatterns

 

 

Create index 화면에서 "fluentd-*" 패턴을 생성해줍니다.

 

 

Time Field는 @timestamp를 선택합니다.

 

 

이제 discover로 이동합니다.

 

http://localhost:5601/app/discover/

 

 

앞서 남긴 로그를 확인할 수 있습니다.

 

 

 

 

 

반응형

 

우분투에 Fluentd를 설치하는 방법에 대해 알아봅니다.

 

 

 

0. 사전 준비

 

Fluentd를 설치할 우분투 환경을 미리 준비합니다. 해당 글에선 우분투 20.04 버전을 기준으로 설명합니다.

 

 

 

1. 설치 전 설정.

 

Fluentd를 설치하기 전에 이후 단계에서 문제가 발생하지 않도록 환경을 올바르게 설정할 것을 권장합니다. 공식 문서에 따르면 NTP설정, 최대 File Descriptors 숫자 설정, 네트워크 커널 매개 변수 최적화를 먼저 수행할 것을 권고합니다.

 

먼저 NTP를 설정해줍니다. 정확한 현재 타임 스탬프를 갖도록 노드에 chrony, ntpd 등과 같은 NTP 데몬을 설정하는 것이 좋습니다. 이는 모든 프로덕션 등급 로깅 서비스에 중요합니다. Amazon Web Services 사용자의 경우 AWS에서 호스팅 하는 NTP 서버를 사용하는 것이 좋습니다.

 

다음은 File Descriptors의 최대치를 늘려줘야 합니다. 만약 td-agent 패키지를 사용하는 경우이 값은 기본적으로 설정되므로 스킵하셔도 됩니다. 이 글은 td-agent를 이용할 것이므로 변경 방법만 설명한 뒤 넘어가도록 하겠습니다. 저와 동일한 방법으로 설치를 원하시는 분은 NTP 설정만 하시고 넘겨주시면 됩니다.

 

다음 명령어를 통해 현재 시스템의 File Descriptors의 최댓값을 확인해 줍시다. 만약 해당 값이 1024라면 수정이 필요합니다. 

 

$ ulimit -n

 

 

/etc/security/limits.conf 파일을 열고 다음 내용을 추가해 주세요.

 

$ sudo /etc/security/limits.conf

root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536

 

 

저장 후 시스템을 리부팅 시켜줍니다. 만약 systemd에서 fluentd를 실행한다면 LimitNOFILE = 65536 옵션도 사용할 수 있습니다.

 

Fluentd 인스턴스가 많은 고부하의 환경이라면 네트워크 커널 매개 변수 최적화가 필요합니다. 다음 구성을 /etc/sysctl.conf에 추가합니다.

 

net.core.somaxconn = 1024
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535

 

전 개발용으로 사용할 예정이기 때문에 네트워크 커널 매개 변수 최적화 과정도 생략하였습니다. 만약 변경사항을 적용했다면 sysctl -p 명령을 사용하거나 노드를 재부팅해야 합니다.

 

 

 

2. td-agent를 이용한 fluentd 설치.

 

td-agent는 Treasure Data, Inc.에서 관리하는 안정적인 Fluentd 배포 패키지입니다. Fluentd에서는 설치 프로세스를 자동화하기 위해 쉘 스크립트를 제공해 줍니다. /etc/apt/source.list.d/treasure-data.list에 새  apt 저장소를 등록하고 td-agent deb 설치를 시작해 봅시다.

 

$ curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agnet4.sh | sh

 

 

뭔가 자동으로 쭉 진행 되고 위처럼 맨 마지막에 Installation complete. Happy Logging!이 찍혔다면 정상적으로 설치가 된 겁니다. 이제 데몬을 실행시켜줍시다.

 

$ sudo service td-agent start
$ sudo service td-agent status

 

 

 

3. HTTP를 통해 샘플 로그 업로드 해보기.

 

이제 샘플 로그를 한번 올려보겠습니다. 엔드포인트의 기본 포트는 8888입니다. 다음 명령어를 통해 설정값을 조회할 수 있으며 원하시면 여기서 변경할 수 있습니다.

 

$ vim /etc/td-agent/td-agent.conf

 

 

이제 HTTP 엔드포인트에서 로그를 수신해 stdout으로 라우팅 해보도록 하겠습니다. 다음 명령어를 확인해 주세요. td-agent 로그의 경우 /var/log/td-agent/td-agnet.log를 참고하시면 됩니다.

 

$ curl -X POST -d 'json={"json":"message"}' http://localhost:8888/debug.test
$ tail -n 1 /var/log/td-agent/td-agent.log

 

 

로그를 정상적으로 확인할 수 있습니다.

 

 

 

 

 

반응형

출처: https://medium.com/techmanyu/logstash-vs-fluentd-which-one-is-better-adaaba45021b

 

이 글은 다음 글을 번역한 글입니다: Logstash vs Fluentd — Which one is better!

 

Logstash vs Fluentd — Which one is better !

When it comes to collecting and shipping logs to Elastic stack, we usually hear about ELK — Elastic, Logstash and Kibana. It has almost…

medium.com

 

LogStash와 Fluentd에 대해 알아보며 유사점과 차이점에 대해 알아보고 어떤 로그 수집기가 대상 프로젝트에 더 어울리는지 알아봅니다.

 

 

 

0. 앞선 글.

 

로그를 수집하고 Elastic stack로 전달하고자 할 때 우리는 일반적으로 ELK - Elastic, Logstash, Kibana를 듣게 됩니다. 이제 ELK는 Elastic stack와 동의어가 되었을 정도입니다. 하지만 기술적으로 그 어디에도 완벽한 솔루션은 존재하지 않습니다.

 

Fluentd는 Docker나 Kubernetes 환경과 같은 마이크로 서비스의 로깅에 대해 인기를 끌고 있습니다. 이는 Fluientd가 Treasure Data에 의해 구축되었고 CNCF의 일부이기 때문입니다. 따라서 Fluentd는 Kubernetes, Prometheus, OpenTracing과 같은 CNCF 호스팅 프로젝트들과 훨씬 더 어울립니다.

 

최근 프로젝트에 대해 이 두 로그 수집기에 대해 평가할 일이 있었고 두 분석기에 대한 장단점을 조사한 뒤 어떤 사례에 어떤 로그 분석기가 더 적합한지 결정할 수 있었습니다. 이 비교의 목적은 둘 중 어떤 로그 분석기가 더 우월한지 선택하는 것이 아니라 어떤 사용 사례에 어떤 로그 분석기가 더 적합한지 찾는 것입니다.

 

 

1. LogStash와 Fluentd의 비교.

 

A. 보증

Logstash는 인기 있는 ELK stack의 일부이며 Fluentd는 Treasure Data에 의해 구축되었고 CNCF의 일부입니다. 

Fluentd 역시 Eleastic에 대해 훌륭한 지원을 제공합니다. Kubernetis, OpenTascing, Prometheus와 같은 CNCF 호스팅 프로젝트에서는 Fluentd가 더 좋은 선택이 될 수 있습니다.

 

B. 코드 언어

Logstash는 호스트에 자바 런타임이 필요한 JRuby입니다. Fluentd는 자바 런타임이 필요하지 않은 CRuby입니다.

Fluentd는 자바 런타임이 필요하지 않다는 이점이 있습니다.

 

C. 이벤트 라우팅.

Logstash는 if-else 조건에 기반에 이벤트가 라우팅 됩니다. 예를 들자면 다음과 같습니다.

output { if [loglevel] == "ERROR" and [development] == "production" { { ... } }

 

Fluentd는 태그에 기반해 이벤트가 라우팅 됩니다. 예를 들자면 다음과 같습니다.

<match logtype.error> type ... </match>

 

이벤트에 태그를 지정하고 각 이벤트 유형에 대해 if-else를 사용하는 것이 더 쉽기 때문에 Fluentd가 더 나은 라우팅 접근 방식을 제공합니다. 만약 로그에 다른 종류의 타입이 많아진다면 Logstash는 관리하기가 쉽지 않을 것입니다.

 

D. 플러그인

Logstash는 200개 이상의 플러그인이 존재하며 Fluentd는 500개 이상의 플러그인이 존재합니다.

Logstash는 공식 git 저장소에 모든 플러그인을 가지고 있지만 Fluentd에는 아직 플러그인에 대한 중앙 git 저장소가 없습니다.

 

E. 성능

LogStash는 Fluentd보다 상대적으로 좀 더 많은 메모리를 사용합니다.

Fluentd가 약간 wrt 성능에 대해 약간 더 나은 평가를 받고 있습니다. 하지만 두 로그 수집기 모두 가벼운 수준이며 성능 측면에서 두 로그 수집기 모두 우수합니다.

 

F. 전송

Logstash는 메모리 상의 큐에 고정된 크기인 20개의 이벤트를 갖고 있으며 재시작 시 지속성을 위해 Redis 또는 Kafka와 같은 외부 큐에 의존합니다. Fluentd는 고도로 구성 가능한 버퍼링 시스템을 보유하고 있으며, 메모리상에 또는 디스크에 끝없는 배열로 구성될 수 있습니다.

OpenStack Summit 2015에서 이 강연에서 논의된 바와 같이, 둘 다 대부분의 사용 사례에서 잘 수행되고 10,000 개 이상의 이벤트를 문제없이 지속적으로 수행할 수 있습니다.

 

E. 엔터프라이즈급 지원

LogStash와 Fluentd 모두 지원합니다. 

LogStash가 공식적인 Elastic 스택의 일부이므로 LogStash의 지원이 더 낫습니다.

 

 

 

2. 사용 사례.

 

A. 로그 수집

Fluentd는 Docker에 Fluentd용 로깅 드라이버가 내장되어 있습니다. 즉, Fluentd에 로그를 푸시하기 위해 컨테이너에 추가 에이전트가 필요하지 않습니다. 로그는 STDOUT에서 Fluentd 서비스로 직접 전송되며 추가 로그 파일이나 영구 저장소가 필요하지 않습니다. 단지 docker-compose 파일에 다음과 같은 섹션을 추가해주면 됩니다.

logging: driver: "fluentd" options: fluentd-address: <fluentd IP>:<fluentd service port> tag: testservice.logs

 

Logstash의 경우 STDOUT의 애플리케이션 로그는 도커 로그에 기록되고 파일에 기록됩니다. 그런 다음 파일의 로그를 filebeat와 같은 플러그인을 통해 읽어서 Logstash로 보내야 합니다.

 

B. 로그 파싱.

Fluentd에는 json, regex, csv, syslog, apache, nginx 등과 같은 표준 내장 파서와 로그를 파싱 하는 grok과 같은 외부 파서가 있습니다.

Logstash에는 표준 형식 외에도 집계, geoip 등과 같은 필터링 및 구문 분석을 위한 더 많은 플러그인이 있습니다.

 

C. 메트릭 데이터 수집.

Fluentd는 시스템 / 컨테이너 측정 항목을 수집하는 즉시 사용할 수 있는 기능이 없습니다. 그러나 Prometheus exporter에서 메트릭을 스크랩 할 수 있습니다.
Logstash는 시스템 / 컨테이너 메트릭을 수집하고 이를 Logstash로 전달하는 즉시 사용 가능한 Metricbeat를 지원합니다. 또한 Logstash는 Prometheus exporter에서 메트릭을 스크랩 할 수도 있습니다.

 

D. 스크랩

Fluentd에는 메트릭, 상태 확인 등과 같이 http 엔드 포인트에서 데이터를 가져올 수있는 http_pull 플러그인이 있습니다.
Logstash에는 http 엔드 포인트에서 데이터를 가져올 수있는 Elastic에서 지원하는 http 플러그인이 있습니다.

 

 

 

3. 그러면 무엇을 이용해야 할까요?

 

위의 사용 사례를 살펴보면 Fluentd와 Logstash가 특정 요구 사항에 적합하다는 것이 분명합니다. 가장 좋은 점은 둘 다 동일한 환경에서 공존할 수 있으며 특정 사용 사례에 사용할 수 있다는 것입니다.

 

기존 VM의 모놀리틱 한 애플리케이션의 경우 로그, 메트릭, 상태 등의 수집을 위해 여러 에이전트를 지원하므로 LogStash가 확실한 선택처럼 보입니다. 

 

Docker 및 Kubernetes에서 호스팅 되는 마이크로 서비스의 경우에는 Fluentd가 기본 제공 로깅 드라이버와 원활한 통합을 고려할 때 훌륭한 선택으로 보입니다. json, nginx, grok 등과 같이 일반적으로 사용되는 모든 파서를 지원하기도 합니다.

 

ELK-EFK 하이브리드 구조에서는 아래와 같이 두 로그 수집기를 동시에 사용하여 지원할 수 있습니다. 

 

 


이 글이 혼란을 줄이고 더 나은 결정을 내리는 데 도움이되기를 바랍니다.

 

 

 

 

 

반응형

+ Recent posts