Published on

EKS에서 fluent-bit 로그 누락·지연 원인 9가지

Authors

EKS에서 fluent-bit를 DaemonSet으로 붙여 로그를 수집하다 보면, 특정 Pod 로그가 통째로 빠지거나(누락), 몇 분~수십 분 뒤늦게 도착하는(지연) 문제가 종종 발생합니다. 문제는 fluent-bit 자체 버그라기보다 노드 디스크/파일 시스템, tail 상태 DB, kubelet 로그 로테이션, 네트워크/DNS, 출력(Output) 백프레셔, 리소스 제한, 멀티라인 파서 같은 여러 레이어에서 생깁니다.

이 글은 “원인 후보를 많이 나열”하는 대신, 각 원인별로 어떤 증상이 나오는지 → 무엇부터 확인할지 → 어떤 설정으로 고칠지를 9가지로 정리합니다.

> 참고로 네트워크/DNS 계열이 얽혀 있으면 로그 전송 지연이 매우 그럴듯하게 보입니다. EKS에서 DNS가 간헐 실패하는 케이스는 아래 글도 함께 보면 진단이 빨라집니다: EKS에서 CoreDNS 정상인데 DNS가 간헐 실패할 때

0) 먼저 “누락 vs 지연”을 구분하는 3분 진단

fluent-bit 내부 메트릭/로그로 방향 잡기

  • 지연: 출력(Output) 쪽에서 재시도/버퍼링이 누적되는 경우가 많습니다.
    • retry in ... / failed to flush chunk / could not send 같은 로그
    • storage backlog 증가
  • 누락: tail 입력(Input)에서 파일 오프셋을 잘못 잡거나, 로테이션/삭제로 파일을 놓치는 경우가 많습니다.
    • inode 변경, rotated 감지 실패, DB 손상, Skip_Long_Lines

다음 명령으로 fluent-bit Pod 로그를 먼저 확인합니다.

kubectl -n logging logs -l app.kubernetes.io/name=fluent-bit --tail=200

Prometheus로 메트릭을 긁는다면 /api/v1/metrics/prometheus 노출 여부를 확인하고, fluentbit_output_*, fluentbit_input_* 지표의 에러/리트라이/드롭을 봅니다.


1) Output 백프레셔(전송 실패/재시도)로 인한 지연

증상

  • 로그는 “언젠가” 도착하지만 5~30분 이상 늦음
  • fluent-bit 로그에 failed to flush chunk / retry in 반복
  • Elasticsearch/OpenSearch/CloudWatch/Loki 등 대상이 순간적으로 느리거나 429/5xx

확인

  • 대상 엔드포인트로의 네트워크, DNS, TLS 핸드셰이크, 레이트리밋
  • fluent-bit storage.type filesystem 사용 시 디스크 백로그 증가
# fluent-bit 컨테이너에서 대상 DNS 확인
kubectl -n logging exec -it ds/fluent-bit -- sh -c 'nslookup YOUR_ENDPOINT'

# 간단한 TCP 체크(이미지에 따라 nc 없음)
kubectl -n logging exec -it ds/fluent-bit -- sh -c 'wget -S -O- https://YOUR_ENDPOINT/health || true'

해결

  • 출력 플러그인별 재시도/버퍼 튜닝(예: Retry_Limit False는 무한 재시도라 지연이 길어질 수 있음)
  • 백프레셔가 길어질 때 드롭 정책(SLA에 따라) 또는 별도 큐(Kinesis/Firehose 등)로 완충
  • DNS 간헐 실패가 의심되면 CoreDNS/노드 DNS 경로를 점검: EKS에서 CoreDNS 정상인데 DNS가 간헐 실패할 때

2) fluent-bit 리소스 부족(CPU throttling/메모리 압박)로 처리 지연

증상

  • 트래픽 급증 시에만 지연, 평소엔 정상
  • 노드에서는 여유가 있어도 fluent-bit Pod에 requests/limits가 낮아 CPU throttling 발생
  • 메모리 부족 시 chunk flush가 늦고, 심하면 OOMKilled 후 재시작으로 일부 누락처럼 보임

확인

kubectl -n logging top pod -l app.kubernetes.io/name=fluent-bit
kubectl -n logging describe pod -l app.kubernetes.io/name=fluent-bit | egrep -i 'oom|thrott'

해결

  • fluent-bit에 현실적인 리소스 할당(특히 멀티라인/필터 많을수록 CPU 소모 큼)
  • 파싱/필터를 최소화하고, 가능한 한 다운스트림에서 처리

예시(개념):

resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: 1000m
    memory: 512Mi

3) 노드 DiskPressure/디스크 고갈로 인한 버퍼/상태 DB 문제

증상

  • 특정 노드에서만 누락/지연 집중
  • storage.type filesystem 사용 시 버퍼 파일을 못 쓰거나, tail DB가 깨짐
  • 노드 이벤트에 DiskPressure 또는 이미지/로그 디렉터리 포화

확인

kubectl describe node <node> | egrep -i 'DiskPressure|Pressure'
kubectl get events -A --field-selector involvedObject.kind=Node | egrep -i 'diskpressure|evict'

해결


4) tail 상태 DB(pos 파일/SQLite) 손상 또는 휘발성 저장으로 인한 누락

fluent-bit tail 입력은 읽은 위치를 DB로 기록합니다. 이 DB가 손상되거나, 컨테이너 재시작 시 초기화되면 중복 수집 또는 스킵(누락) 이 발생할 수 있습니다.

증상

  • fluent-bit 재시작 이후 특정 구간 로그가 비거나, 반대로 중복 유입
  • db 파일 관련 에러 로그

확인

  • DB 경로가 emptyDir인지(재시작 시 초기화) 확인
  • 노드 디스크/권한 문제로 DB 기록 실패 여부 확인

해결

  • DaemonSet에서 hostPath로 DB를 노드에 영속화(노드 재부팅까지는 유지)
  • DB.Sync(플러시 정책) 조정

예시:

[INPUT]
    Name              tail
    Path              /var/log/containers/*.log
    Tag               kube.*
    DB                /var/fluent-bit/state/flb_kube.db
    DB.Sync           Normal
    Mem_Buf_Limit     50MB
    Skip_Long_Lines   On
volumeMounts:
  - name: varflbstate
    mountPath: /var/fluent-bit/state
volumes:
  - name: varflbstate
    hostPath:
      path: /var/fluent-bit/state
      type: DirectoryOrCreate

5) kubelet 로그 로테이션/삭제 타이밍과 tail 추적 불일치

컨테이너 로그(/var/log/containers/*.log/var/log/pods/...)는 kubelet이 로테이션합니다. 로테이션이 빠르게 일어나거나(작은 max size), 파일이 빨리 삭제되면 fluent-bit가 파일 핸들을 놓치거나 inode 변경을 따라가지 못해 누락이 생길 수 있습니다.

증상

  • 로그가 많은 워크로드에서만 누락
  • 특정 시점(로테이션 직후) 구간이 비어 있음

확인

  • 노드의 kubelet 로그 로테이션 설정(--container-log-max-size, --container-log-max-files)
  • 해당 Pod의 로그 파일이 얼마나 빨리 rotate 되는지

해결

  • kubelet 로테이션 정책 완화(파일 수/크기 증가)
  • fluent-bit tail 설정에서 로테이션 감지/스캔 주기 조정

예시(개념):

[INPUT]
    Name              tail
    Path              /var/log/containers/*.log
    Refresh_Interval  5
    Rotate_Wait       30
    Ignore_Older      0

6) 멀티라인 파서/필터 설정 문제로 “로그가 사라진 것처럼” 보이는 누락

Java stacktrace, Python traceback, Nginx error log 등은 멀티라인 처리가 필요합니다. 멀티라인 규칙이 맞지 않으면:

  • 여러 줄이 한 이벤트로 합쳐지지 않고 찢어져 검색에서 누락처럼 보이거나
  • 반대로 멀티라인 버퍼가 끝을 못 만나 flush가 늦어져 지연처럼 보일 수 있습니다.

증상

  • 특정 앱(특정 로그 포맷)에서만 누락/지연
  • “에러 로그만” 유독 안 보임

확인

  • 멀티라인 파서 적용 대상(Tag/Match)이 정확한지
  • 시작/종료 패턴이 실제 로그와 일치하는지

해결

  • 멀티라인 규칙 최소화 + 샘플 로그로 로컬 재현

예시(Fluent Bit multiline parser 개념):

[MULTILINE_PARSER]
    Name          java-exception
    Type          regex
    Flush_Timeout 2000
    Rule      "start" "/^\d{4}-\d{2}-\d{2} /" "cont"
    Rule      "cont"  "/^\s+at /"             "cont"
    Rule      "cont"  "/^Caused by:/"         "cont"

7) 입력 경로/권한/마운트 실수로 특정 노드·특정 컨테이너 로그가 누락

EKS에서 fluent-bit DaemonSet은 보통 hostPath로 /var/log/containers, /var/log/pods, /var/lib/docker/containers(런타임별) 등을 마운트합니다. 런타임이 containerd인데 docker 경로만 보거나, 마운트가 빠지면 일부 로그가 아예 수집되지 않습니다.

증상

  • 특정 노드/AMI/노드그룹에서만 로그가 안 잡힘
  • fluent-bit는 정상 Running인데 입력 레코드가 거의 없음

확인

kubectl -n logging exec -it ds/fluent-bit -- sh -c 'ls -al /var/log/containers | head'
kubectl -n logging exec -it ds/fluent-bit -- sh -c 'ls -al /var/log/pods | head'

해결

  • 런타임(containerd) 기준 경로 마운트 재점검
  • 보안 컨텍스트(권한) 확인: readOnly: true는 괜찮지만 접근 권한이 없으면 실패

8) 네트워크 경로 문제(NAT/IPv6/보안그룹)로 전송 지연·재시도 폭증

Output 대상이 AWS 서비스(CloudWatch Logs, OpenSearch, Kinesis 등)라면, VPC 엔드포인트/라우팅/NAT/보안그룹/DNS 문제로 연결이 간헐적으로 실패해 재시도가 누적됩니다. 이 경우 사용자는 “로그가 늦게 온다”고 느끼지만 실제로는 계속 실패하다가 나중에 성공하는 패턴입니다.

증상

  • 특정 AZ/서브넷의 노드에서만 지연
  • 특정 시간대(네트워크 혼잡, NAT 포화)에만 급격히 악화

확인

  • fluent-bit Pod가 떠 있는 노드의 서브넷 라우팅, NAT 게이트웨이 상태, VPC 엔드포인트 유무
  • STS/외부 엔드포인트 접근이 필요한 구성(IRSA, SigV4 등)이라면 STS 경로도 같이 점검

STS/DNS/라우팅 이슈가 엮일 때는 아래 글이 체크리스트로 유용합니다:

해결

  • VPC 엔드포인트(PrivateLink) 도입으로 NAT 의존도 감소
  • 서브넷 라우팅/SG/NACL, DNS 리졸버 경로 점검
  • 엔드포인트별 타임아웃/재시도 설정을 “무한 대기”가 아닌 현실적인 값으로

9) IRSA/권한 문제로 Output이 드롭 또는 무한 재시도(결과적으로 누락·지연)

CloudWatch Logs 출력이나 AWS SigV4가 필요한 출력(OpenSearch 등)에서 IRSA 권한이 부족하면, fluent-bit는 전송 실패를 반복합니다. 구성에 따라서는 재시도 끝에 버퍼가 찼을 때 오래된 chunk를 버리며 누락이 생길 수도 있습니다.

증상

  • fluent-bit 로그에 AccessDenied, UnrecognizedClient, ExpiredToken, Throttling
  • CloudWatch Logs에 log group/stream 생성 실패

확인

kubectl -n logging describe sa fluent-bit
kubectl -n logging logs ds/fluent-bit --tail=200 | egrep -i 'AccessDenied|Throttl|Expired|sts'

해결

  • IAM 정책(Logs:CreateLogStream/PutLogEvents 등) 재점검
  • STS 429(Throttling)로 지연이 누적되는 특수 케이스는 아래 글 참고: EKS IRSA는 되는데 STS 429 Throttling 해결
  • 토큰 갱신/시간 동기(NTP) 문제도 함께 확인

실전: 문제를 빠르게 좁히는 체크리스트(우선순위)

  1. fluent-bit 로그에서 failed to flush/retry가 보이면 Output 백프레셔(1, 8, 9)부터
  2. 특정 노드에 집중되면 DiskPressure/디스크/마운트(3, 7) 우선
  3. 재시작 직후부터 이상하면 tail DB/상태(4)
  4. 특정 앱/포맷만 문제면 멀티라인/파서(6)
  5. 고부하에서만 지연이면 리소스/CPU throttling(2)
  6. 고로그 앱에서만 구간 누락이면 kubelet 로테이션(5)

마무리: “fluent-bit 문제”가 아니라 “파이프라인 문제”로 보자

EKS에서 fluent-bit 로그 누락·지연은 대개 한 지점(예: Output 장애)에서 시작해, 버퍼/디스크/상태 DB/로테이션까지 연쇄적으로 영향을 줍니다. 그래서 해결도 “플러그인 설정만 만지는 것”보다,

  • 전송 경로 안정화(VPC 엔드포인트, DNS 안정화)
  • 버퍼/디스크/상태 DB 영속화
  • 리소스와 로테이션 정책의 균형

을 함께 잡아야 재발이 줄어듭니다.

원하시면 사용 중인 Output(CloudWatch/OpenSearch/Loki 등), fluent-bit ConfigMap, 노드 로그 로테이션 값(kubelet 설정), 그리고 “누락되는 예시 시간대/노드”를 기준으로 위 9가지를 실제 환경에 맞게 우선순위로 재정렬해 드릴게요.