본문 바로가기
ELK

서비스에 ELK적용하기

by 킹차니 2023. 8. 4.

ELK를 적용하는 이유

약 8개의 MSA가 존재하고 모든 MSA들의 로그를 일일히 각 EC2 인스턴스에 들어가서 확인하는 것은 매우 비효율적이었음. 특히 라이더타운 서버는 모두 스프링부트 + 도커 컨테이너 로 돌아가고 있기 때문에 도커 컨테이너 로그는 로그 내역이 쌓이면 이전에 로그 내역을 보기가 힘들었음. 그래서 로깅을 위해 ELK를 적용하기로 했음.

 

ELK 스택

시각화를 위한 kibana는 7.6.2 버전 사용.

데이터 저장, 검색 엔진을 위한 elasticsearch 역시 7.6.2 버전 사용.

logstash는 무거워서 사용하지 않음. 나중에는 모르겠지만 본인은 현재 단지 스프링 부트의 로그들을 저장하고 확인하기 위해서만 ELK를 사용하고 싶음. 해서 훨씬 가벼운 filebeat를 각 인스턴스에 설치하여 elasticsearch에 전송하고 싶었음.

 

아래와 같은 그림으로 구상하려 한다.

 

 

여기서부터는 그냥 내가 위의 그림처럼 구현해서 테스트해보기 위해 필요했던 작업을 메모하려한다. 그리고 아직 부족한게 많음. 로그 출력이나 키바나의 ui를 좀 더 커스텀 할 수 있다면 하는 것이 좋을 것 같다.

 

 

1. elasticsearch

일단 vpc 내에 ec2를 하나 만들고 elasticsearch를 실행시켜야한다. 먼저 도커 설치, 도커 컴포즈 설치했음.

그리고 9200를 열어줬음. 

난 docker compose로 실행시킬꺼라 docker-compose.yml 파일은 아래와 같다.

version: "3"

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
    restart: always
    volumes:
      - es-data:/usr/share/elasticsearch/data
    container_name: elasticsearch
    environment:
      - xpack.security.enabled=false
      - discovery.type=single-node
    ports:
      - "9200:9200"
    networks:
      - my-network

volumes:
  es-data:
    driver: local

networks:
  my-network:
    external: true

그리고 docker-compose up -d 로 실행시킨다.

 

 

2. kibana

이제 또 다른 ec2에 kibana를 실행시켜야한다.

역시 도커 컴포즈로 했고, 얘는 내가 직접 web으로 들어가서 봐야하기 때문에 vpc 중에서도 public 서브넷에 ec2인스턴스를 만들어줬다.

그리고 엘라스틱서치와 다르게 kibana.yml 을 호스트PC에 만들어서 -v 옵션을 넣으로 마운팅해줬다.

 

kibana.yml 파일은 아래와 같다.주석이 없는 부분만 보면 된다. server.host를 0.0.0.0으로 해서 외부에서 접속할 수 있도록 해준다.

# Kibana is served by a back end server. This setting specifies the port to use.
#server.port: 5601

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "0.0.0.0"
# Enables you to specify a path to mount Kibana at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
# from requests it receives, and to prevent a deprecation warning at startup.
# This setting cannot end in a slash.
#server.basePath: ""

# Specifies whether Kibana should rewrite requests that are prefixed with
# `server.basePath` or require that they are rewritten by your reverse proxy.
# This setting was effectively always `false` before Kibana 6.3 and will
# default to `true` starting in Kibana 7.0.
#server.rewriteBasePath: false

# The maximum payload size in bytes for incoming server requests.
#server.maxPayloadBytes: 1048576

# The Kibana server's name.  This is used for display purposes.
#server.name: "your-hostname"

# The URLs of the Elasticsearch instances to use for all your queries.
#elasticsearch.hosts: ["http://10.0.142.137:9200"]

# When this setting's value is true Kibana uses the hostname specified in the server.host
# setting. When the value of this setting is false, Kibana uses the hostname of the host
# that connects to this Kibana instance.
#elasticsearch.preserveHost: true

# Kibana uses an index in Elasticsearch to store saved searches, visualizations and
# dashboards. Kibana creates a new index if the index doesn't already exist.
#kibana.index: ".kibana"

# The default application to load.
#kibana.defaultAppId: "home"

# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
#elasticsearch.username: "kibana"
#elasticsearch.password: "pass"                                                                                                               1,31          All

 

kibana의 docker-compose.yml은 아래와 같다.

version: "3"

services:
  kibana:
    image: docker.elastic.co/kibana/kibana:7.6.2
    restart: always
    container_name: kibana
    volumes:
      - ./kibana.yml:/usr/share/kibana/config/kibana.yml
    environment:
      ELASTICSEARCH_URL: http://elasticsearchIP:9200
      ELASTICSEARCH_HOSTS: http://elasticsearchIP:9200
    ports:
      - "5601:5601"

 

 

3. filebeat

 

맨 처음에는 filebeat 중에서도 docker input 플러그인을 사용하여 컨테이너로 실행되고 있는 스프링부트의 컨테이너 로그를 바로 읽어서 엘라스틱서치로 전송하려했다. 하지만 쉽게 되지 않았고, 계속해서 스프링부트의 로그가 아닌 컨테이너의 상태 로그만을 전송했다. 

하여 이 방법은 포기하고 그냥 log input 플러그인을 사용해서 스프링부트의 로그 파일을 읽기로 했다. 그런데 이것도 처음에 너무 잘 안됐는데, 아래와 같이 스프링프로젝트의 yml에 로그의 위치를 명시했더니 로그 파일이 컨테이너 내에 /var/lib/deliveryservice.log로 저장되었다.

즉 위의 파일은 docker exec 명령어를 사용해서 컨테이너 내부에 들어가야 확인할 수 있다. 

요 파일을 호스트PC에서도 저장될 수 있도록 해당 스프링부트 프로젝트를 docker run 할때 -v 옵션을 사용해주었다. 아래와 같다.

-v /home/ubuntu/logs/:/var/lib/

위 옵션을 넣어주면 호스트PC의 /home/ubuntu/logs 에 deliveryserbice.log파일이 생기고 로그를 확인할 수 있다.

이제 요 파일을 filebeat가 읽게 하면 되는 것이다.

 

먼저 filebeat 역시 docker-compose로 실행할 것이고 input과 같은 파일비트의 설정을 해줘야하기 때문에 filebeat.yml이 필요하다. 아래와 같다.

filebeat.inputs:
  - type: log
    containers:
    paths:
      - /var/logs/*.log
    multiline:
      pattern: '^[[:space:]]'
      negate: false
      match: after

output.elasticsearch:
  hosts: ["elasticsearchIP:9200"]

setup.kibana:
  host: "kibanaIP:5601"

 

docker-compose.yml은 아래와 같다.

version: "3"
services:
  filebeat:
    image: docker.elastic.co/beats/filebeat:7.6.2
    container_name: filebeat
    user: root
    volumes:
      - /home/ubuntu/logs:/var/logs
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro

 

이제 모두 실행하고 키바나 화면에서 스프링부트의 로그가 잘 보이는지 확인해보자.

Kibana --> Discover 에 들어가면 볼 수 있다.

'ELK' 카테고리의 다른 글

엘라스틱 스택  (0) 2023.06.19