최근에 쿠버네티스를 공부할 일이 있어서 보고 있는데, 쿠버네티스 자체가 도커(Docker) 오케스트레이션을 해주는 툴이라 도커에 대한 개념이 없으니, 공부하기가 힘들었습니다. 그래서 이렇게 급하게 책을 사서 공부하면서 내용을 정리하고자 합니다.

해당 내용은 위키북스에서 나온 시작하세요! 도커 책을 보면서 정리한 내용입니다. 책의 내용이 매우 좋아서 강추합니다.

이번에는 도커의 로깅 시스템에 대해서 다뤄보도록 하겠습니다.


json-file 로그 사용하기

도커는 기본적으로 표준출력에러를 저장하여 이를 확인할 수 있는 명령어를 제공합니다.

먼저 MySQL 컨테이너를 만들어보도록 하겠습니다.

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

이 컨테이너의 상태를 알기 위해서는 docker logs [컨테이너 이름] 명령어를 이용하여 내용을 확인할 수 있습니다.

$ docker logs mysql
  Initializing database
  2019-01-14T10:18:41.333808Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
  2019-01-14T10:18:41.922038Z 0 [Warning] InnoDB: New log files created, LSN=45790
  2019-01-14T10:18:41.981700Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
  2019-01-14T10:18:42.055245Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: c457d8b0-17e5-11e9-bdc2-0242ac110005.
  2019-01-14T10:18:42.061221Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
  2019-01-14T10:18:42.062115Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
  2019-01-14T10:18:43.248892Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249020Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249081Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249148Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249297Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249501Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249812Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
  2019-01-14T10:18:43.249909Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
  Database initialized
  Initializing certificates
  ...

docker logs 명령어에서 지원하는 옵션들

  • -tail : 마지막 줄만 가져오기
  • --since [epoch time] : 유닉스 시간이후의 로그를 확인
  • -t : 타임스탬프 표시
  • -f : 실시간으로 로그르 출력

도커 로그의 저장위치

컨테이너 로그는 JSON 형태로 호스트의 아래 경로에 저장됩니다

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

syslog 설정

컨테이너의 로그는 기본 제공하는 JSON뿐만 아니라 별도의 로그 시스템을 사용할 수도 있습니다. 여기서는 syslog를 사용해보도록 하겠습니다.

$ docker run -d --name syslog_container \
> --log-driver=syslog \
> ubuntu:14.04 \
> echo syslogtest
512bfa54a2b963194a19b4651033468c72e45d430b9a91b40b10852ae5c61a40
docker: Error response from daemon: failed to initialize logging driver: Unix syslog delivery error.

이렇게 하면 로컬호스트의 syslog에 저장이 되는데, MacOS 환경에서는 안되었습니다.

리눅스 위에서 돌리신다면 /var/log/syslog or /var/log/messages에서 확인 가능하십니다.


rsyslog 설정

로컬호스트의 syslog 뿐만 아니라 remote의 syslog도 사용할 수 있습니다.

rsyslog 서버 설정

먼저 rsyslog를 위한 서버를 만들도록 하겠습니다.

$ docker run -i -t --name rsyslog_server \      # --name : 컨테이너 이름
> -h rsyslog \                                  # -h : 컨테이너의 호스트네임
> -p 514:514 -p 514:514/udp \                   # -p : 포트 포워딩, tcp/udp전부 514포트 열어놓기
> ubuntu:14.04

/etc/rsyslog.conf에 들어가서 아래 내용에 해당하는 주석을 제거합니다.

root@rsyslog:/# vi /etc/rsyslog.conf

#################
#### MODULES ####
#################

$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog   # provides kernel logging support
#$ModLoad immark  # provides --MARK-- message capability

# provides UDP syslog reception
$ModLoad imudp                         # 여기 주석(='#')이 있었는데 제거
$UDPServerRun 514                      # 여기 주석(='#')이 있었는데 제거

# provides TCP syslog reception
$ModLoad imtcp                         # 여기 주석(='#')이 있었는데 제거
$InputTCPServerRun 514                 # 여기 주석(='#')이 있었는데 제거

서비스 재시작

root@rsyslog:/# service rsyslog restart
 * Stopping enhanced syslogd rsyslogd                     [ OK ]
 * Starting enhanced syslogd rsyslogd                     [ OK ]

IP 확인

root@rsyslog:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9464 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3110 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:13829793 (13.8 MB)  TX bytes:171843 (171.8 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

rsyslog 클라이언트 설정

먼저 컨테이너를 만들도록 하겠습니다.

$ docker run -i -t --name rsyslog_client \
> --log-driver=syslog \                                 # --log-driver : 로깅드라이버 설정, syslog 사용하겠다는 의미
> --log-opt syslog-address=tcp://172.17.0.2:514 \       # --log-opt : 로깅 드라이버에 추가할 옵션, syslog-address=[주소]
> --log-opt tag="mylog" \                               # --log-opt : 로깅 드라이버에 추가할 옵션, tag=[태그]   
> ubuntu:14.04

테스트를 위해서 echo명령어로 test를 입력해보겠습니다.

root@84a718ebb726:/# echo test
test

그 다음 rsyslog_server로 다시 들어가서

$ docker attach rsyslog_server
root@rsyslog:/#

/var/log/syslog를 확인해보면 해당 로그가 들어있는걸 확인할 수 있습니다.

root@rsyslog:/# tail /var/log/syslog
Jan 15 03:04:27 172.17.0.1 mylog[1277]: #033]0;root@84a718ebb726: /#007root@84a718ebb726:/# #015#033[K#033]0;root@84a718ebb726: /#007root@84a718ebb726:/# echo test#015
Jan 15 03:04:27 172.17.0.1 mylog[1277]: test#015

이렇게 외부 서버에 로그가 쌓이게끔 설정을 할 수도 있습니다.

추가로 --log-opt옵션으로 syslog-facility를 설정하면 로그가 저장될 파일을 변경할 수도 있습니다.