[Docker Container의 로깅 구조에 대한 요약정리]



컨테이너에 올라가 있는 어플리케이션들이 뿜뿜하는 로그들이 어떤식으로 Docker에 의해 수집되는가를 간략히 정리해본다.


참고 링크 : https://docs.docker.com/config/containers/logging/configure/


docker logs 명령어는 컨테이너의 /dev/stdout, stdin, stderr 을 보여주는데, 이것이 무슨말인지 궁금하다면 nginx 표준 이미지를 실행시켜서 컨테이너 내부에 들어가 보자.


sudo docker run -d nginx

sudo docker -it exec [container_id] /bin/bash


nginx의 로그 파일인 /var/log/nginx/access.log 파일 정보를 ls로 확인해보면 /dev/stdout 으로 심볼릭 링크가 걸려 있음을 확인할 수 있다. 

이제 nginx 로그가 어떤식으로 Docker에 쌓이게 되는지 Flow를 정리하면 다음과 같다.

  1. nginx access 로그 발생
  2. nginx는 컨테이너 내의 /var/log/nginx/access.log 파일에 로그 기록
  3. /var/log/nginx/access.log --> /dev/stdout (즉, 표준 출력)으로 심볼릭 링크가 되어 있다!
  4. Docker는 컨테이너의 표준 출력으로 부터 발생한 로그에 컨테이너의 추가 Value (Container ID, Timestamp) 등을 추가하여 Json 파일 형태로 기록
  5. docker logs 명령어는 해당 JSON 파일 보여줌 ( docker insepect 명령어로 컨테이너의 상세 정보를 보면 해당 컨테이너의 로그 파일 위치를 확인 가능하며 파일을 열어보면 json 형태로 출력되고 있음)

여기서 중요한 부분은 2와 3번 과정으로, 쉽게 생각하면 어플리케이션이 그냥 콘솔로 로그를 출력해버리면 Docker가 알아서 수집해준다는 것이다. 위의 nginx 심볼릭 링크는 컨테이너 어플리케이션이 로그를 출력하기 위한 하나의 예시일 뿐 반드시 이런식으로 구현해야 하는 것은 아니다.



참고로 위에서 확인한 Docker의 기본 로그 출력방식은 Default Logging Driver : JSON-File를 사용한 것이다. 이것만으로는 제약이 있으므로, Docker는 추가적인 logging driver를 사용하는데, docker info 명령을 사용하면 현재 사용중인 Logging Driver의 설정 상태를 확인 할수 있다.


이 기본 로깅 드라이버가 아닌 다른 것을 사용하기 위해선 /etc/docker에 daemon.json을 파일을 작성하여야 하며


위 예시는 Docker의 Fluentd 로깅 드라이버를 사용하겠다는 설정이다. 이 로깅 드라이버는 발생된 컨테이너의 로그를 앞서 본 Json file 형태가 아니라 해당 주소와 포트의 Fluentd로 포워딩해주게 된다. 상세한 사항은 Docker logging driver를 참고한다.




참고 : 컨테이너->로그 드라이버로 로그를 전송하기 위한 모드 2가지

  • default :  direct, blocking
  • non-blocking : stdout, stderr 스트림이 차단되어 발생하는 예상치 못한 어플리케이션 fail을 방지할 수 있음, 단, 버퍼가 가득 차면 새 메시지가 들어올 때 과거 메시지는 메모리에서 드랍됨. 메시지 드랍은 어플리케이션의 로그 Writing 프로세스의 블락 보다 선호됨
    버퍼 사이즈 지정 가능 : 기본값은 1MB : --log-opt mode=non-blocking --log-opt max-buffer-size=4m