해당 글은 [Fluent Bit을 사용하여 Cloudwatch log group으로 로그 전송하기] 실습 구성에 이어서 진행한다.
- [INPUT]에 대한 설정은 위 글을 참조하면 된다.
Fluent Bit은 로그 데이터를 비용 측면과 효율성을 고려하여 효율적으로 저장하고 활용하기 위해 Amazon S3 Output 플러그인을 활용하여 Amazon S3로 전송하여 보관할 수 있다.
실습
전제 조건
- AWS EKS 클러스터
- Helm CLI 도구
설치 환경
- AWS EKS v1.22
- Helm v3.8.2
설치 버전
- Fluent Bit 1.9.10
실습 절차
1. Multipart Upload 와 PutObject2. 데이터 유실 방지 (store_dir)
3. Amazon S3 OUTPUT 구성
4. S3 버킷 디렉토리 구조 변경
1. Multipart Upload 와 PutObject
Amazon S3 플러그인은 2가지 업로드 방식을 사용하여 S3에 업로드한다.
- Multipart Upload
- 대용량 파일을 조각으로 나누어 병렬로 업로드하는 기능
- S3 PutObject
- 작은 크기 파일을 한 번에 전송하는 방식
두 방식 중 Multipart Upload가 권장되며 기본값이다.
Multipart Upload를 사용하면 큰 파일을 여러 파트로 나누어 병렬로 업로드하므로 업로드 시간을 단축할 수 있고, 파일 업로드 중 네트워크 오류 또는 다른 문제로 업로드가 실패하는 경우, 해당 파트만 재업로드해서 재시작 및 복구에 용이하다.
Multipart Upload를 사용하는데, PutObject를 사용하는 경우가 있다.
"upload_timeout" 설정 시간에 도달하면 원하는 Multipart upload 사이즈인 "upload_chunk_size"에 도달하지 않아도 업로드를 한다. 이때, Multipart upload에서 사용하는 UploadPart에 파트 사이즈가 최소 5,242,880byte 이상이어야 하는데 이보다 작을 경우 fluent bit log에서 아래와 같은 메세지를 볼 수 있다.
Pre-compression upload_chunk_size= 37392, After compression, chunk is only 3115 bytes, the chunk was too small, using PutObject to upload
compression(압축) 후 버퍼링된 데이터가 S3 UploadPart 크기에 충족하지 못할 경우 PutObject를 사용하여 upload 한다는 메세지이다.
추가로 아래 3가지 경우에 PutObject를 사용하여 업로드한다.
1. "use_put_object" 옵션이 On으로 설정된 경우
- 기본적으로 "use_put_object" 옵션은 Off이기 때문에 Multipart Upload API를 사용하지만 On으로 설정하면 PutObject를 사용하여 업로드한다.
2. 이전 실행에서 store_dir에 남아있는 이전 버퍼 파일들을 전송해야 할 때
- S3 Output Plugin에서 데이터를 임시로 저장하는 디렉토리를 store_dir이라는 설정을 통해 지정할 수 있는데, 이 디렉토리에는 이전 실행에서 남아있던 버퍼 파일들이 저장되어 있을 수 있다. 새로운 실행에서 이전 데이터를 잃지 않도록 이전 버퍼 파일들을 모두 전송한다. 이때, 파일 단위로 PutObject를 사용하여 이전 데이터를 S3로 전송한다.
3. 종료 시 현재 버퍼링 된 데이터를 모두 전송해야 할 때
- Fluent Bit은 종료 시 현재 버퍼링 된 데이터를 모두 전송하여 데이터의 유실을 방지한다. 종료 시에는 PutObject를 사용하여 현재 버퍼링 된 데이터를 S3로 전송한다.
2. 데이터 유실 방지 (store_dir)
Fluent Bit이 갑작스럽게 중단된다면, 종료하기 전에 모든 데이터를 전송하고 업로드를 완료하려고 할 것이다.
그러나 일부 데이터를 전송하지 못하는 경우가 있을 수 있는데, 이런 상황에서 store_dir 옵션을 사용하면 Fluent Bit은 종료 전에 전송되 못한 데이터를 store_dir 디렉토리에 저장한다. 이 후 재시작 시에 store_dir에서 기존의 데이터를 확인하고, 이전에 전송되지 못한 데이터를 재전송을 시도한다.
이렇게 함으로써 중단되었던 시점부터 로그 데이터 수집을 다시 시작할 수 있으며, 데이터의 유실을 방지할 수 있다.
S3 OUTPUT 설정에 아래와 같이 추가하면 된다.
[OUTPUT]
Name s3
store_dir /var/fluent-bit/state/flb-storage/s3
3. Amazon S3 OUTPUT 구성
[필요 정책]
아래 정책을 워커노드 IAM Role에 추가해야 한다.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "*"
}]
}
아래와 같이 설정하여 S3에 쌓이는지 확인한다.
[OUTPUT]
Name s3
Match application.*
bucket {S3_버킷_이름}
region ${AWS_REGION}
total_file_size 50M
upload_timeout 1m
use_put_object Off
static_file_path On
upload_chunk_size 10m
store_dir /var/fluent-bit/state/flb-storage/s3
compression gzip
workers 1
- total_file_size : S3의 최대 파일 크기.
- upload_timeout : 이 시간이 경과하면 S3에 업로드한다.
- use_put_object : Multipart upload API 대신 S3 PutObject를 사용한다.
- static_file_path : "s3_key_format"에 $UUID가 없으면 자동으로 S3_Key 이름 끝에 자동으로 UUID 문자열을 추가한다. On으로 설정할 경우 자동으로 UUID를 추가하지 않게 된다.
- upload_chunk_size : Multipart upload를 위한 각 파트의 크기
- store_dir : S3로 보내기 전 로컬에 Buffering하는 디렉토리이다.
- compression : S3 객체 압축 유형으로 "use_put_object"가 on, off인 경우 gzip 압축을 활성화할 수 있다.
- workers : s3 output을 위한 전용 스레드가 활성화된다. 현재 1 workers만 지원하고, 그 이상으로 설정할 경우 오류/불확실한 동작이 발생한다.
[참고]
Flunet Bit 배포 후 아래와 같은 오류가 나올 수 있다.
"[error] [output:s3:s3.1] use_put_object must be enabled when compression is enabled"
[원인]
Fluent Bit 1.9.6 버전까지는 Multipart upload를 사용할 때 gzip 압축을 지원하지 않아 "use_put_object: off"로 설정하고 "compression: gzip"으로 설정하면 위와 같은 에러가 발생한다.
1.9.7 버전부터 지원하면서 "use_put_object: off" 하고 "compression: gzip" 을 사용할 수 있게 되었다.
위 설정으로 배포하면 S3에 아래와 같은 구조로 생성된다. 이는 "s3_key_format" 옵션 기본값이다.
/fluent-bit-logs/$TAG/%Y/%m/%d/%H/%M/%S
Fluent Bit 로그를 보면 S3에 업로드한 오브젝트 구조를 확인할 수 있다.
[ info] [output:s3:s3.1] Successfully uploaded object /fluent-bit-logs/application.var.log.containers.fluent-bit-hksj7_amazon-cloudwatch_fluent-bit-8799bf1f9e21f3eac93ff77ca5cc879458d92002235c8bfc0526e1083d7baa2a.log/2023/07/20/06/56/20
실제 AWS S3에서 확인하면 위 로그와 같은 구조로 생성된 걸 확인할 수 있다.
4. S3 버킷 디렉토리 구조 변경
위에서 확인했듯이 "s3_key_format"의 기본값으로 S3 버킷 구조가 생성되어 log 파일이 저장된다.
위 로그에서 $TAG 부분은 아래와 같다.
application.var.log.containers.fluent-bit-hksj7_amazon-cloudwatch_fluent-bit-8799bf1f9e21f3eac93ff77ca5cc879458d92002235c8bfc0526e1083d7baa2a.log
'$TAG[0]: application, $TAG[1]: var' 이런 식으로 $TAG[n]을 사용하여 구분할 수 있다.
아래와 같이 변경하여 적용한다.
s3_key_format /${CLUSTER_NAME}/fluent-bit-logs/$TAG[0]/$TAG[5]/%Y/%m/%d/$TAG[4]_%Y%m%d%H%M.log.gz
s3_key_format_tag_delimiters ._
"s3_key_format_tag_delimiter" 값을 "._" 로 변경하면 아래와 같이 TAG를 사용하여 디렉토리 구조를 변경할 수 있다.
- ${CLUSTER_NAME} : Fluent Bit ConfigMap에서 설정한 EKS Cluster 이름
- $TAG[0] : Fluent Bit [Input]의 Tag인 "application"
- $TAG[4] : Pod 이름인 "fluent-bit-hksj7"
- $TAG[5] : 네임스페이스 이름인 "amazon-cloudwatch"
적용 후 로그를 확인한다.
[ info] [output:s3:s3.1] Successfully uploaded object /wlsdn-eks/fluent-bit-logs/application/amazon-cloudwatch/2023/07/22/fluent-bit-5bkvd_202307220935.log.gz
S3 버킷에서 실제로 변경한 구조로 생성되는지 확인한다.
"upload_timeout" 설정에 의해 1분마다 파일이 생성되는 걸 확인할 수 있다.
'Observability > Fluent Bit' 카테고리의 다른 글
Fluent Bit을 사용하여 Cloudwatch log group으로 로그 전송하기 (0) | 2023.07.17 |
---|
댓글