Journey to Security/클라우드

[Docker] Nginx 로그를 Fluentd를 통해 MongoDB에 저장하기 (중앙 집중형 로그 관리)

Cordilog 2026. 1. 12. 21:07

도커 컨테이너는 기본적으로 휘발성을 가진다.

컨테이너가 삭제되면 내부의 로그 파일도 함께 사라지기 때문에, 운영 환경에서는 로그를 외부 저장소에 영구적으로 보관할 방법이 필요하다.

 

이러한 로그 수집의 예시로 웹 서버(Nginx)에서 발생하는 로그를 수집기(Fluentd)를 거쳐 데이터베이스(MongoDB)에 중앙 집중적으로 저장하는 파이프라인을 구축해 보자.

1. 전체 아키텍처 및 데이터 흐름

시스템의 전체적인 로그 데이터 흐름은 다음과 같다.

 

 

  • Nginx: 클라이언트 요청을 처리하고 표준 출력(Stdout)으로 로그를 뱉는다.
  • Docker Log Driver: 컨테이너의 로그를 받아서 파일로 쌓는 대신 Fluentd로 전송한다.
  • Fluentd: 수신한 로그를 버퍼링하고 MongoDB가 이해할 수 있는 포맷(json)으로 변환한다.
  • MongoDB: 최종적으로 로그 데이터를 영구 저장한다.

2. 미리 준비할 사항

  • Docker Log Driver: 도커는 컨테이너 로그를 처리하는 다양한 드라이버(json-file, syslog, fluentd, awslogs 등)를 지원한다. 여기서는 fluentd 드라이버를 사용한다.
  • 호환성 체크: 여기서 사용할 alicek106/fluentd:mongo 이미지는 구형 플러그인을 포함하고 있으므로, 호환성을 위해 MongoDB 5.0 버전을 사용한다.
  • Host IP 확인: 컨테이너 간 통신을 위해 호스트 머신의 IP 주소가 필요하다. (hostname -I 명령어로 확인)

3. 구축 단계 (Step-by-Step)

Step 1: 로그 저장소 구축 (MongoDB)

로그를 최종 저장할 데이터베이스를 실행한다. (Fluentd 플러그인과의 호환성을 고려해 5.0 버전을 사용)

docker run --name mongodb -d -p 27017:27017 mongo:5.0

 

 

Step 2: 수집기 설정 (fluent.conf 작성)

Fluentd가 로그를 어떻게 받아서 어디로 보낼지 정의하는 설정 파일을 작성한다.

  • vi fluent.conf 또는 nano fluent.conf
<source>
  @type forward        ## Docker Log Driver로부터 로그를 수신
</source>

<match docker.**>      ## 태그가 docker.으로 시작하는 모든 로그를 매칭
  @type mongo          ## 출력 플러그인으로 MongoDB 사용
  database nginx       ## 저장할 DB 이름
  collection access    ## 저장할 컬렉션(테이블) 이름
  host [Host_IP]       ## MongoDB가 실행 중인 호스트 IP (예: 192.168.x.x)
  port 27017
  flush_interval 10s   ## 10초마다 모아서 한 번에 저장 (성능 최적화)
</match>

Step 3: 수집기 실행 (Fluentd)

작성한 설정 파일을 컨테이너 내부에 마운트하여 Fluentd를 실행한다.

docker run -d --name fluentd -p 24224:24224 \
-v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf \
-e FLUENTD_CONF=fluent.conf \
alicek106/fluentd:mongo

 

 

  • -p 24224:24224: Fluentd의 기본 수신 포트 개방.
  • -v: 호스트에 있는 fluent.conf 파일을 컨테이너 내부 설정 경로로 연결.

Step 4: 웹 서버 실행 및 로그 드라이버 연결 (Nginx)

Nginx를 실행하되, 로그를 내부에 남기지 않고 Fluentd로 쏘도록 옵션을 부여한다.

docker run -d -p 8000:80 --name nginx-mongo \
--log-driver=fluentd \
--log-opt fluentd-address=[Host_IP]:24224 \
--log-opt tag=docker.nginx.webserver \
nginx:latest

 

 

  • --log-driver=fluentd: 로그를 Fluentd로 보냄을 명시.
  • --log-opt fluentd-address: Fluentd가 실행 중인 주소 지정.
  • --log-opt tag: 로그 분류를 위한 태그 설정 (fluent.conf의 match docker.** 규칙에 걸리게 됨).

4. 결과 확인

시스템 구축이 완료되었으므로 로그가 정상적으로 흐르는지 테스트한다.

1. 트래픽 발생

웹 서버에 접속하여 로그를 생성한다. (테스트를 위해 3~4회 수행)

curl localhost:8000
curl localhost:8000
curl localhost:8000

 

 

2. MongoDB 데이터 조회

MongoDB 컨테이너에 접속하여 실제로 데이터가 들어왔는지 확인한다.

# MongoDB 접속
docker exec -it mongodb mongo

# 데이터 조회
use nginx
db.access.find()

 

 

위와 같이 JSON 형태로 로그가 조회된다면 성공이다.

 

위 테스트 내용을 시퀀스 다이어그램으로 표현하면 다음과 같다. 

 

5. 마무리

이러한 구성을 통해 얻을 수 있는 이점은 다음과 같다.

  1. 데이터 영속성: Nginx 컨테이너가 삭제되거나 재생성되어도 과거 로그 기록은 MongoDB에 안전하게 남아있다.
  2. 통합 관리: 여러 대의 웹 서버를 운영하더라도 모든 로그가 하나의 DB로 모이므로, 장애 발생 시 원인 분석이 용이하다.
  3. 데이터 활용: 텍스트 파일이 아닌 DB에 저장되므로, 쿼리를 통해 특정 시간대나 특정 에러 코드만 검색하는 등 2차 가공 및 분석이 쉬워진다.