[Kubernetes] 쿠버네티스 로깅 - EFK란? 설치 및 사용법
🚀 EFK 란?
EFK란 Elasticsearch + Fluent Bit + Kibana의 조합을 말한다.
EFK 외에도 다양한 도구의 조합이 있다.
- ELK Stack: Elasticsearch + Logstash + Kibana
- EFK Stack: Elasticsearch + Fluentd + Kibana
- Elastic Stack: Elasticsearch + Beat + Kibana
참고로 ELK가 가장 처음 사용된 조합이다.
🔎 Elasticsearch
Elasticsearch는 검색엔진이다. 데이터를 저장하는 저장소가 있고 그 데이터 저장소에서 검색한다.
Elasticsearch를 로그를 저장하고 검색하는 용도로도 쓰긴하지만 기본 용도는 검색이다.
구글 검색과 같은 검색엔진을 만들 때 사용한다.
🔎 Fluent Bit
Fluent Bit의 역할은 Logging을 하는 것이다. Fluent Bit가 여러 로그 파일들을 수집한다.
그리고 수집한 로그 파일들을 Elasticsearch에게 전송한다.
🔎 Kibana
kibana로 로그를 시각적으로 관리한다.
🔎 로깅 도구 조합의 역사
Elasticsearch, Logstash, Kibana는 모두 같은 회사 제품이며 Java로 만들어졌다.
이 도구의 조합은 쿠버네티스에만 사용하는 것이 아니다.
로그 수집기인 Logstash
가 어떤 로그를 수집하느냐에 따라 달라진다.
쿠버네티스에 사용한다면 쿠버네티스 파드의 로그를 수집하는 용도로 사용하는 것이다.
ELK는 모두 Java로 만들어져 CPU를 과도하게 사용한다는 문제가 있었다. 그래서 대안으로 Fluentd를 사용하게 되었다.
Fluentd는 오픈 소스이며 Ruby로 만들어졌다.
하지만 Fluentd 또한 성능이 뛰어나지 않았고 대안으로 Fluent Bit를 사용하게 됐다.
Fluent Bit는 C로 만들어져 CPU, Memory를 적게 사용한다. Logstash, Fluentd이 기능은 훨씬 많지만 Fluent Bit가 가벼워서 많은 사람들이 선호하게 되었다.
로그 수집기는 로그를 가져와서 수집해서 필터링하고 가공한뒤 가공된 데이터를 제공한다.
쿠버네티스에 사용할 때는 Docker에서 로그를 json 형식으로 구조화해서 저장하므로 추가적인 필터링이나 가공 작업이 필요없다.
로그를 수집해서 계속 Elasticsearch에게 던져주기만 하면 된다.
→ 그래서 쿠버네티스에는 기능의 다양성은 부족하지만 가벼운 Fluent Bit로도 충분하다.
Elastic사가 최근에 고객 마케팅 상품으로 만든 것이 Elastic Stack이다. Beat라는 경량화된 제품을 만들었다.
로깅 도구의 조합은 이밖에도 매우 다양하다.
- Elasticsearch + Beat + Logstash + kibana
- Elasticsearch + Fluent Bit + Fluentd + kibana
규모가 아주 큰 경우에는 중간 과정에서 로그의 수집과 가공을 분리하기도 한다.
🚀 Elasticsearch 설치
https://artifacthub.io/packages/helm/elastic/elasticsearch
❯ helm repo add elastic https://helm.elastic.co
"elastic" has been added to your repositories
❯ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "elastic" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
❯ helm repo list
NAME URL
bitnami https://charts.bitnami.com/bitnami
prometheus-community https://prometheus-community.github.io/helm-charts
elastic https://helm.elastic.co
❯ helm search repo elastic
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/elasticsearch 18.2.5 8.2.2 Elasticsearch is a distributed search and analy...
elastic/elasticsearch 7.17.3 7.17.3 Official Elastic helm chart for Elasticsearch
prometheus-community/prometheus-elasticsearch-e... 4.12.0 1.3.0 Elasticsearch stats exporter for Prometheus
elastic/apm-server 7.17.3 7.17.3 Official Elastic helm chart for Elastic APM Server
elastic/eck-operator 2.2.0 2.2.0 A Helm chart for deploying the Elastic Cloud on...
elastic/eck-operator-crds 2.2.0 2.2.0 A Helm chart for installing the ECK operator Cu...
elastic/filebeat 7.17.3 7.17.3 Official Elastic helm chart for Filebeat
elastic/kibana 7.17.3 7.17.3 Official Elastic helm chart for Kibana
elastic/logstash 7.17.3 7.17.3 Official Elastic helm chart for Logstash
elastic/metricbeat 7.17.3 7.17.3 Official Elastic helm chart for Metricbeat
bitnami/dataplatform-bp2 13.0.2 1.0.1 DEPRECATED This Helm chart can be used for the ...
bitnami/grafana 7.6.5 8.3.4 Grafana is an open source, feature rich metrics...
bitnami/kibana 10.1.8 8.2.2 Kibana is an open source, browser based analyti...
elasticsearch
와 kibana
를 설치할 것이다.
❯ helm show values elastic/elasticsearch > es-value.yaml
❯ code es-value.yaml
18 replicas: 1
81 requests:
82 cpu: "500m"
83 memory: "1Gi"
84 limits:
85 cpu: "500m"
86 memory: "1Gi"
87
간단한 기능만을 사용할 것이므로 리소스 할당량을 변경한다.
❯ kubectl create ns logging
namespace/logging created
❯ helm install elastic elastic/elasticsearch -f es-value.yaml -n logging
설치 완료 !
🚀 Fluent Bit 설치
https://fluentbit.io/
fluent/fluent-bit: Fast and Lightweight Logs and Metrics processor for Linux, BSD, OSX and Windows (github.com)
git clone https://github.com/fluent/fluent-bit-kubernetes-logging.git
cd fluent-bit-kubernetes-logging
kubectl create -f fluent-bit-service-account.yaml
kubectl create -f fluent-bit-role-1.22.yaml
kubectl create -f fluent-bit-role-binding-1.22.yaml
kubectl create -f output/elasticsearch/fluent-bit-configmap.yaml
output/elasticsearch/fluent-bit-ds.yaml
32 - name: FLUENT_ELASTICSEARCH_HOST
33 value: "elasticsearch-master"
kubectl create -f output/elasticsearch/fluent-bit-ds.yaml
동작 여부를 확인한다.
❯ kubectl get ds -n logging
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluent-bit 3 3 3 3 3 <none> 98s
❯ kubens logging
Context "kubernetes-admin@cluster.local" modified.
Active namespace is "logging".
❯ kubectl get po
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 1/1 Running 0 21m
fluent-bit-7rxlm 1/1 Running 0 2m7s
fluent-bit-7t79b 1/1 Running 0 2m7s
fluent-bit-rcq4l 1/1 Running 0 2m7s
❯ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-master ClusterIP 10.233.42.99 <none> 9200/TCP,9300/TCP 22m
elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 22m
❯ kubectl port-forward -n logging elasticsearch-master-0 9200:9200
Forwarding from 127.0.0.1:9200 -> 9200
Forwarding from [::1]:9200 -> 9200
Handling connection for 9200
❯ curl localhost:9200
{
"name" : "elasticsearch-master-0",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "B3HpPlieTXyzc9tBGR3Vvg",
"version" : {
"number" : "7.17.3",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "5ad023604c8d7416c9eb6c0eadb62b14e766caff",
"build_date" : "2022-04-19T08:11:19.070913226Z",
"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"
}
"You Know, for Search"
가 뜨면 정상 설치가 완료된 것이다.
🚀 Kibana 설치
helm show values elastic/kibana > kibana-value.yaml
kibana-value.yaml
49 resources:
50 requests:
51 cpu: "500m"
52 memory: "1Gi"
53 limits:
54 cpu: "500m"
55 memory: "1Gi"
119 service:
120 type: LoadBalancer
마찬가지로 리소스 할당량을 변경한다.
외부에 노출되어야 하므로 서비스 타입을 LoadBalancer
로 변경한다.
helm install kibana elastic/kibana -f kibana-value.yaml -n logging
처음 화면이다. Explore on my own을 선택한다.
elasticsearch의 스토리지가 있고 kibana가 해당 스토리지에서 데이터를 가져올 때 어떤 데이터를 가지고 올 것인가 ?
Fluent Bit가 데이터를 수집, 저장하고 그 데이터를 elasticsearch가 가져와서 저장하면 kibana는 그것을 사용한다.
Fluent Bit가 elasticsearch에 전송시키고 elasticsearch가 저장할 것이다.
수많은 파드들로부터 로그 파일들을 수집하고 그것을 파일로 저장하는데 그 파일명은 logstash-시간 형식을 가진다.
하루에 하나씩 만들어지고 필요하면 분리시킬 수 있다.
Name에 logstash-*
로 검색하면 매일 추가적으로 생성되는 파일도 매칭될 것이다. 거기서 검색한다는 것이다.
그리고 인덱스 패턴을 생성한다.
다시 햄버거 메뉴에서 Analytics Discover 클릭한다.
여기서 우리는 이제 검색을 한다. 검색창의 KQL은 Kibana Query Language이다.
현재까지 모은 로그가 1129개임을 알 수 있다.
❯ kubectl apply -f https://kubernetes.io/examples/controllers/job.yaml
job.batch/pi created
❯ kubectl get po
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 1/1 Running 0 75m
fluent-bit-7rxlm 1/1 Running 0 55m
fluent-bit-7t79b 1/1 Running 0 55m
fluent-bit-rcq4l 1/1 Running 0 55m
kibana-kibana-77d6dbdb68-zb44x 1/1 Running 0 48m
pi--1-gsx8g
❯ kubectl apply -f https://kubernetes.io/examples/controllers/job.yaml
job.batch/pi created
❯ kubectl get po
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 1/1 Running 0 75m
fluent-bit-7rxlm 1/1 Running 0 55m
fluent-bit-7t79b 1/1 Running 0 55m
fluent-bit-rcq4l 1/1 Running 0 55m
kibana-kibana-77d6dbdb68-zb44x 1/1 Running 0 48m
pi--1-gsx8g
vagrant@k8s-node2:~$ sudo -i
root@k8s-node2:~# cd /var/log
root@k8s-node2:/var/log# cd containers
root@k8s-node2:/var/log/containers# ls
...
pi--1-gsx8g_logging_pi-8160eddb9f296523a6929706d2f4396837ca85a75419f645f86f8a4ede9e15e9.log
...
root@k8s-node2:/var/log/containers# ls -l
pi--1-gsx8g_logging_pi-8160eddb9f296523a6929706d2f4396837ca85a75419f645f86f8a4ede9e15e9.log -> /var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384/pi/0.log
/var/log/pods/로 심볼릭 링크가 걸려있다.
root@k8s-node2:/var/log/containers# cd /var/log/pods/
root@k8s-node2:/var/log/pods# ls
logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384
해당 디렉토리로 이동하면 logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384
가 존재한다.
root@k8s-node2:/var/log/pods# cd logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384/
root@k8s-node2:/var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384# ls
pi
root@k8s-node2:/var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384# cd pi
root@k8s-node2:/var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384/pi# ls
0.log
root@k8s-node2:/var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384/pi#
컨테이너명으로 된 디렉토리가 있고 0.log라는 로그 파일이 있다.
root@k8s-node2:/var/log/pods/logging_pi--1-gsx8g_076cd99d-c552-4bea-bea8-ec3680380384/pi# cat 0.log
2022-05-29T06:26:43.636767353Z stdout F 3.141592653589793238462643383279502884197169399375105820974944592307............
파이 계산 값이 로그로 찍혀있다. 이 데이터가 elasticsearch에서 검색된다.
3.14* 로 검색하면 로그를 확인할 수 있다.
로그는 이제부터 elasticsearch에 저장되기 때문에 파드가 지워져도 상관없다.