EFK stack은 Elasticsearch, Fluent bit(Fluentd), Kibana 3개의 플랫폼 조합을 뜻하며,
클러스터 환경에서 로그의 수집, 검색, 시각화를 가능하게 한다.
그림을 보면 알 수 있듯이, 각 클러스터에 fluent bit가 daemonset으로 log를 수집한다.
elasticsearch는 fluent bit가 수집한 로그를 저장하며, 요청에 따라 검색을 한다.
마지막으로 유저가 용이하게 사용할 수 있도록 kibana로 시각화 한다.
FluentBit
Log는 /var/log(시스템 로그)또는
/var/log/container(파드 로그) 또는 /var/log/pods(파드 로그)에 저장된다.
(이때 /var/log/container에서 /var/log/pods로 심볼릭 링크가 연결되어있다)
Fluent Bit는 이러한 로그 파일들을 수집한다.
즉 Fluent Bit는 로그 수집기이며, 로그 컬렉터, 로그 스트리머 등으로 불린다.
Fluent Bit는 이렇게 수집된 로그들을 Elastic Search로 전송한다.
Elastic Search
elastic search는 로그 저장소 및 검색 엔진으로,
데이터를 저장하는 저장소가 있고, 이 저장소에서 로그를 검색 한다.
Kibana
Elastic Search를 Kibana를 통해 시각적으로 확인한다.
즉, 수집한 로그를 시각화 하는 대시 보드이다.
단, 무인증 형태이기 때문에 실무에서 사용할 때는 유의해야한다.
☁️ 참고
- ELK Stack: Elasticsearch + Logstash + Kibana
- EFK Stack: Elasticsearch + Fluentd + Kibana
- Elasticsearch + Fluent Bit + Kibana
- Elastic Stack: Elasticsearch + Beat + Kibana
메모리 사용량 : Fluent Bit < Fluentd < Logstash
기능 : Logstash > Fluentd > Fluent Bit
fluentd vs fluentbit
fluent bit는 자바 런타임이 필요한 JRuby logstash 에서
가벼워진 자바 런타임이 필요하지 않는 CRuby fluentd에서
더욱 경량화 된 C로 만들어진 전송에 특화된 로그 수집기이다.
fluent bit 공식 사이트에 들어가면 이 둘의 차이를 디테일하게 확인할 수 있다.
결론적으로 요약하자면 fluentd는 플러그인 등 확장성이 좋고, fluent bit는 리소스를 적게 차지 한다.
EFK Logging
Kibana: 데이터 시각화
Fluent Bit: 로그 컬렉터(수집기)
Elasticsearch: 검색 엔진
Fluent Bit 가 노드에서 로그를 수집한 후 Elasticsearch 로 전송, 로그는 Elasticsearch 에 저장되고 Kibana 가 수집한 로그들을 시각화 한다.
Elasticsearch
https://artifacthub.io/packages/helm/elastic/elasticsearch
먼저 helm으로 레포지토리(저장소)를 추가하고, 업데이트한다.
helm repo add elastic https://helm.elastic.co
helm repo update
해당 레포지토리에서 elasticsearch와 kibana를 설치할 예정이다.
다음으로 몇가지를 수정(사용자화)하기 위해 values를 es-value.yaml로 받아온다.
helm show values elastic/elasticsearch > es-value.yml
테스트를 위한 것이기 때문에, 복제본의 개수와 리소스를 줄여서 다음과 같이 수정한다.
es-value.yml
...
18 replicas: 1
19 minimumMasterNodes: 1
...
80 resources:
81 requests:
82 cpu: "500m"
83 memory: "1Gi"
84 limits:
85 cpu: "500m"
86 memory: "1Gi"
logging namespace를 생성하고, 해당 ns에 elasticsearch를 설치한다.
kubectl create ns logging
helm install elastic elastic/elasticsearch -f es-value.yml -n logging
Fluent Bit
https://github.com/fluent/fluent-bit-kubernetes-logging
Fluent Bit는 Helm차트가 있긴 하지만 버전이 낮으므로, GitHub에서 clone 한다.
git clone https://github.com/fluent/fluent-bit-kubernetes-logging.git
Service Account와 Role, RoleBinding을 설치한다.
cd fluent-bit-kubernetes-logging
kubectl create -f fluent-bit-service-account.yaml -n logging
kubectl create -f fluent-bit-role-1.22.yaml -n logging
kubectl create -f fluent-bit-role-binding-1.22.yaml -n logging
fluent-bit-configmap.yaml는 공통적으로 적용되는 설정파일이고,
fluent-bit-ds-minikube.yaml는 minikube에서 사용하는 것이고,
일반은 fluent-bit-ds.yaml파일(데몬셋)이다.
vi fluent-bit-kubernetes-logging/output/elasticsearch/fluent-bit-ds.yaml
Fluent가 Elastic Search로 로그를 보낼 수 있도록
다음과 같이 fluent-bit-ds.yaml을 Elastic Search 서비스 이름에 맞춰서 수정하고, 생성한다.
32 - name: FLUENT_ELASTICSEARCH_HOST
33 value: "elasticsearch-master"
cd fluent-bit-kubernetes-logging/output/elasticsearch
kubectl create -f fluent-bit-configmap.yaml -n logging
kubectl create -f fluent-bit-ds.yaml -n logging
minikube 를 사용할 경우 fluent-bit-ds.yaml 대신 fluent-bit-ds-minikube.yaml 을 사용한다.
Kibana
kibana는 앞서 설치한 elasticsearch와 동일한 레포지토리에서 설치한다.
먼저 다음과 같이 values를 kibana-value.yaml로 받아오고, 리소스를 수정한다.
또한, 외부에 노출시키기 위해 서비스타입을 LoadBalancer로 수정한다.
helm show values elastic/kibana > kibana-value.yml
kibana-value.yml
...
49 resources:
50 requests:
51 cpu: "500m"
52 memory: "0.7Gi"
53 limits:
54 cpu: "500m"
55 memory: "0.7Gi"
...
119 service:
120 type: LoadBalancer
helm install kibana elastic/kibana -f kibana-value.yml -n logging
작동 확인
설치한 것들이 잘 작동되는지 테스트를 진행해보자.
$ kubectl port-forward -n logging elasticsearch-master-0 9200:9200
터미널을 하나 더 열어서 curl명령어로 확인했을 때,
다음과 같이 tagline이 You Know, for Search라고 출력되면 정상적으로 작동되고 있다는 뜻이다.
$ curl localhost:9200
{
"name" : "elasticsearch-master-0",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "XXXXXXXXXXXXXXXXXX",
"version" : {
"number" : "7.17.3",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "XXXXXXXXXXXXXXXXXX",
"build_date" : "XXXXXXXXXXXXXXXXXX",
"build_snapshot" : false,
"lucene_version" : "8.11.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
$ curl localhost:9200/_cat/indices
green open .kibana_task_manager_7.17.3_001 XXXXXXXXXXXXXXXXXX 1 0 17 3804 538.4kb 538.4kb
green open .apm-custom-link XXXXXXXXXXXXXXXXXX 1 0 0 0 226b 226b
green open .apm-agent-configuration XXXXXXXXXXXXXXXXXX 1 0 0 0 226b 226b
yellow open logstash-2022.06.01 XXXXXXXXXXXXXXXXXX 1 1 4676 0 15.8mb 15.8mb
green open .kibana_7.17.3_001 XXXXXXXXXXXXXXXXXX 1 0 22 4 4.7mb 4.7mb
다음으로 kibana에 접속한다.
$ kubectl get svc -n logging
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-master ClusterIP 10.233.21.152 <none> 9200/TCP,9300/TCP 27m
elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 27m
kibana-kibana LoadBalancer 10.233.19.27 192.168.100.240 5601:31535/TCP 18m
kibana의 EXTERNAL-IP와 PORT 192.168.100.240:5601 로 접속을 시도하면
다음과 같이 정상적으로 접속되는 것을 확인할 수 있다.
EFK 세팅하기
Explore on my own을 클릭하고,
[Management] - [Stack Management]를 클릭한다.
[Kibana] - [Index Patterns] - [Create index pattern]을 클릭한다.
Elastic Search에서 index는 database이다.
logstash-xxxx.xx.xx 파일을 확인할 수 있는데,
이것은 Fluent Bit가 Elastic Search에 전송한 로그파일로, 하루에 1개씩 생성된다.
Name에 모든 로그 파일을 수집하도록 logstash-*를 입력하고
Timestamp field는 @timestamp를 선택한다.
[Analytics] - [Discover]를 클릭한다.
그러면 다음과 같이 로그들을 확인할 수 있다. 여기서 KQP는 Kibana Query Language이다.
Search 창에 원하는 키워드를 입력하여 검색이 가능하다.