컨테이너 내부에서 어떤 일이 발생하는지 확인하는 것은 디버깅 및 운영 측면에서 중요합니다. 어플리케이션 레벨에서 로그가 기록되도록 개발하여 별도의 로깅 서비스를 사용할 수도 있지만, 도커는 컨테이너의 표준 출력과 에러 로그를 별도로 메타데이터로 저장하고 이를 확인하는 명령어를 제공합니다.
기본적으로 컨테이너 로그는 JSON 형태로 도커 내부에 저장됩니다.
mysql 컨테이너를 생성하여 간단한 로그를 남겨보도록 하겠습니다.
1. # mysql 5.7 컨테이너 생성
2. docker run -d --name mysql \
3. -e MYSQL_ROOT_PASSWORD=1234 \
4. mysql:5.7
mysql과 같은 어플리케이션은 포그라운드(foreground)에서 동작하기 때문에 -d 옵션을 사용해서 백그라운드 모드로 컨테이너를 생성하는 경우가 많습니다. 따라서, 어플리케이션이 잘 구동되고 있는지 여부를 알 수 없지만, docker logs 커맨드를 통해서 컨테이너의 표준 출력을 확인하여 어플리케이션의 상태를 알 수 있습니다.
docker logs는 컨테이너 내부에서 출력을 보여주는 명령어입니다.
이번에는 -e 옵션을 제거하여 mysql 컨테이너를 생성하고, docker ps 명령어로 컨테이너의 목록을 확인해보겠습니다.
1. docker run -d --name no_password_mysql mysql:5.7
2. docker ps
no_password_mysql 컨테이너가 생성은 되었지만, 실행은 되지 않았음을 확인할 수 있습니다. 이 컨테이너는 docker start로 다시 시작해도 컨테이너는 시작되지 않습니다.
이런 경우 docker logs 명령어를 통해서 어플리케이션에 어떤 문제가 발생했는지 확인할 수 있습니다.
위 출력 결과처럼 컨테이너가 정상적으로 실행 및 동작하지 않고, docker attach 커맨드도 사용하지 못하는 환경에서 docker logs는 간단하고 빠르게 에러를 확인하게 해줍니다.
- 로그가 너무 많다면, --tail <숫자> 옵션을 사용하면 마지막 로그부터 출력할 줄의 수를 설정할 > 수 있음.
- --since 옵션에 유닉스 시간을 입력해 특정 시간 이후의 로그를 확인할 수 있음.
- -t 옵션으로 타임스탬프를 표시할 수 있음.
- -f 옵션을 사용하면 로그를 실시간 스트림으로 확인할 수 있음.
run 명령어로 -i -t 옵션을 설정해 docker attach 커맨드를 사용할 수 있는 컨테이너에서도 docker logs 명령어를 사용할 수 있습니다. 이 로그를 확인하면 컨테이너 내부에서 bash shell 등을 입출력한 내용을 확인할 수 있습니다.
기본적으로 위와 같은 컨테이너 로그는 JSON 형태로 도커 내부에 저장되는데, 이 JSON 파일은 아래 경로에서 컨테이너의 ID로 시작하는 파일명으로 저장됩니다.
cat /var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log
하지만 컨테이너 내부의 출력이 너무 많은 상태로 방치하게 되면, JSON 파일의 크기가 계속해서 커져서 호스트의 남은 저장 공간을 전부 사용할 수 있습니다. 이러한 상황을 방지하기 위해서 --log-opt 옵션을 사용하면 컨테이너 JSON 로그 파일의 최대 크기를 지정할 수 있습니다.
max-size는 로그 파일의 최대 크기, max-file은 로그 파일의 개수를 의미합니다.
1. docker run -it \
2. --log-opt max-size=10k --log-opt max-file=3 \
3. --name log-test ubuntu:20.04
로그 관련하여 어떠한 설정도 하지 않았다면, 도커는 기본적으로 위와 같은 컨테이너 로그를 JSON 파일로 저장하지만, 그 밖에도 각종 로깅 드라이버를 사용하고 로그를 수집할 수 있습니다.
대표적인 예로 syslog, journald, fluentd, awslogs 등이 있으며, 어플리케이션의 특징에 적합한 로깅 드라이버를 선택하면 됩니다.
로깅 드라이버는 기본적으로 json-file로 설정되지만, 도커 데몬 시작 옵션에서 --log-driver 옵
션을 사용하여, 기본적으로 사용할 로깅 드라이버를 변경할 수 있습니다. 또한, 위에서 살펴본 max-> size와 같은 --log-opt 옵션 또한 도커 데몬에 적용함으로써 모든 컨테이너에 일괄적으로 적용할
수 있습니다.
syslog는 유닉스 계열 운영체제에서 로그를 수집하는 오래된 표준 중의 하나라고 합니다. 커널, 보안 등 시스템과 관련된 로그, 어플리케이션의 로그 등 다양한 종류의 로그를 수집해 저장합니다.
대부분의 유닉스 계열 운영체제에서는 syslog를 사용하는 인터페이스가 동일하기 때문에 체계적으로 로그를 수집하고 분석할 수 있다는 장점이 있습니다.
다음 커맨드를 통해서 syslog에 로그를 저장하는 컨테이너를 생성해보겠습니다. 컨테이너의 커맨드가 echo syslogtest로 설정되기 때문에, 컨테이너는 생성되면서 syslogtest를 출력하고 종료될 것입니다.
(-d 옵션으로 주었기 때문에 백그라운드로 실행되어 호스트에는 나타나지 않는 것으로 추측됩니다..)
1. docker run -d --name syslog_container \
2. --log-driver=syslog \
3. ubuntu:20.04 \
4. echo syslogtest
syslog 로깅 드라이버는 기본적으로 로컬호스트의 syslog에 저장하므로 운영체제 및 배포판에 따라 syslog 파일의 위치를 알아야합니다. 우분투 14.04의 경우 /var/log/syslog에서 확인이 가능하며, 우분투 16.04 이상은 journalctl -u docker.service 커맨드로 확인할 수 있다.
현재 호스트 OS는 우분투 20.04를 사용하므로, journalctl -u docker.service 커맨드를 입력해서 마지막 부분을 보면 syslogtest를 확인할 수 있습니다.
syslog를 원격 서버에 설치하면 로그 옵션을 추가해 로그 정보를 원격 서버로 보낼 수도 있습니다.
연습하기 위해서는 서버 호스트와 클라이언트 호스트, 두 개의 머신이 필요하기 때문에 직접 시도해보지는 않았습니다.
fluentd는 각종 로그를 수집하고 저장할 수 있는 기능을 제공하는 오픈소스 도구입니다. 도커 엔진의 컨테이너의 로그를 fluentd를 통해 저장할 수 있도록 플러그인을 공식적으로 제공하고 있습니다. fluentd는 데이터 포맷으로 JSON을 사용하기 때문에 쉽게 사용할 수 있을뿐만 아니라 수집되는 데이터를 ASW S3, HDFS(Hadoop Distributed File System), MongoDB 등 다양한 저장소에 저장할 수 있다는 단점이 있습니다.
예를 들면, fluentd와 MongoDB를 연동해서 데이터를 저장하는 방법이 있습니다. 특정 호스트에 생성되는 컨테이너는 하나의 fluentd에 접근하고, fluentd는 몽고DB에 데이터를 저장하는 구조입니다.
예제는 우선 패스하도록 하겠습니다.. !
ASW(Amazon Web Service)에서는 로그 및 이벤트 등을 수집하고 저장해 시각적으로 보여주는 클라우드워치(CloudWatch)를 제공합니다. 도커를 ASW EC2에서 사용하고 있다면, 다른 도구를 별도로 설치할 필요없이 컨테이너에서 드라이버 옵션을 설정하는 것만으로 클라우드워치 로깅 드라이버를 사용할 수 있습니다.
클라우드워치도 추후에 따로 한 번 연습해보는 시간을 가져보도록 하겠습니다.