새소식

기술/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을 선택하면 실시간으로 로그를 확인할 수 있습니다.

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

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

 

 

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에서 잘 적용되었는지 확인합니다.

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

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