일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- docker설치
- 로깅시스템
- 만들면서배우는클린아키텍처
- Spring
- 로그관제시스템
- Spring boot
- aws sns
- ubuntu
- root password
- mac docker
- spring_cv
- efk
- FluentdTail
- 회고록
- interface default
- 2024년
- Fluentd Aggregator
- spring sleuth
- 헥사고날아키텍처
- cv
- 포트앤어댑터아키텍처
- ubuntu docker
- 클린아키텍처
- ubuntu20.04LTS
- openjdk-8-jdk
- docker
- FluentdElasticsearch
- aws sqs
- 이력서페이지
- 이력서
- Today
- Total
ToasT1ng 기술 블로그
[EFK] 3. 쓸만한 EFK 구축 (1) - Fluentd Aggregator 본문
지난 포스팅에서는 Service => Fluentd => Elasticsearch 까지 로그를 성공적으로 받을 수 있게 구성해봤다.
[EFK] 2. 간단한 EFK 구축 (2)
지난 포스팅에서는 우리가 구축할 EFK 의 전체적인 구조와, Service 역할을 해줄 간단한 Spring Boot App 을 제작했었다. [EFK] 1. 간단한 EFK 구축 (1) EFK 의 구조 대부분의 로깅 시스템은 이런 식으로 구성
toast1ng.tistory.com
이어서 오늘은 Fluentd Aggregator 를 중점적으로 다뤄보려고 한다.
Fluentd Aggregator 의 필요성
단일 서버 구성으로 규모있는 시스템을 구축하는 것은 불가능한 일이다. 어떻게 할 수 있겠는가? 하나만 죽어도 시스템 전체가 다운되어버리는데. 대부분의 경우 시스템의 안정성을 위해, 여러 대의 서버를 Clustering 하여 하나의 시스템을 이루도록 구축한다.
Logging System 은 이 점을 고려해야 한다. 현재까지는 단일 End Point 에서 Log 를 발생시켜 Elasticsearch 까지 도달하도록 했지만 실제 상황에서는 여러 End Point 에서 Log 가 발생되어 Elasticsearch 까지 도달하게 된다.
지금까지 우리가 구성한 Logging System 에서는 이를 어떻게 처리할까?
10개로 Clustering 된 시스템이 있으면, 10개의 Fluentd 에서 각각 N초에 한 번씩 쌓인 Log 들을 ElasticSearch 로 쏜다. ES에게 N초에 한 번꼴로 1초에 10번의 접근이 있게 된다.
만약 이런 시스템이 10개가 더 있다고 해보자. 100개의 Fluentd 에서 각각 N초에 한 번씩 쌓인 Log 들을 ElasticSearch 로 쏜다. ES에게 N초에 한 번꼴로 1초에 100번의 접근이 있게 된다.
각각은 물리적으로 다른 곳에서 오기 때문에 순차적으로 접근하지 않는다. 최악의 경우, 1ms 도 다르지 않은 시간에 정말 동시에 ES에 접근하게 될 수도 있다. 우리가 구성할 ElasticSearch 에서 이 모든 트래픽을 감당할 수 있을까?
이렇게 구성했을 경우, ElasticSearch 로 들어오는 트래픽 양은 필연적으로 점점 늘어나게 된다. 각 Cluster 를 구성하는 Server 의 개수가 늘어나면 End Point 도 증가하게 될 것이다.
아무리 넉넉하게 ElasticSearch 의 컴퓨팅 리소스를 책정해 둔다고 해도 언젠가는 불안정해질 수 있다는 뜻이다.
Q. 늘어나는 트래픽 양에 맞춰 ES 의 컴퓨팅 파워를 계속 높이면 되지 않을까?
A. 비용이 너무 너무 너무 많이 든다. 별로 효율적이지가 않다.
그렇다면 어떤 방법을 써야하는게 좋을까?
간단하다. ES 에 직접적으로 접근하는 End Point 양을 줄이면 된다. Fluentd Aggregator 가 필요한 이유이다.
Fluentd Aggregator 가 일종의 Queue 역할을 수행해줄 수 있게 된다. 더 이상 ES 에 동시다발적으로 접근하지 않게 된다. Aggregator 를 따로 두면 서로 다른 형태의 Log 들을 여기서 수집하고 filtering 하여 같은 형태의 Log 들로 변환해서 ES 에 쏘는 것도 가능하다. 필요에 따라서 잘 활용하면 될 것이다.
이제 본격적으로 Fluentd Aggregator 를 구축해보자.
Fluentd_aggregator
전체 파일 구조에 다음과 같이 추가된다. ( fluentd-aggregator/ 추가 )
elasticsearch/
∟ backup/
∟ config/
∟ elasticsearch.yml
∟ data/
∟ docker-compose.yml
fluentd-aggregator/
∟ buffer/
∟ conf/
∟ fluentd.conf
∟ pos/
∟ service.pos
∟ Dockerfile
fluentd/
∟ buffer/
∟ conf/
∟ fluentd.conf
∟ pos/
∟ service.pos
∟ Dockerfile
spring/
∟ log/
∟ simplelogging.log
∟ ......
fluentd_aggregator 의 fluentd.conf 는 다음과 같이 작성한다.
<source>
@type forward
port 24224
bind 0.0.0.0
tag log.*
</source>
<match **>
@type copy
<store>
@type elasticsearch
hosts http://<YOUR_ES_IP>:9200
user fluentd_user
password [YOUR_PASSWORD]
<buffer service,time>
@type file
path /var/buffer/elasticsearch
timekey 30s
flush_mode interval # flush_interval 에 설정한 시간마다 flush
flush_interval 5s
flush_thread_count 5
retry_type exponential_backoff
retry_forever false
retry_wait 1 # 첫 Retry 까지 기다리는 시간
retry_exponential_backoff_base 2 # N 번 이상 실패했을 경우 exponential_backoff
retry_randomize true # exponential_backoff 에 random number 쓸지 말지
retry_max_interval 5m
retry_timeout 72h # Maximum duration before giving up.
</buffer>
index_name fluentd-${service}-%Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
reconnect_on_error true
reload_on_failure true
reload_connections false
</store>
<store>
@type stdout
</store>
</match>
forward 되어 들어온 data 들을 elasticsearch 로 보낸다. <match></match> 부분은 저번 포스팅에서 fluentd 설정에서 사용했던 것과 같다.
Dockerfile 은 저번에 설정했던 것과 동일하다.
FROM fluent/fluentd:edge-debian
ADD conf/fluentd.conf /fluentd/etc/fluentd.conf
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "4.3.3"]
USER fluent
이제 실행시켜보자.
~$ sudo docker build -f Dockerfile -t <ID>/fluentd-aggregator .
~$ sudo docker run -d -p 24224:24224 -e FLUENTD_CONF=fluentd.conf --network <YOUR_NETWORK_NAME> -v <YOUR_BUFFER_PATH>:/var/buffer -v <YOUR_POS_FOLDER>:/var/pos --name fluentd-aggregator <ID>/fluentd-aggregator
< Example >
~$ sudo docker build -f Dockerfile -t toast1ng/fluentd-aggregator .
~$ sudo docker run -d -p 24224:24224 -e FLUENTD_CONF=fluentd.conf --network elasticsearch_efk -v /home/ubuntu/fluentd-aggregator/buffer:/var/buffer -v /home/ubuntu/fluentd-aggregator/pos:/var/pos --name fluentd-aggregator toast1ng/fluentd-aggregator
아무런 문제없이 잘 작동한다.
fluentd 의 fluentd.conf 를 다음과 같이 수정하자.
<source>
@type tail
format json
path /var/log/*.log
path_key tailed_path
pos_file /var/pos/service.pos
tag fluentdlog.*
</source>
<match **>
@type copy
<store>
@type forward
<buffer>
@type file
total_limit_size 1GB # File Buffer 의 Max Size
path /var/buffer/fluentd
flush_interval 5
retry_wait 1 # 첫 Retry 까지 기다리는 시간
retry_exponential_backoff_base 2 # N 번 이상 실패했을 경우 exponential_backoff
retry_randomize true # exponential_backoff 에 random number 쓸지 말지
retry_max_interval 30s
retry_timeout 72h # Retry 의 최대 Duration ( 3일로 설정함 )
retry_forever false
</buffer>
reconnect_on_error true
reload_on_failure true
reload_connections false
<server>
host <YOUR_IP_ADDRESS>
port <YOUR_PORT>
</server>
</store>
<store>
@type stdout
</store>
</match>
@forward 를 사용하여 원하는 Server IP 주소와 Port 로 Data 들을 보내도록 설정 파일을 고쳤다.
Dockerfile 은 다음과 같다.
FROM fluent/fluentd:edge-debian
ADD conf/fluentd.conf /fluentd/etc/fluentd.conf
저번 파일에서 Elasticsearch 관련 명령어를 실행하는 부분을 없앴다.
이제 실행해보자.
~$ sudo docker build -f Dockerfile -t <ID>/fluentd .
~$ sudo docker run -d -e FLUENTD_CONF=fluentd.conf --network <YOUR_NETWORK_NAME> -v <YOUR_BUFFER_PATH>:/var/buffer -v <YOUR_POS_FOLDER>:/var/pos -v <YOUR_LOG_FOLDER>:/var/log --name fluentd <ID>/fluentd
< Example >
~$ sudo docker build -f Dockerfile -t toast1ng/fluentd .
~$ sudo docker run -d -e FLUENTD_CONF=fluentd.conf --network elasticsearch_efk -v /home/ubuntu/fluentd/buffer:/var/buffer -v /home/ubuntu/fluentd/pos:/var/pos -v /home/ubuntu/spring/log:/var/log --name fluentd toast1ng/fluentd
다 잘 실행되는지 확인하기 위해서, Service 에서 Log 를 발생시켜보자.
~$ curl -XPOST 'localhost:8080/loop?msg=hello&loopTimes=10&term=1'
~$ sudo docker logs -f fluentd-aggregator
Fluentd-Aggregator 의 로그를 확인해보면 5초에 한 번씩 Elasticsearch 로 잘 보내고 있음을 확인할 수 있다.
Kibana
Elasticsearch 에 잘 도달했는지 확인하고 싶다. 그런데 매번 API Call 을 사용해 확인하면 너무 번거로워진다. Kibana 쓰면 더 간단하고 빠르게 볼 수 있다.
Kibana 는 Elasticsearch 와 연동되어, ES 의 Indexing 된 Data 를 검색할 수 있게 하고 표나 테이블 등으로 시각화시켜주는 하나의 툴이다. 사용자가 ES 로 Direct 하게 API Call 을 할 필요 없이, Kibana 가 제공해주는 웹 페이지에서 클릭과 입력 몇 번으로 모든 것을 가능하게 한다. Grafana 와 같은 다른 Monitoring Tool 을 사용해도 되지만 Kibana 는 Elasticsearch 와 같은 회사이므로 연동성이 훨씬 더 보장된다.
그럼 이제 Kibana 를 구축해보자.
파일 구조에 kibana/ 가 추가된다.
kibana/
∟ config/
∟ kibana.yml
∟ docker-compose.yml
elasticsearch/
∟ backup/
∟ config/
∟ elasticsearch.yml
∟ data/
∟ docker-compose.yml
fluentd-aggregator/
∟ buffer/
∟ conf/
∟ fluentd.conf
∟ pos/
∟ service.pos
∟ Dockerfile
fluentd/
∟ buffer/
∟ conf/
∟ fluentd.conf
∟ pos/
∟ service.pos
∟ Dockerfile
spring/
∟ log/
∟ simplelogging.log
∟ ......
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.ts
#
server.name: kibana
server.host: 0.0.0.0
elasticsearch.hosts: [ "http://<YOUR_ES_IP>:9200" ]
monitoring.ui.container.elasticsearch.enabled: true
## X-Pack security credentials
#
elasticsearch.username: elastic
elasticsearch.password: <YOUR_PASSWORD>
xpack.security.sessionTimeout: 600000
docker-compose.yml
version: '3.4'
services:
kibana:
image: docker.elastic.co/kibana/kibana:7.10.2
container_name: kibana
volumes:
- ./config/kibana.yml:/usr/share/kibana/config/kibana.yml
environment:
- "ELASTICSEARCH_USERNAME=elastic"
- "ELASTICSEARCH_PASSWORD=<YOUR_PASSWORD>"
ports:
- 5601:5601
networks:
- elasticsearch_efk
networks:
elasticsearch_efk:
external:
name: elasticsearch_efk
다음과 같이 실행시킨다.
~$ sudo docker-compose -f docker-compose.yml up --build -d
잠시 기다렸다가 <Kibana_Server_IP>:5601 로 접속한다.
아이디 비번을 입력하여 접속하고 좌상단의 메뉴바를 눌러 Management > Stack Management 에 들어간다.
왼쪽의 Kibana > Index Patterns 에 들어가서
새 Index Pattern 을 생성해준다.
다 만들고 나서 Kibana > Discover 로 들어와 우상단의 시간 설정을 하면
발생시킨 로그들이 잘 있는 것을 확인할 수 있다.
이번 포스팅에서는 Fluentd Aggregator 를 사용해 Elasticsearch 의 부담을 줄이고, Kibana 까지 구축해봤다.
Elasticsearch 로 오는 트래픽 부담을 줄였다고는 하지만.. Elasticsearch 한 대만으로 충분한 것일까? 문제가 생기면 어떻게 해야 할까?
다음 포스팅에서는 이를 해결하기 위한 방법으로 Elasticsearch 의 Clustering 에 대해 다룰 것이다.
'로깅시스템' 카테고리의 다른 글
[EFK] 4. 쓸만한 EFK 구축 (2) - Elasticsearch (0) | 2022.04.09 |
---|---|
[EFK] 2. 간단한 EFK 구축 (2) (0) | 2021.09.08 |
[EFK] 1. 간단한 EFK 구축 (1) (0) | 2021.08.21 |
[EFK] 0. 로그 관제 시스템? EFK? (0) | 2021.08.16 |