본문 바로가기
Data Engineering/Fluentd

Fluent Bit으로 쿠버네티스 컨테이너의 로그파일에서 로그 수집

by 홍띠 2022. 11. 27.
Why Fluent Bit?
Fluent bit은 로그 수집기인 Fluentd의 경량화된 버전이다. 각 컨테이너의 로그를 수집하여 전달하는 Forwarder의 역할만 수행할 것이고, 사이드카 컨테이너로 구성 예정이므로 메인컨테이너의 성능에 영향을 적게 하기 위해 Fluentd 보다 리소스를 작게 필요로 하는 Fluent Bit을 사용하려고 한다. 
(Fluent bit&Fluent Bit: https://docs.fluentbit.io/manual/about/fluentd-and-fluent-bit)

EKS에서 구동중인 각 Deployment에는 N개의 파드가 작업을 분산하여 실행한다. 각각의 파드에서 발생하는 로그를 모으기 위해서, 각 파드의 사이드카 컨테이너로써 Fluent Bit을 배치하여, 메인 컨테이너의 로그를 한곳으로 하려고 한다. 아래의 그림처럼 구성할 예정이다.


Fluent bit을 동작시키기 위해서는 Fluentd와 마찬가지로 conf파일을 작성해야 한다.

Conf파일은 또한 Configmap으로 등록하여, 컨테이너에 volume mount로 읽도록 한다.(참고: Configmap, Secret 사용하기 )

#fluent-bit.conf
[SERVICE]
    parsers_file parsers_multiline.conf

[INPUT]
    name    tail
    tag     sample.log
    path    /var/log/sample.log
    db      /var/log/sample.log.db
    multiline.parser multiline-regex-springLog
    
[OUTPUT]
    Name    forward
    Match   sample.*
    Host    fluentd-release
    Port    24224
    
[FILTER]
    Name    record_modifier
    Match   sample.*
    Record  node ${MY_NODE_NAME}
    Record  pod_name ${MY_POD_NAME}
    Record  pod_ip ${MY_POD_IP}

Input과 Output만 잘 설정되어 있으면은 로그 수집의 기능에는 문제 없이 동작한다. 여기서는 좀 더 로그를 정제해서 내보내기 위하여 Filter와 parser를 사용했다.

 

Input에서는 파일을 읽어오도록 tail을 사용하였고, 해당 데이터의 태그를 적절하게 지정 하였다. 이 tag를 사용해서 다른 과정에서 처리할 데이터를 구분한다. 이외의 다른 옵션들은 상황에 맞게 사용하면 된다. Input에 사용된 multi line parser는 Fluent-bit에서 multiline parser 사용 을 참고하면 된다. 

Output은 해당 파드 외부의 Fluentd로 전달할 것이므로 forward를 사용하였다. Fluentd가 구성된 방식에 맞게 Host와 포트를 지정해준다.

Filter는 쿠버네티스의 각 파드정보를 추가하도록 하여, 추후에 여러개의 파드에서 수집된 로그를 확인 할 때, 로그가 발생된 파드와 노드를 알 수 있도록 하였다.


이제 Sidecar 컨테이너로써 쿠버네티스 yaml파일에 작성한다.

아래의 예시는 다른 부분들은 생략하고, Fluent bit을 설정하는 부분만 추린것이다.

~
spec:
  template:
    spec:
      containers:
        - name: Main Container
            - name: logs-emptydir
              mountPath: /usr/local/tomcat/logs
        - name: fluent-bit
          image: fluent/fluent-bit:1.9
          resources:
            limits:
              cpu: 200m
              memory: 256Mi
            requests:
              cpu: 10m
              memory: 64Mi
          env:
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          volumeMounts:
            - name: logs-emptydir
              mountPath: /var/log
            - name: fluentbit-conf
              mountPath: /fluent-bit/etc/fluent-bit.conf
              subPath: fluent-bit.conf
            - name: fluent-parser
              mountPath: /fluent-bit/etc/parsers_multiline.conf
              subPath: parsers_multiline.conf
      volumes:
        - name: fluentbit-conf
          configMap:
            name: fluentbit-conf
        - name: fluent-parser
          configMap:
            name: fluent-parser
        - name: logs-emptydir
          emptyDir: {}
~

컨테이너의 Image는 공식 fluent-bit 이미지를 사용하였고, 리소스는 사용환경에 맞게 설정하면 된다.

env에서는 fluent-bit.conf의 Filter에서 사용할 파드의 정보를 환경변수로써 등록하게 하였다.

volumeMounts 에서는 fluent bit에 사용되는 conf 설정파일들을 configmap에서 읽어오도록 하였고,

중요한 부분은 메인 컨테이너와 사이드카 컨테이너(Fluent Bit)이 emptydir을 사용해서 메인 컨테이너의 로그 디렉토리에 Fluent bit이 접근 할 수 있도록 설정해야 한다. 

 

 

이제 작성한 yaml 파일을 배포하면, 메인컨테이너의 로그파일을 fluent-bit 컨테이너가 읽어와 fluentd로 전달 할 것이다.

'Data Engineering > Fluentd' 카테고리의 다른 글

Fluent Bit에서 특정 패턴 Exclude 하기  (0) 2023.07.23
Fluent-bit에서 multiline parser 사용  (0) 2022.10.30