본문 바로가기

카테고리 없음

ELK 로그시스템 구현하기 - 2 (With Nginx & SpringBoot & Docker)

https://jobc.tistory.com/221

 

ELK 로그시스템 구현하기 - 1 (With Nginx & SpringBoot & Docker)

로컬에서 Nginx와 Spring Boot의 로그를 ES쌓는 파이프라인 ELK을 구현해본다. Spring Boot Application을 Docker로 띄우기 첫번째 스텝은 Nginx와 Spring Boot를 Docker로 띄어 통신이 되는지 확인한다. Spring B..

jobc.tistory.com

 

  • 로컬에서 80포트로 curl을 날림
  • Docker Nginx가 요청을 받고 8080포트로 리버시프록시
  • Docker Spring Boot App이 요청을 받고 응답

위 글에서 3단계를 진행했다.

 

이제 서버가 띄어졌으니 여기에 본격적인 로그 시스템을 구축한다.

Nginx 로그의 시스템을 구축할 것이냐 또는 WAS의 로그를 구축할 것이냐 선택사항이긴하지만, 여기서는 Nginx의 로그 시스템을 구현한다.

최종적으로 기록될 로그의 플로우는 아래와 같을 것이다.

Nginx 로그 > Filebeat > Logstash > Elastic Search > Kibana

ELK 구조에서 Filebeat만 추가한 방식인데, 꼭 이처럼 안해도 되고 Nginx > Logstash > ES > Kibana 또는 Nginx > Filebeat > ES > Kibana 등 다양한 플로우로 구현할 수 있다.

다만 여기서 Filebeat를 추가한 이유는 Logstash로 바로 로그를 쌓는 것보다 Filebeat가 더 가볍기 때문에 부하가 많은 시스템에서는 로그 유실을 방지할 수 있다.

 

Filebeat 설정 및 이미지 생성

첫번째로 Filebeat의 설정파일과 이미지 파일을 생성한다.

아래와 같이 filebeat.yml을 작성하여 설정파일을 준비한다.

# input 설정
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/*.log

# Multiple Log를 수집하는 경우, 아래와 같이 추가로 입력
# - type: log
# 	enabled: true
# 	paths: []

# output 설정
output.logstash:
  enabled: true
  hosts: ["logstash:5044"]
  # FIXME: Cannot reach the hosts of Logstash

# output.elasticsearch:
#   hosts: ["http://elasticsearch:9200"]
#   username: "elastic"
#   password: "changeme"

# filebeat와 함께 제공된 샘플 Kibana 대시보드를 사용하는 경우
setup.kibana:
  host: "http://kibana:5601"
  username: "elastic"
  password: "changeme"

이미지 파일은 별다른 설정없이 그대로 가져와서 Dockerfile을 작성한다.

FROM docker.elastic.co/beats/filebeat:7.3.2

여기까지 Filebeat의 준비는 완료되었다.

ELK 설정 및 오픈소스

ELK의 기본 이미지와 설정은 오픈소스를 활용한다.

$ git clone https://github.com/deviantony/docker-elk.git

그 이후 설정파일만 약간 수정해준다.

Elastic Search & Kibana 설정 변경

$ vi docker-elk/elasticsearch/config/elasticsearch.yml

X-pack 라이센스가 있다면 상관없지만, 무료로 사용할 것이라면 ES와 Kibana 설정에서 X-pack 설정을 주석 처리한다.

## 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

## 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
# xpack.monitoring.collection.enabled: true

Kibana 설정도 위와 마찬가지로 수정한다.

$ 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
#
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
# xpack.monitoring.ui.container.elasticsearch.enabled: true

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

Logstash 설정 수정

Logstash도 위와 같이 X-pack 관련 설정은 주석처리를 하고, Filebeat가 추가되었으므로 관련 설정을 수정해준다.

input {
	beats {
		port => 5044
	}
}

## Add your filters / logstash plugins configuration here

output {
	elasticsearch {
		hosts => "elasticsearch:9200"
		index => "nginx_log"
		user => "elastic"
		password => "changeme"
	}
	stdout { codec => rubydebug }
}

여기까지 작성했다면, 아래와 같은 디렉토리 구조가 됐을 것이다.

├── spring-app
│   ├── application.jar
│   └── Dockerfile
├── elasticsearch
│   ├── config
│   │   └── elasticsearch.yml
│   └── Dockerfile
├── filebeat
│   ├── filebeat.yml
│   └── Dockerfile
├── kibana
│   ├── config
│   │   └── kibana.yml
│   └── Dockerfile
├── logstash
│   ├── config
│   │   └── logstash.yml
│   ├── Dockerfile
│   └── pipeline
│       └── nginx.conf
└── nginx
	  ├── nginx.conf
	  └── log
	      ├── access.log
	      └── error.log

 

 

Docker-compose 작성

이제 위에서 작성한 설정파일과 이미지파일을 Docker-compose를 이용해 조합할 차례이다.

docker-compose.yml 파일은 아래와 같이 작성했다.

version: "3.2" # 버전은 3.2로 해줘야한다.

services:
  elasticsearch:
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      discovery.type: "single-node"
      #ELASTIC_PASSWORD: changeme
    networks:
      - elk

  logstash:
    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./logstash/config/logstash.yml
        target: /usr/share/logstash/config/logstash.yml
        read_only: true
      - type: bind
        source: ./logstash/pipeline
        target: /usr/share/logstash/pipeline
        read_only: true
    ports:
      - "5000:5000"
      - "9600:9600"
    expose:
      - "5044"
    environment:
      LS_JAVA_OPTS: "-Xmx256m -Xms256m"
    networks:
      - elk
    depends_on:
      - elasticsearch

  kibana:
    build:
      context: kibana/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./kibana/config/kibana.yml
        target: /usr/share/kibana/config/kibana.yml
        read_only: true
    ports:
      - "5601:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

  spring-app:
    image: spring-app:0.1
    networks:
      - elk

  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/log:/var/log/nginx
    depends_on:
      - spring-app
    networks:
      - elk

  filebeat:
    build: ./filebeat
    entrypoint: "filebeat -e -strict.perms=false"
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
      - ./nginx/log:/var/log/nginx
    networks:
      - elk
    depends_on:
      - spring-app
      - nginx
      - logstash
      - elasticsearch
      - kibana
    links:
      - logstash

networks:
  elk:
    driver: bridge

volumes:
  elasticsearch:

 

docker-compose 실행 및 확인

docker-compose up 명령어를 사용해 docker-compose를 실행한다.

띄어놓은 웹으로 요청을 날리고, 로그를 Kibana에서 확인해본다.

  1. localhost:5601 접속
  2. 왼쪽 메뉴에 Management → Kibana의 Index Patterns 으로 이동
  3. 우측 상단 Create index pattern → Index pattern 이름 지정 → Next step
  4. Time Filter 지정 후에 Create index pattern 클릭
  5. 왼쪽 메뉴 Discover → 4번에서 생성한 index name 선택