노드 자체의 로그와 Data Plane의 로그 확인은 EKS에서 지원하지 않으므로 별도의 도구로 수집해야한다.
또한 로그를 애플리케이션(컨테이너)에 저장하는 경우 심볼릭 링크로 연결된 노드의 /var/log/*
위치의 로그가 컨테이가 지워질 시 함께 지워진다는 단점이 있다. + (용량의 한계, 중앙화되지 않은 로그관리)
따라서 fluentbit🐦를 사용한다.
fluentbit는 벌새다!
실제로 벌새랑 상당히 닮았지 않은가? 하는 역할도 꽃에서 꿀을 쪽쪽 빨아먹는 벌새마냥, 노드에서 로그를 쪽쪽 빨아먹는 역할을 수행한다.
AWS 공식 문서에서 제공하는 fluentbit🐦는 3가지 종류의 로그를 수집할 수 있다.
- application 로그 : 컨테이너의 로그를 의미한다.
/var/log/containers
에 위치한 로그이다.
- host 로그 : 노드(인스턴스) 자체의 로그
/var/log/dmesg,secure,messages
에 위치한 로그이다.
- data plane 로그 : EKS host의 data plane의 로그
kubelet, kubeproxy, docker 등에 관한 로그가 data plane로그이다.
/var/log/journal
에 위치한다.
이러한 flunetbit🐦는 어떻게 해당 로그들을 수집할까?
파드로 배포됨에 있어서 노드의 hostpath 볼륨을 이용하는 것이다.
hostpath 볼륨을 통해서 노드의 /var/log/containers
/var/log/dmesg,secure,messages
/var/log/journal
영역에 저장된 각 로그들을 수집한다.
(내부적으로는 심볼릭 링크⤴️
를 통해 노드에 존재)
이러한 fluntbit🐦는 Input
, Filter
, Ouput
형태로 구성되는데 Input
은 로그 소스의 HostPath를 지정하는 것이고, Filter
는 필터링할 형식을 지정한다. 그리고 Output
은 수집한 로그를 전달할 로깅 시스템을 의미한다.
💡EKS 환경에서의 Output은 Amazon CloudWatch가 된다.
먼저 각 노드마다 데몬셋 형태로 fluentbit가 배포되고 각 노드의 hostpath를 통해서 fluentbit가 로그를 쪽쪽 빨아먹는다. (수집한다)
이렇게 수집된 로그들은 Output
으로 정의된 Amazon CloudWatch의 각 로그 그룹으로 로그를 전송한다.
이처럼 fluntbit🐦 통해서 중앙집중형 로깅 시스템을 구축할 수 있다.
이제 fluntbit🐦를 직접 설치해보고, 로그를 확인해보자.
// 네임스페이스 생성
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
// 네임스페이스 확인
kubectl get ns
먼저 네임스페이스를 생성해 준다. amazon-cloudwatch 네임스페이스가 생성되었다.
이제 fluntbit🐦에 들어갈 여러 설정정보를 저장한 ConfigMap을 생성해준다. 이는 어떤 수준으로 로그를 수집할지를 정의한다.
// Fluent-bit ConfigMap 생성
FluentBitHttpServer='On'
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
FluentBitReadFromTail='On'
kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${CLUSTER_NAME} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${AWS_DEFAULT_REGION} -n amazon-cloudwatch
// ConfigMap 확인
kubectl describe configmap -n amazon-cloudwatch fluent-bit-cluster-info
// Fluentbit 생성
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
// 설치 확인
kubectl get ds,pod,cm,sa -n amazon-cloudwatch
데몬셋 형태로 각 노드에 1개씩 총 3개가 배포된 것을 확인할 수 있다.
// FluentBit Configmap 기본 확인
kubectl get cm fluent-bit-cluster-info -n amazon-cloudwatch -o yaml | yh
// FluentBit Configmap 상세 정보 : 로그의 INPUT/FILTER/OUTPUT 설정
/// 설정 구성 : application-log.conf, dataplane-log.conf, fluent-bit.conf, host-log.conf, parsers.conf
kubectl describe cm fluent-bit-config -n amazon-cloudwatch
설정할 옵션을 정의하는 Configmap을 확인해보자.
처음 fluentbit를 생성할 때 정의한 옵션들이 있는fluent-bit-cluster-info
와 상세 옵션인 fluent-bit-config
총 2개의 ConfigMap이 있다.
fluent-bit-cluster-info 기본 정보
fluent-bit-config 상세 정보
Application📦. 즉, 컨테이너의 로그 정보를 수집하는 예시만 확인해보자.
// FluentBit Daemonset 확인
// 💡로그를 수집하는 방법 : 파드 Volumes에 노드의 HostPath를 통해서
kubectl describe ds fluent-bit -n amazon-cloudwatch
// 노드의 /var/log에 저장된 logs tree 확인
ssh ec2-user@$N1 sudo tree /var/log
fluntbit🐦을 직접 열어보면 실제로 Volume에 노드의 hostPath를 통해서 로그를 수집하고 있다는 것을 확인할 수 있다.
//신규 터미널 모니터링
kubectl logs deploy/nginx -f
로그를 확인하기 위해서 새로운 터미널을 하나 더 열고 로그를 계속 추적하도록 하자. -f
는 실시간 스트리밍을 의미한다.
yum install -y httpd
// 30000번의 요청을 보냄
ab -c 500 -n 30000 https://nginx.$MyDomain/
ApacheBench를 통해서 부하를 발생시키고 해당 로그를 확인해보자.
AWS CloudWatch로 들어가 application 로그 그룹을 확인해보자.
4개의 파드가 존재하므로 application 로그 그룹에는 4개의 로그 스트림이 구성되어있는 것을 확인할 수 있다.
이제 우리의 서비스인 nginx🌿 파드의 로그를 확인해보자.
ApacheBench
를 검색해서 필터링해보면 30000번의 부하를 수행하도록 한 로그가 출력된다. (로그는 대소문자를 구문하니 주의하자)