docker 컨테이너 log 남기기

2020. 1. 26. 18:16devops/docker

docker 컨테이너 log 남기기

container안에서 어떤 일(에러 및 로그 정보)이 생기는지는 매우 중요합니다. 도커는 컨테이너의 표준 출력과 에러 로그를 별도의 메타데이터 파일로 저장하며 이를 확인하는 명령어를 제공합니다. 

 

logs 명령어

docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:5.7

-d옵션을 사용하여 백그라운드로 실행하게 만들겠습니다. container를 생성한 후 docker logs 명령어를 통해서 log정보를 통해 실행정보를 확인할 수 있습니다. 

 docker logs mysql                                                                                                                                              ✔  9577  18:29:03
2020-01-26 09:29:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-01-26 09:29:03+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-01-26 09:29:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-01-26 09:29:03+00:00 [Note] [Entrypoint]: Initializing database files

이번에는 고의로 에러를 발생시켜 보겠습니다. 

docker run -d --name no_password_mysql \
mysql:5.7

위와 같은 명령어를 사용하여 container를 만든 다음 docker ps를 확인하면 container가 종료된 것을 볼 수 있습니다. 이럴 때 docker logs를 사용하여 확인할 수 있습니다. 

docker logs no_password_mysql                                                                                                                                  ✔  9582  18:32:06
2020-01-26 09:32:02+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-01-26 09:32:02+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-01-26 09:32:02+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-01-26 09:32:02+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

당연히 -e옵션을 통해 비밀번호를 안넣어주어서 오류가 난 것을 확인할 수 있습니다. 로그가 너무 길어서 읽기 힘들다면 --tail 옵션을 사용하여 마지막 줄 부터 몇개의 줄을 선택하여 볼 수 있습니다. 

docker logs --tail 2 no_password_mysql

또는 since 명령어를 사용하여 유닉스 특정 시간 이후의 로그를 확인할 수 있습니다. 

docker logs --since 147465979 mysql

그리고 -f는 실시간으로 로그를 확인하고 -t는 timestamp와 함께 로그가 표시됩니다. 

docker logs -f -t mysql

 

log josn파일로 저장하기 

컨테이너 로그은 json형태로 docker 내부에 저장됩니다. 아래와 같은 경로에 저장됩니다.

/var/lib/docker/cotainers/${CONTAINER_ID}/${CONTAINER_ID}-json.log

mac에서는 위의 경로에 존재하지 않아서 linux 계열 os에서는 

~/Library/Containers/com.docker.docker/Data/log/vm
~/Library/Containers/com.docker.docker/Data/log/host

확인할 수 있었습니다. 

 

--log-opt 옵션으로 json 로그 파일의 최대 개수 및 용량을 설정할 수 있습니다. 

ㅡmax-size는 파일의 용량 max-file은 개수를 의미합니다. 

docker run -it \
--log-opt max-size=10k --log-opt max-file=3 \
--name log-test ubuntu:14.04

syslog 로그

컨테이너의 로그는 json 뿐만 아니라 syslog로 보내 저장하도록 설정할 수 있습니다. 대부분 unix 계열의 운영체제에서는 syslog를 사용하는 인터페이스가 동일하기 때문에 체계적으로 로그를 수집하고 분석 할 수 있다는 장점이 있습니다. 

 

syslog에 로그를 저장하는 컨테이너를 생성합니다. 컨테이너의 커맨드가 echo syslogtest로 설정되기 때문에 syslogtest라는 문구를 출력하고 컨테이너는 종료될 것입니다. 

docker run -d --name syslog_container \                                                                                                                        ✔  9668  19:17:35
--log-driver=syslog \
ubuntu:14.04 \
echo syslogtest
5d6fb0fd051e2d803e099e13867f82a4db5c891809dce25bd1bd4210e40fe0a4
docker: Error response from daemon: failed to initialize logging driver: Unix syslog delivery error.

위와 같이 진행되면 로컬의 os마다 다르게 저장됩니다. 

  • ubuntu 14.04 /var/log/syslog
  • centos, RHEL /var/log/messages
  • ubuntu 16.04, CoreOS journalctl -u docker.service

 

fluentd 로깅

fluented는 각종 로그를 수집하고 저장할 수 있는  기능을 제공하는 오픈소스이다. 도커 엔진의 컨테이너의 로그를 fluentd를 통해 저장할 수 있도록 공식적으로 제공하고 있습니다. 

fluentd를 통 하둡, s3, mongodb  등에 저장할 수 있습니다. 

 

https://hub.docker.com/_/fluentd

 

fluentd - Docker Hub

Supported tags and respective Dockerfile links Quick reference Where to get help:the Docker Community Forums, the Docker Community Slack, or Stack Overflow Where to file issues:https://github.com/fluent/fluentd-docker-image/issues Maintained by:Fluentd Sup

hub.docker.com

mongodb, fluentd, nginx등을 로컬주소로 사용하겠습니다. 

 

mongodb container실행 

docker run -d --name mongoDB -p 27017:27017 mongodb

fluentd container를 실행하기 전에 fluentd 설정 정보인 fluent.conf를 만들어보겠습니다. 

<source>
  @type forward
</source>

<match docker.**>
  @type mongo
  database nginx
  collection access
  host 172.30.1.34
  port 27017
  flush_interval 10s
</match>

위의 설정 내용은 로그 데이터를 mongoDB에 저장하고 access라는 collection에 저장하며 host는 local의 ip port는 mongodb container를 만들 때 사용한 port번호를 적어줍니다. <match docker.**>는 로그의 내용이 docker로 시작하면 mongodb에 저장하겠다는 의미입니다. 

docker run -d --name fluentd -p 24224:24224 \                                                                                                                  ✔  9710  22:36:36
-v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf \
-e FLUENT_CONF=fluent.conf \
alicek106/fluentd:mongo

 

다음으로 로그를 만들어내는 webserver nginx를 사용해보겠습니다. 어떤 이미지를 사용해도 상관없습니다. --log-opt의 주소는 fluentd의 주소를 사용합니다. tag의 내용인 docker.nginx.webserver가 <match docker.**>와 같아서 로그가 mongoDB에 저장됩니다. 

docker run -p 80:80 -d \                                                                                                                                       ✔  9710  22:36:36
--log-driver=fluentd \
--log-opt fluentd-address=172.30.1.34:24224 \
--log-opt tag=docker.nginx.webserver \
nginx

80번 포트를 통해 nginx에 접근할 수 있습니다. 

docker exec -it mongoDB mongo

위 명령어를 통해 배쉬 창에 접속한 후 위의 명령어를 따라치면 접속한 log정보를 확인할 수 있습니다. 여기서 알아야 할 점은 nginx의 log를 fluentd에 보낸 다음 다시 mongdb로 보냈다는 사실이다. 

'devops > docker' 카테고리의 다른 글

docker 이미지  (0) 2020.01.31
docker 컨테이너 자원 할당 제한  (0) 2020.01.29
docker 네트워크  (1) 2020.01.22
container를 외부에 노출하기  (0) 2020.01.22
docker 컨테이너 사용해보기  (0) 2020.01.21