본문 바로가기

모니터링

로그 수집 - Service Discovery에 관하여(filebeat autodiscovery)

보통 filebeat를 활용해서 kubernetes 클러스터에 배포된 application의 로그를 읽으려고하면 filebeat을 daemonset으로 띄우고 난 뒤 /var/log/containers에 있는 로그를 수집한다.

( 주의해야한다. filebeat에서 input을 docker 혹은 container로 해야 데이터를 수집한다. 그냥 input을 log(file인가?)로 하고 해당 경로를 하드코딩해서 넣거나 와일드카드로 넣어도 작동하지가 않는다. 그 파일이 링크로 연결되어있는 파일이기 때문인 것 같다. )

 

그런데 이렇게 설정해두면 실제 운영환경에서 문제가 생긴다.

1. container는 죽었다 살았다 하면서 계속 그 유니크 값이 달라지는데, 그렇기 때문에 하드 코딩을해서 input에 넣을 수가 없다. 

2. 그렇다고 * 이렇게 와일드카드로 넣어서 모든 container를 계속 읽는다고 치면, 내가 원하는 컨테이너만 읽을 수가 없을 뿐더러 다 읽고나서 논리적으로 분리된 output topic으로 나간다고 할 때 보낼 방법이 없다. (예를 들어 a application에서 나온 정보는 a output으로, b application에서 나온 정보는 b output으로 보낼 수가 없음. )

 

그래서 filebeat autodiscovery를 사용한다.

autodiscovery는 우리가 특정 조건을 설정하고, 해당 조건에 만족하는 container만 수집하도록 도와준다. 이 때, 메타데이터 등을 활용하여 다른 output으로도 보낼 수 있다.

autodiscovery 예시는 아래와 같다.

 

filebeat.yml: |-
filebeat.autodiscover:
providers:
- type: kubernetes
templates:
- condition:
equals:
kubernetes.annotations.logging: "true"
config:
- type: container
paths:
- '/var/log/containers/*-${data.kubernetes.container.id}.log'

output.console:
pretty: true

 

여기서 주의해야할 점은 filebeat.autodicover 자체가 filebeat.input을 대체한다. 

보통 filebeat.yaml을 작성할 때 

filebeat.inputs:

-type: container

paths:

-'/var/log/container/*.log'

이런식으로 작성하는데, 이 부분이 그대로 위에 config 부분에 사용된다고 보면된다.

그리고 autodiscovery는 kubernetes event가 발생하면 이를 탐지해서 반응하는데, 이 때 json으로 template처럼 해당 pod에 대한 정보를 가지고 온다. 그 데이터에 접근해야 될 경우가 생기는데, 그럴 때는 config에서는 data.kubernetes. 를 통해 접근한다.

templates: 부분에서는 data.으로 접근할 필요가 없다! 그냥 kubernetes.으로 접근하면 된다!

 

filebeat를 daemonset으로 활용할 때 한 가지 주의할 점은, 반드시 kubernetes를 구성하는 노드의 호스트 volume을 mount해야 한다!!