ELK Stack을 이용한 로그 관제 시스템 만들기

in #elk5 years ago


안녕하세요. 개발자 모도리입니다.
서비스 운영 중 로그 관리가 필요하여 예전에 구축했었던 ELK를 이용한 로그 관제 시스템을 다시 구성해 봤습니다.

ELK(ElasticSearch, LogStash, Kibana) 설치

구조도

  • 로그를 생성하는 서버들에 Filebeat를 설치하고, 로그를 집계할 서버에 ELK를 설치한다.
  • Filebeat에서 LogStash로 로그를 전송하고 LogStash에서 한번 필터링을 거친 로그들이 ElasticSearch에 저장된다.
  • 저장 된 로그는 Kibana를 통해서 시각화하여 볼 수 있다.

권장 사항

  • 메모리 4GB 이상 (ELK를 한 대에 서버에 설치할 경우)
  • JAVA 8 사용

JAVA 설치

Repository 추가 및 설치

sudo add-apt-repository ppa:webupd8team/java

sudo apt update

sudo apt install oracle-java8-installer

sudo apt install oracle-java8-set-default

자바 버전 확인

java -version

ElasticSearch 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.2.deb

sudo dpkg -i elasticsearch-6.6.2.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl daemon-reload

sudo systemctl enable elasticsearch.service

sudo systemctl start elasticsearch.service

sudo systemctl status elasticsearch.service

 ● elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 11:58:03 UTC; 13min ago

(나중에 필요한 경우) 서비스 등록 해지 및 중지

sudo systemctl disable elasticsearch.service

sudo systemctl stop elasticsearch.service

설치 확인

curl -X GET "localhost:9200/"

{
  "name" : "xQub8IM",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "7RLVGGnxR6qHbV9mYqA_mg",
  "version" : {
    "number" : "6.6.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "3bd3e59",
    "build_date" : "2019-03-06T15:16:26.864148Z",
    "build_snapshot" : false,
    "lucene_version" : "7.6.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
 }

Kibana 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/kibana/kibana-6.6.2-amd64.deb

sudo dpkg -i kibana-6.6.2-amd64.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable kibana.service

sudo systemctl start kibana.service

sudo systemctl status kibana.service

 ● kibana.service - Kibana
   Loaded: loaded (/etc/systemd/system/kibana.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 11:58:03 UTC; 13min ago

설치 확인

curl -v [Log 수집 서버 IP]:5601

* Rebuilt URL to: localhost:5601/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5601 (#0)
> GET / HTTP/1.1
> Host: localhost:5601
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< location: /app/kibana
< kbn-name: kibana
< kbn-xpack-sig: 292ada877125f67092b9a6a4b59b08ca
< content-type: text/html; charset=utf-8
< cache-control: no-cache
< content-length: 0
< connection: close
< Date: Tue, 26 Mar 2019 02:11:00 GMT
< 
* Closing connection 0

LogStash 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/logstash/logstash-6.6.2.deb

sudo dpkg -i logstash-6.6.2.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable logstash.service

sudo systemctl start logstash.service

sudo systemctl status logstash.service

 ● logstash.service - logstash
   Loaded: loaded (/etc/systemd/system/logstash.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 12:10:22 UTC; 17s ago

FileBeat 설치 (Log 생성 서버, Amazon Linux(CentOS 계열))

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.6.2-x86_64.rpm

sudo rpm -vi filebeat-6.6.2-x86_64.rpm

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable filebeat.service

sudo systemctl start filebeat.service

sudo systemctl status filebeat.service

 ● filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch.
   Loaded: loaded (/usr/lib/systemd/system/filebeat.service; enabled; vendor preset: disabled)
   Active: active (running) since 월 2019-03-25 21:41:23 KST; 51s ago

환경 설정

ElasticSearch

설정 파일 수정

sudo vi /etc/elasticsearch/elasticsearch.yml

  • ElasticSearch와 binding 할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 9200)
network.host : 0.0.0.0

서비스 재시작

sudo systemctl restart elasticsearch.service

Kibana

설정 파일 수정

sudo vi /etc/kibana/kibana.yml

  • Kibana와 binding할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 5601)
server.host : "0.0.0.0"
elasticsearch.url : "http://elasticsearch_server_address:9200"

서비스 재시작

sudo systemctl restart kibana.service

LogStash

설정 파일 생성

sudo vi /etc/logstash/conf.d/kstarlive-web.conf

input {
 beats {
   port => 5044
 }
}

filter {
  if [fields][log_type] == "nginx_access" {
    grok {
      match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\"\"%{DATA:[nginx][access][agent]}\""] }
      remove_field => "message"
    }
    mutate {
      add_field => { "read_timestamp" => "%{@timestamp}" }
    }
    date {
      match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
      remove_field => "[nginx][access][time]"
    }
    useragent {
      source => "[nginx][access][agent]"
      target => "[nginx][access][user_agent]"
      remove_field => "[nginx][access][agent]"
    }
    geoip {
      source => "[nginx][access][remote_ip]"
      target => "[nginx][access][geoip]"
    }
  }
}

output {
  if([fields][log_type] == "nginx_access") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "access-log-%{+YYYY.MM.dd}"
    }
  }
  else if([fields][log_type] == "nginx_error") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "error-log-%{+YYYY.MM.dd}"
    }
  }
  else if([fields][log_type] == "laravel") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "laravel-log-%{+YYYY.MM.dd}"
    }
  }
}
  • filebeat에서 로그 데이터를 받아서 log_type에 따라서 별도의 index를 사용해서 elasticsearch에 저장 하는 설정
  • logstash 필터링 설정 참고

서비스 재시작

sudo systemctl restart logstash.service

Filebeat

모듈 설치 및 설정

  • nginx 모듈 사용 설정

sudo filebeat modules enable nginx

  • 설정 된 모듈 확인

sudo filebeat modules list

  • 초기 환경 설정

sudo filebeat setup -e

  • 모듈 설정 파일 수정

sudo vi /etc/filebeat/modules.d/nginx.yml

- module: nginx
  # Access logs
  access:
    enabled: true
    input:
      fields:
        server_name: dev-web
        log_type: nginx_access
    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/home/ec2-user/kstarlive_web/storage/logs/nginx/access.log"]

  # Error logs
  error:
    enabled: true
    input:
      fields:
        server_name: dev-web
        log_type: nginx_error

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/home/ec2-user/kstarlive_web/storage/logs/nginx/error.log"]

설정 파일 수정

sudo vi /etc/filebeat/filebeat.yml

#=========================== Filebeat inputs =============================
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/ec2-user/kstarlive_web/www/storage/logs/*.log
  fields:
    server_name: dev-web
    log_type: laravel

#-------------------------- Elasticsearch output ------------------------------
#output.elasticsearch:

#----------------------------- Logstash output --------------------------------
output.logstash:
  # The Logstash hosts
  hosts: ["10.0.1.45:5044"]
  • laravel에서 발생하는 에러 로그를 수집하기 위한 설정. fields는 추가 데이터를 지정하는 부분 kibana에서 server_name 별로 필터링해서 보여주고자 할 때 이런식으로 각 서버 마다 server_name을 다르게 설정하면, 원하는 서버만 필터링해서 보기 편하다. elasticsearch에 바로 데이터를 보내지 않고, logstash를 거치기 때문에 elasticsearch 설정은 주석 처리한다.

서비스 재시작

sudo systemctl restart filebeat.service

시각화

  • 브라우저에 [Kibana가 설치 된 서버 주소]:5601 를 입력하여 Kibana에 접속한다.

인덱스 패턴 만들기

  • 좌측 메뉴 Management에 들어가서 Kibana > Index Patterns 선택

  • Create index pattern을 누르면 Define index pattern 라는 입력창이 나온다.
  • LogStash에서 output으로 나오게 한 index 종류들이 나오는데 묶어서 볼 것 로그들의 패턴을 입력한다.

  • access-log-* 과 같은 형식으로 입력하면 access log만 모아서 볼 수 있다.
  • 패턴 입력 후 Next step을 누르면 Time Filter field name을 선택하는 화면이 나오는데, @timestamp를 선택한다.

데이터 탐색하기

  • 좌측 메뉴 Discover에 들어가서, Add a filter + 밑의 드롭다운 메뉴에서 만들어 놓은 인덱스를 선택한다.

  • 보고 싶은 필드를 확인하고 add 버튼을 눌러서 해당 필드만 볼 수 있도록 한다.
  • filebeat 설정에서 추가했던 fields.log_type, fields.server_name가 있는 것을 확인할 수 있다.

  • 해당 데이터 중 특정 값을 필터링하려면 Add a filter + 버튼을 눌러서 특정 필드를 선택하고 is, is not 등을 선택하고 원하는 값을 입력한다.

  • 상단의 Save 버튼을 눌러서 필터링 된 결과를 저장한다.

그래프 만들기

  • 좌측의 Visualize 메뉴를 선택하고 + 버튼을 누른다.
  • 원하는 시각화 컴포넌트 종류를 선택한다.

  • Horizontal Bar를 선택한 경우

  • Buckets > X-Axis를 클릭하고, Aggregation에서 Filters를 선택한다.

  • Add filter를 눌러서 filter, filter label을 입력하고 상단의 ▶︎ 버튼을 눌러서 오른쪽에서 미리보기를 확인한다.

  • 상단의 Save를 눌러서 시각화 한 화면을 저장한다.

대시보드 구성하기

  • 좌측 메뉴에 Dashboard를 선택하고 Create new dashboard 눌러서 새로운 대시보드 화면을 만든다.
  • 상단의 Add를 누르면 데이터 탐색하기, 그래프 만들기 에서 저장 한 시각화 검색 결과를 불러올 수 있다.

  • 원하는 구성을 만든 후 저장한다.

트러블 슈팅

JAVA 버전 문제

Unrecognized VM option 'UseParNewGC'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
chmod: cannot access '/etc/default/logstash': No such file or directory

메모리 부족 문제

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000ca660000, 899284992, 0) failed; error='Cannot allocate memory' (errno=12)

디스크 부족 문제

[2019-03-26T04:35:00,614][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 403 ({"type"=>"cluster_block_exception", "reason"=>"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"})
  • 디스크 부족할 경우 발생, 용량을 늘려준다.
  • read only로 설정 된 값을 풀어준다.
    • curl -X PUT "localhost:9200/*/_settings" -H 'Content-Type: application/json' -d'{"index.blocks.read_only_allow_delete": null}'
  • 오래된 index를 삭제한다.

참고


  • 저는 블록체인 개발사 (주)34일에서 블록체인 엔지니어로 일하고 있습니다.
  • 880만 팔로워 전세계 1위 한류 미디어 케이스타라이브(KStarLive)와 함께 만든 한류 플랫폼에서 사용되는 케이스타코인(KStarCoin) 프로젝트를 진행 중입니다. 팬 커뮤니티 활동을 하면서 코인을 얻을 수 있으며, 한류 콘텐츠 구매, 공연 예매, 한국 관광 상품 구매, 기부 및 팬클럽 활동 등에 사용 될 계획입니다.
Sort:  

Congratulations @modolee! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.35
TRX 0.12
JST 0.040
BTC 70601.40
ETH 3576.96
USDT 1.00
SBD 4.75