쿠버네티스에서 애플리케이션을 띄우다 보면 처음에는 이런 것만 신경 쓴다.
Pod 잘 떴나?
Service 연결됐나?
Ingress로 접속되나?
그런데 운영 관점으로 넘어가면 질문이 바뀐다.
에러가 났을 때 로그는 어디서 보지?
nginx access log는 어디에 쌓이지?
Pod가 죽으면 로그도 사라지는 거 아냐?
모든 노드의 로그를 한 곳에서 모아볼 수 없을까?
이때 등장하는 도구가 Fluent Bit이다.
Fluent Bit은 한마디로 가벼운 로그 수집기다.
Fluent Bit
= 로그를 읽고
= 필요한 형태로 가공하고
= OpenSearch, Elasticsearch, Loki, S3 같은 저장소로 보내는 도구
흐름은 대충 이렇게 보면 된다.
애플리케이션 로그
↓
Fluent Bit
↓
OpenSearch
↓
OpenSearch Dashboards에서 조회
이번 실습에서는 nginx 로그를 Fluent Bit이 수집해서 OpenSearch로 보내고, OpenSearch Dashboard에서 확인하는 구조를 다뤘다.
Pod 안에서 로그를 직접 보면 되지 않을까?
kubectl logs nginx-pod
물론 이 명령어로 로그를 볼 수 있다.
하지만 운영 환경에서는 이것만으로 부족하다.
예를 들어 Pod가 100개라면?
nginx-1 로그 보고
nginx-2 로그 보고
nginx-3 로그 보고
...
이렇게 하나씩 볼 수 없다.
또 Pod가 죽고 새로 만들어지면 로그 추적이 어려워진다.
그래서 운영 환경에서는 보통 로그를 한 곳으로 모은다.
여러 Pod 로그
여러 Node 로그
여러 Namespace 로그
↓
Fluent Bit
↓
로그 저장소
즉, Fluent Bit은 분산된 로그를 중앙으로 모아주는 수집기라고 보면 된다.
Fluent Bit은 보통 세 가지 일을 한다.
1. Input
로그를 읽는다
2. Filter
로그를 가공한다
3. Output
로그 저장소로 보낸다
조금 더 쉽게 보면:
Input = 어디서 로그를 읽을래?
Filter = 로그를 어떻게 다듬을래?
Output = 어디로 보낼래?
예를 들어 nginx 로그를 OpenSearch로 보내는 경우는 이런 느낌이다.
Input
= /var/log/nginx/access.log 읽기
Filter
= Kubernetes metadata 붙이기
= namespace, pod name, container name 추가
Output
= OpenSearch로 전송
Fluent Bit과 OpenSearch는 역할이 다르다.
| 도구 | 역할 |
|---|---|
| Fluent Bit | 로그를 수집하고 전달 |
| OpenSearch | 로그를 저장하고 검색 |
| OpenSearch Dashboards | 로그를 화면에서 조회 |
즉, Fluent Bit은 저장소가 아니다.
Fluent Bit은 배달부에 가깝다.
nginx 로그 발생
↓
Fluent Bit이 읽음
↓
OpenSearch에 배달
↓
Dashboard에서 검색
비유하면 이렇다.
Fluent Bit = 택배 기사
OpenSearch = 물류 창고
Dashboard = 물건 검색 화면
첫 번째 방식은 Sidecar 패턴이다.
Sidecar는 하나의 Pod 안에 메인 컨테이너와 보조 컨테이너를 같이 넣는 방식이다.
Pod
├─ nginx container
└─ fluent-bit container
nginx는 웹 서버 역할을 하고,
Fluent Bit은 nginx가 남긴 로그를 읽어서 OpenSearch로 보낸다.
보통 같은 Pod 안에서 로그 파일을 공유하기 위해 volume을 같이 쓴다.
nginx
→ /var/log/nginx/access.log에 로그 작성
fluent-bit
→ 같은 파일을 읽음
→ OpenSearch로 전송
이 방식은 특정 애플리케이션 로그를 세밀하게 수집하고 싶을 때 좋다.
예를 들어 이 nginx만 특별한 로그 포맷으로 수집하고 싶다면 Sidecar 패턴을 쓸 수 있다.
| 구분 | 내용 |
|---|---|
| 장점 | 애플리케이션별 로그 수집 설정을 세밀하게 할 수 있음 |
| 장점 | 메인 컨테이너와 로그 수집 컨테이너가 같은 Pod 안에 있어서 로그 파일 공유가 쉬움 |
| 단점 | Pod마다 Fluent Bit 컨테이너가 추가됨 |
| 단점 | Pod 수가 많아질수록 리소스 사용량이 늘어남 |
쉽게 말하면:
Sidecar 방식
= 이 앱 로그는 따로 특별하게 관리하고 싶을 때
두 번째 방식은 Cluster-level 로그 수집이다.
이번 실습에서는 Fluent Bit을 DaemonSet으로 배포했다.
helm repo add fluent https://fluent.github.io/helm-charts
helm repo update
helm install fluent-bit fluent/fluent-bit \
-f fluentbit-daemonset-custom-values.yaml \
--create-namespace \
--namespace monitoring
DaemonSet은 모든 노드에 Pod를 하나씩 띄우는 리소스다.
Node 1
└─ fluent-bit
Node 2
└─ fluent-bit
Node 3
└─ fluent-bit
즉, 각 노드마다 Fluent Bit이 하나씩 떠서 그 노드의 컨테이너 로그를 수집한다.
Fluent Bit을 Deployment로 띄우면 특정 노드에만 뜰 수 있다.
그런데 로그는 모든 노드에서 발생한다.
Node 1에도 로그가 있고
Node 2에도 로그가 있고
Node 3에도 로그가 있다
그래서 Fluent Bit은 보통 DaemonSet으로 띄운다.
모든 노드의 로그를 수집해야 한다
↓
모든 노드에 로그 수집기가 있어야 한다
↓
DaemonSet 사용
이건 CKA에서도 중요한 포인트다.
모든 노드에 하나씩 떠야 하는 Pod
= DaemonSet
대표 예시는 다음과 같다.
로그 수집기: Fluent Bit
모니터링 에이전트: Node Exporter
네트워크 플러그인: CNI
스토리지 에이전트
보안 에이전트
| 구분 | 내용 |
|---|---|
| 장점 | Pod마다 sidecar를 붙이지 않아도 됨 |
| 장점 | 클러스터 전체 로그를 공통 방식으로 수집하기 좋음 |
| 장점 | 운영 환경에서 일반적으로 많이 사용 |
| 단점 | 애플리케이션별로 매우 세밀한 설정을 하기는 상대적으로 어려움 |
| 단점 | 노드 로그 경로, 권한, 파싱 설정을 이해해야 함 |
쉽게 말하면:
Cluster-level 방식
= 클러스터 전체 로그를 한 번에 모으고 싶을 때
| 구분 | Sidecar 패턴 | Cluster-level 패턴 |
|---|---|---|
| 배포 위치 | 애플리케이션 Pod 안 | 각 Node마다 |
| Kubernetes 리소스 | Pod 내부 컨테이너 | DaemonSet |
| 로그 수집 범위 | 특정 Pod 중심 | 클러스터 전체 |
| 장점 | 앱별 세밀한 제어 가능 | 운영 전체 로그 수집에 적합 |
| 단점 | Pod마다 sidecar 필요 | 앱별 커스텀은 상대적으로 약함 |
| 사용 예시 | 특정 nginx 로그 별도 수집 | 전체 컨테이너 로그 수집 |
정리하면 이렇다.
Sidecar
= 특정 앱 전용 로그 수집
Cluster-level
= 클러스터 공통 로그 수집
Fluent Bit 설정을 볼 때는 세 가지만 보면 된다.
INPUT
FILTER
OUTPUT
예를 들어 이런 질문을 던지면 된다.
어디서 읽는가?
무엇을 붙이거나 가공하는가?
어디로 보내는가?
OpenSearch로 보내는 설정이라면 Output 쪽에 보통 이런 정보가 들어간다.
Host
Port
Index
TLS 여부
인증 정보
그리고 Kubernetes 로그를 수집한다면 Filter에서 이런 metadata를 붙일 수 있다.
namespace
pod name
container name
labels
annotations
이 metadata가 붙어야 Dashboard에서 로그를 찾기 쉽다.
예를 들어 나중에 이런 식으로 검색할 수 있다.
namespace = nginx
pod_name = nginx-deployment-xxxxx
container_name = nginx
이번 실습 흐름은 이렇게 볼 수 있다.
1. OpenSearch 설치
2. OpenSearch Dashboards 설치
3. Dashboard Ingress 생성
4. nginx 애플리케이션 배포
5. Fluent Bit 배포
6. nginx에 접속해서 로그 발생
7. OpenSearch Dashboard에서 index 확인
8. Discover에서 로그 확인
강의에서는 OpenSearch Dashboard에서 다음 흐름으로 로그를 확인했다.
Index Management > Indices 확인
Dashboards Management > Index patterns 생성
Discover 메뉴에서 로그 조회
sidecar 방식에서는 sidecar-nginx-log-* 인덱스를 확인했고, cluster-level 방식에서는 nginx-* 인덱스를 확인하는 흐름이었다.
Fluent Bit은 로그를 저장하는 게 아니라 보내는 도구다.
Fluent Bit = 수집/전달
OpenSearch = 저장/검색
둘 다 웹 UI라서 헷갈릴 수 있다.
Grafana
= 메트릭 시각화에 주로 사용
OpenSearch Dashboards
= 로그 검색과 분석에 주로 사용
물론 Grafana도 로그를 볼 수 있고, OpenSearch Dashboards도 시각화를 할 수 있지만, 이번 실습의 역할은 이렇게 나눠서 이해하면 된다.
Prometheus + Grafana
= 메트릭
Fluent Bit + OpenSearch + Dashboards
= 로그
이건 거의 외워도 된다.
DaemonSet
= 모든 노드에 Pod 하나씩 배포
그래서 로그 수집기와 잘 맞는다.
Fluent Bit은 Kubernetes에서 발생하는 로그를 읽어서 OpenSearch 같은 저장소로 보내는 가벼운 로그 수집기다.
Pod 로그
Node 로그
Container 로그
↓
Fluent Bit
↓
OpenSearch / Elasticsearch / Loki / S3
Sidecar로 붙이면 특정 앱 로그를 세밀하게 수집할 수 있고,
DaemonSet으로 띄우면 클러스터 전체 로그를 공통 방식으로 수집할 수 있다.
결국 Fluent Bit을 공부한다는 건 단순히 로그 수집기 하나를 아는 게 아니라,
Kubernetes 운영에서 로그를 어떻게 중앙화할 것인가
를 공부하는 것이다.