새소식

기술/Application

Docker-Compose를 이용하여 ELK Stack 시작하기

  • -

Docker-Compose를 이용하여 ELK Stack 시작하기

1) Docker와 Docker-Compose가 설치된 서버에서 다음 Github Repository를 Clone 합니다.

[centos@elk ~]$ git clone https://github.com/teichae/docker-elk

 

2) 실행하기 앞서 환경 설정을 해야 합니다.
먼저 elasticsearch의 환경설정 파일을 다음과 같이 수정합니다.

[centos@elk docker-elk]$ vi ./docker-elk/elasticsearch/config/elasticsearch.yml

---
## Default Elasticsearch configuration from Elasticsearch base image.
## https://github.com/elastic/elasticsearch/blob/master/distribution/docker/src/docker/config/elasticsearch.yml
#
cluster.name: "docker-cluster"
network.host: 0.0.0.0

## Use single node discovery in order to disable production mode and avoid bootstrap checks
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
#
discovery.type: single-node

#X-Pack관련 내용 주석 처리 (유료 라이선스이기 때문에 주석처리합니다.)
## X-Pack settings
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-xpack.html
#
#xpack.license.self_generated.type: trial
#xpack.security.enabled: true
#pack.monitoring.collection.enabled: true

 

3) Kibana의 설정 파일도 다음과 같이 수정합니다.

[centos@elk docker-elk]$ vi ./docker-elk/kibana/config/kibana.yml
---
## Default Kibana configuration from Kibana base image.
## https://github.com/elastic/kibana/blob/master/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js
#elasticsearch.hosts를 서버 IP로 변경합니다.
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: [ "http://elasticsearch server ip:9200" ]

#X-Pack관련 내용 주석 처리 (유료 라이선스이기 때문에 주석처리합니다.)
#xpack.monitoring.ui.container.elasticsearch.enabled: true

## X-Pack security credentials
#
#elasticsearch.username: elastic
#elasticsearch.password: changeme

 

4) Logstash의 설정 파일도 다음과 같이 수정합니다.

[centos@elk docker-elk]$ vi ./logstash/config/logstash.yml
## Default Logstash configuration from Logstash base image.
## https://github.com/elastic/logstash/blob/master/docker/data/logstash/config/logstash-full.yml
#
http.host: "0.0.0.0"

#X-Pack관련 내용 주석 처리 (유료 라이선스이기 때문에 주석처리합니다.)
#xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
## X-Pack security credentials
#xpack.monitoring.enabled: true
#xpack.monitoring.elasticsearch.username: elastic
#xpack.monitoring.elasticsearch.password: changeme

 

5) logstash에서 로그를 가공하기 위해 filebeat 설정과 가공할 로그 내용을 삽입합니다.
본 가이드에서는 아파치 로그를 수집해보겠습니다.

[centos@elk docker-elk]# vi ./logstash/pipeline/logstash.conf

- 변경 내용 -
#filebeat 사용 선언 및 수신할 IP와 포트 지정
input {
  beats {
    port => 5000
    host => "0.0.0.0"
  }
}
#grok 형식으로 들어오는 로그를 가공하기 위해 필터 사용
# tags에 apache가 있을 경우 메시지 필드를 공용 아파치 로그로 변환하고 접속지의 IP를 기반으로 정보 가공 내용 추가하기
filter {
    if "apache" in [tags]{
        grok {
            match => { "message" => "%{COMMONAPACHELOG}" }
             }
        geoip {
            source => "clientip"
            target => "geoip"
              }
       }
}

# Logstash의 가공한 정보를 어디에 출력할지 설정
# 모든 데이터를 elk-%{+YYYY.MM.dd}라는 이름의 인덱스를 만들어서 Elasticsearch로 보내도록 설정
output {
        elasticsearch {
                hosts => "elasticsearch server ip:9200"
                index => "elk-%{+YYYY.MM.dd}"
        }
}

 

6) 이제 docker를 실행할 docker-compos,yml 파일을 열어서 ELASTIC_PASSWORD 옵션을 주석 처리하고 자바 메모리를 수정합니다.

version: '2'

services:

  elasticsearch:
    container_name:elasticsearch
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      ES_JAVA_OPTS: "-Xmx1024m -Xms1024m"
      #비밀번호는 사용하지 않기 때문에 주석처리
      #ELASTIC_PASSWORD: changeme
    networks:
      - elk

  logstash:
    container_name:logstash
    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "5000:5000"
      - "9600:9600"
    environment:
      LS_JAVA_OPTS: "-Xmx1024m -Xms1024m"
    networks:
      - elk
    depends_on:
      - elasticsearch

 kibana:
    container_name:kibana
    build:
      context: kibana/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - ./kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "5601:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

networks:

  elk:
    driver: bridge

 

7) yml을 잠깐 둘러보면 다음과 같은 용도의 형식을 갖고 있습니다.

version: '2'

services:

#서비스 이름
  elasticsearch: 
  #컨테이너가 사용할 이름 지정
    container_name:elasticsearch
    build:
  #이미지 빌드 시 사용할 context 및 args 지정
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
#저장소 지정
    volumes:
      - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
      - /etc/localtime:/etc/localtime:ro
#사용할 포트 지정 컨테이너 외부, 컨테이너 내부
    ports:
      - "9200:9200"
      - "9300:9300"
#옵션 지정
    environment:
      ES_JAVA_OPTS: "-Xmx1024m -Xms1024m"
      #사용할 메모리 설정
      #비밀번호는 사용하지 않기 때문에 주석처리
      #ELASTIC_PASSWORD: changeme
#사용할 네트워크 옵션    
    networks:
      - elk
#네트워크를 브릿지 모드로 사용할 것을 지정
networks:
  elk:
    driver: bridge

 

8) docker-compose up -d를 실행 (-d는 백그라운드 실행 옵션)

[centos@elk docker-elk]# docker-compose up -d
Starting docker-elk_elasticsearch_1 ... done
Starting docker-elk_logstash_1      ... done
Starting docker-elk_kibana_1        ... done

 

7) 모니터링할 로그가 있는 서버에 접속하여 Filebeat 설치 진행

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.2.1-x86_64.rpm
sudo rpm -vi filebeat-7.2.1-x86_64.rpm

 

8) Filebeat Config 파일 수정

sudo vi /etc/filebeat/filebeat.yml

 

9) 다음 내용으로 수정

  #=========================== Filebeat inputs =============================

  filebeat.inputs:

  # Each - is an input. Most options can be set at the input level, so
  # you can use different inputs for various configurations.
  # Below are the input specific configurations.

  - type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  # 아파치 로그의 위치를 지정 *로 와일드카드 형식을 사용할 수 있음
  # Logstash에서 Tags를 이용하여 필터 규칙을 사용하기 때문에 사용
  paths:
    - /var/log/httpd/access_*
  tags : ["apache"]


  #============================== Kibana =====================================

  # Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
  # This requires a Kibana endpoint configuration.
  setup.kibana:

  # Kibana Host
  # Scheme and port can be left out and will be set to the default (http and 5601)
  # In case you specify and additional path, the scheme is required: http://localhost:5601/path
  # IPv6 addresses should always be defined as: https://[2001:db8::1]:5601
  # Kibana Server IP입력
  host: "Kibana Server IP:5601"

  # Elasticsearch로는 로그를 보내지 않을 것이기 때문에 다 주석처리
  #-------------------------- Elasticsearch output ------------------------------
  #output.elasticsearch:
  # Array of hosts to connect to.
  #hosts: ["0.0.0.0:9200"]

  #Optional protocol and basic auth credentials.
  #protocol: "https"
  #username: "elastic"
  #password: "changeme"

  #----------------------------- Logstash output --------------------------------
  output.logstash:
  # The Logstash hosts
  # Logstash Server IP 입력
  hosts: ["logstash server ip:5000"]

  #================================ Processors =====================================
  # 로그 파일을 보낼 때 서버의 Host정보와 Cloud정보를 보낼지 설정하는 부분
  # 필요 여부에 따라 주석 처리 하거나 하지 않습니다.
  # Configure processors to enhance or manipulate events generated by the beat.

  #processors:
  #  - add_host_metadata: ~
  #  - add_cloud_metadata: ~

 

10) 저장 후 filebeat 실행

nohup filebeat -e -c /etc/filebeat/filebeat.yml &

 

11) elasticsearch로 로그가 잘 쌓이는지 확인하기

http://elasticsearch server:9200/_cat/indices
yellow open elk-2019.08.22       D3QLZcMVQeaiee4_Ae6PMw 1 1 561 0 769.8kb 769.8kb

 

12) Kibana에 접속하여 management로 이동-> Kibana 메뉴의 Index Patterns로 이동

 

13) 우측 상단의 Create index pattern->Index pattern에 불러올 Index 이름 지정->Time Filter로 사용할 Field Name 지정 후 Create index pattern 클릭

 

14) Index pattern 작성 후 Discover 메뉴로 이동하여 생성한 Index Name을 선택하면 실시간으로 로그를 확인할 수 있습니다.

 

 

Tomcat(catalina 로그) 수집하기

톰캣의 로그를 수집하기 위해 로그 패턴에 대해 분석을 해야 합니다.

아파치의 경우는 로그 패턴이 정형화되어 있지만, 톰캣 로그의 경우 개발자마다 튜닝을 다르게 할 수 있기 때문에 로그 패턴 분석이 필요합니다.

 

 

1) 로그 파일 열어보기

[centos@ip-10-0-10-49 logs]$ cat catalina.out
<로그 패턴>
23-Aug-2019 14:51:32.036 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
23-Aug-2019 14:51:32.091 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
23-Aug-2019 14:51:32.335 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 14840 ms
2019-08-23 14:51:32,346 JIRA-Bootstrap INFO      [c.a.j.config.database.SystemDatabaseConfigurationLoader] Reading database configuration from /home/centos/atlassian/application-data/jira/dbconfig.xml
2019-08-23 14:51:32,389 JIRA-Bootstrap INFO      [c.a.j.config.database.SystemDatabaseConfigurationLoader] Reading database configuration from /home/centos/atlassian/application-data/jira/dbconfig.xml
2019-08-23 14:51:32,390 JIRA-Bootstrap INFO      [c.a.j.config.database.SystemDatabaseConfigurationLoader] Reading database configuration from /home/centos/atlassian/application-data/jira/dbconfig.xml
2019-08-23 14:51:34,542 JIRA-Bootstrap INFO      [c.a.j.config.database.SystemDatabaseConfigurationLoader] Reading database configuration from /home/centos/atlassian/application-data/jira/dbconfig.xml
2019-08-23 14:51:34,558 JIRA-Bootstrap INFO      [c.a.jira.startup.JiraStartupLogger] 

    ___ Starting the JIRA Plugin System _________________

2019-08-23 14:51:43,467 JIRA-Bootstrap INFO      [c.a.j.config.database.SystemDatabaseConfigurationLoader] Reading database configuration from /home/centos/atlassian/application-data/jira/dbconfig.xml
2019-08-23 14:51:43,625 JIRA-Bootstrap INFO      [c.a.jira.startup.JiraStartupLogger] Running JIRA startup checks.
2019-08-23 14:51:43,625 JIRA-Bootstrap INFO      [c.a.jira.startup.JiraStartupLogger] JIRA pre-database startup checks completed successfully.
2019-08-23 14:51:43,863 JIRA-Bootstrap INFO      [c.a.j.config.database.DatabaseConfigurationManagerImpl] The database is not yet configured. Enqueuing Database Checklist Launcher on post-database-configured-but-pre-database-activated queue
2019-08-23 14:51:43,864 JIRA-Bootstrap INFO      [c.a.j.config.database.DatabaseConfigurationManagerImpl] The database is not yet configured. Enqueuing Post database-configuration launchers on post-database-activated queue
2019-08-23 14:51:43,881 JIRA-Bootstrap INFO      [c.a.jira.startup.LauncherContextListener] Memory Usage:
    ---------------------------------------------------------------------------------
      Heap memory     :  Used:  118 MiB.  Committed:  371 MiB.  Max: 1980 MiB
      Non-heap memory :  Used:   68 MiB.  Committed:   87 MiB.  Max: 1536 MiB
    ---------------------------------------------------------------------------------
      TOTAL           :  Used:  186 MiB.  Committed:  458 MiB.  Max: 3516 MiB
    ---------------------------------------------------------------------------------

 

2) 한 파일에서 2가지의 패턴으로 로그가 찍히고 있습니다. 패턴 1의 내용을 복사하여 다음 웹사이트에 복사합니다.
Test grok patterns : http://grokconstructor.appspot.com/do/match

 

3) 로그 입력 후 JAVA 형식이니 다음 링크를 참조하여 패턴을 만들어봅니다.
자바 패턴 : http://grokconstructor.appspot.com/groklib/java
패턴 중 앞 쪽이 일 월 연도 순으로 나온 패턴에 대해 다음 패턴을 입력하여 변환을 시도해봅니다.

 

4) 패턴이 잘 매치가 되어 로그들이 잘 변환되었습니다.

 

5) 두 번째 패턴 역시 입력 후 패턴을 확인 후 입력합니다.

 

6) 두번째 패턴의 경우 로그가 1줄이 아닌 멀티플 라인으로 출력되고 있기 때문에, 멀티 라인 패턴을 입력합니다.
멀티플 라인 테스트 : https://play.golang.org/p/uAd5XHxscu
examples_of_multiline_configuration : <링크>

 

7) 이제 완성 된 패턴을 Logstash Config에 입력합니다.
필터에 if 문을 사용하여 service라는 태그를 갖고 있는 로그는 조금 전 만든 패턴을 적용받을 수 있도록 설정합니다.

filter {
    if "apache" in [tags] {
        grok {
            match => [ "message", "%{COMMONAPACHELOG}" ]
             }
        geoip {
            source => "clientip"
            target => "geoip"
              }
       }
    else if "service" in [tags] {
        grok {
             match => ["message", "%{DATA:datestamp} %{DATA:timestamp} %{USERNAME:name} %{LOGLEVEL:loglevel}%{SPACE}\[%{USERNAME:header}\] %{JAVALOGMESSAGE:logmessage}"]
             match => ["message", "%{DATA:datestamp} %{DATA:timestamp} %{LOGLEVEL:loglevel}%{SPACE}\[%{USERNAME:header}\] %{JAVACLASS:class} %{JAVALOGMESSAGE:logmessage}"]
             }
       }
      }

 

8) 인덱스를 2곳으로 나눠서 관리하기 위해 output에도 if문을 사용하여 인덱스를 나누겠습니다.

output {
        if "apache" in [tags] {
                elasticsearch {
                hosts => "elasticsearch server ip:9200"
                index => "apache-%{+YYYY.MM.dd}"
        }
       }
        else if "service" in [tags] {
                elasticsearch {
                hosts => "elasticsearch server ip:9200"
                index => "tomcat-%{+YYYY.MM.dd}"
        }
      }
}

 

9) 설정을 저장하고 Logstash를 재시작합니다.

 

10) 로그를 전송하는 filebeat에도 보내줄 로그와 멀티플 라인 옵션을 적용해야 합니다.
filebeat로 이동하여 옵션을 다음과 같이 수정합니다.

- type: log
  enabled: true
  paths:
    - /home/centos/atlassian/jira/logs/catalina.out
  document_type: service
  tags : ["service"]

  multiline.pattern: '^[A-Z]|^[a-z]|^[[:space:]]|^\;'
  multiline.negate: false
  multiline.match: after

 

11) 설정을 저장 후 filebeat를 재시작합니다.

 

12) Elasticsearch에서 tomcat index가 잘 쌓이는지 확인합니다.

 

13) Kibana로 이동하여 index 설정 후 Discover에서 잘 적용되었는지 확인합니다.

'기술 > Application' 카테고리의 다른 글

Jenkins Pipeline을 이용한 Docker Image Build  (6) 2020.04.11
Docker를 이용한 Jenkins 설치  (0) 2020.04.11
Zabbix를 이용한 JMX 모니터링  (1) 2019.10.19
grafana  (0) 2019.10.15
Docker 설치 및 Docker-Compose 설치  (0) 2019.09.01
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.