본문 바로가기
Framework and Tool/Docker

Docker logging

by ocwokocw 2023. 6. 17.

- 출처: 시작하세요! 도커/쿠버네티스 - 컨테이너 로깅

- 출처: https://docs.docker.com/config/containers/logging/

 

- Container log

docker logs 명령어를 이용하면 실행중인 container에서 수집된 log를 볼 수 있다. 기본적으로 표준 출력(STDIN), 표준 에러(STDERR)를 저장한다. 

다만 docker logs를 제대로 사용할 수 없는 경우도 있는데

  • "dual logging"을 비활성화한 상태에서 logging driver를 사용하여 log를 file, 외부 host, 다른 back-end로 보내는 경우
  • 사용하는 이미지가 web server나 DB와 같은 non-interactive 프로세스를 실행하는 경우 해당 app들이 STDOUT, STDERR 대신 결과를 log file로 보내는 경우

이를 위해, nginx 이미지는 /var/log/nginx/access.log -> /dev/stdout, /var/log/nginx/error.log -> /dev/stderr 에 대한 symbolic link를 생성한다.

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
	&& ln -sf /dev/stderr /var/log/nginx/error.log

http driver는 일반적인 log는 /proc/self/fd/1에, error log는 /proc/self/fd/2에 쓰도록 httpd application 설정을 변경하고 있다.

&& sed -ri \
		-e 's!^(\s*CustomLog)\s+\S+!\1 /proc/self/fd/1!g' \
		-e 's!^(\s*ErrorLog)\s+\S+!\1 /proc/self/fd/2!g' \
		"$HTTPD_PREFIX/conf/httpd.conf" \

 

- Logging driver

Docker는 실행중인 container로 부터 정보를 얻을 수 있도록 돕는 logging mechanism 들을 제공하는데, 이런 mechanism 들을 logging driver 라고 한다. Docker는 default 로 json-file logging driver를 사용한다. 

% docker info --format '{{.LoggingDriver}}'
json-file

만약 logging driver에 대한 설정을 변경하고 싶다면 Mac 기준으로 아래 경로의 daemon.json을 변경한다. 내 컴퓨터에서는 아래와 같이 설정하진 않았지만 예시를 위해 표시하였다.

% cat /Users/user/.docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "labels": "production_status",
    "env": "os,customer"
  }
}

물론 docker daemon 기본설정이 아닌 container 실행시에도 별도 설정이 가능하다.

% docker run -it --log-driver none alpine ash
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # exit

% docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS                    PORTS     NAMES
75dc6961cda1   alpine    "ash"     7 seconds ago   Exited (0) 1 second ago             peaceful_taussig

% docker logs 75dc6961cda1
Error response from daemon: configured logging driver does not support reading

% docker run -it alpine ash
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # echo test
test
/ # exit

% docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                      PORTS     NAMES
93e453d36fdb   alpine    "ash"     9 seconds ago    Exited (0) 2 seconds ago              sharp_poincare
75dc6961cda1   alpine    "ash"     33 seconds ago   Exited (0) 27 seconds ago             peaceful_taussig

% docker logs 93e453d36fdb
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # echo test
test

총 2개의 alpine linux container를 실행시켰는데 하나는 --log-driver none option으로 하나는 default로 실행시켰다. docker logs로 조회해보면 none logging driver는 읽지 못하는것을 확인할 수 있다.

 

- fluentd logging example

fluentd 는 각종 로그를 수집하고 저장할 수 있는 기능을 제공하는 오픈소스이다. application에서 발생하는 log를 받아서 아주 많은 Output plugin(https://www.fluentd.org/plugins/all)을 통해 전달할 수 있다. 학습을 위해 로그를 수집한 뒤 mongodb로 전달하는 예제를 작성해보도록 하자.

우선 bridge network를 생성해주자. nginx web server, fluentd server, mongodb server를 각각 다른 host에 구성할 수 있지만 우리는 가난하므로.. 하나의 host에 각각 container를 띄우고 bridge network 를 사용해서 각각 container name으로 통신할 수 있도록 할 예정이다. (주의: 책에서는 bridge network를 사용하지 않는다.)

% docker network create --driver bridge logging_bridge

 

1) 우선 log를 전달받을 mongodb container를 띄워주도록 하자.

% docker run --network logging_bridge --name mongodb -d -p 27017:27017 mongo
a532268f5dbeba3e8e82525c5b338881155ca847b197a3f7beb1c1c7e303bbc7

fluentd가 mongodb 라는 이름으로 mongodb container 를 찾을 수 있게 해주기 위해 logging_bridge network를 사용하는 option을 추가해준다.

 

2) fluentd 설정을 한다.

% cat fluent.conf
<source>
  @type forward
</source>

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

% docker run -d --name fluentd -p 24224:24224 \
--network logging_bridge \
-v /Users/user/Documents/Study/docker/docker-logging/fluent.conf:/fluentd/etc/fluent.conf \
-e FLUENTD_CONF=fluent.conf \
alicek106/fluentd:mongo

<match docker.**> 하위 level host 부분에 mongodb container 명을 주고 docker run시 logging_bridge network를 사용하도록 명시해준다. docker.** 부분은 docker로 시작하는 tag에 대한 log는 mongodb로 보내겠다는 의미가 된다.

 

3) nginx container를 띄운 후 browser로 접근하여 access log를 남긴다.

% docker run -p 8080:80 -d \
--log-driver=fluentd \
--log-opt fluentd-address=127.0.0.1:24224 \
--log-opt tag=docker.nginx.webserver \
nginx
cb1de5622023e923b955352bac118416ca2ac72545847447daa58056b2112e14

mongodb container에서 제대로 log가 들어왔는지 확인해주자. 제대로 설정을 했다면 nginx db > access collection에 log가 조회될것이다.

% docker exec -it mongodb mongo
...

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
nginx   0.000GB

> use nginx
switched to db nginx

> show collections
access

> db.access.find({})
{ "_id" : ObjectId("648dc4beb5e2c1000d437304"), "container_id" : "b681e1678cc04194bf018cca9df191d38425234e40e11c549dbee56543ee8679", "container_name" : "/stupefied_lederberg", "source" : "stdout", "log" : "/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration", "time" : ISODate("2023-06-17T14:35:31Z") }
{ "_id" : ObjectId("648dc4beb5e2c1000d437305"), "source" : "stdout", "log" : "/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/", "container_id" : "b681e1678cc04194bf018cca9df191d38425234e40e11c549dbee56543ee8679", "container_name" : "/stupefied_lederberg", "time" : ISODate("2023-06-17T14:35:31Z") }
...

'Framework and Tool > Docker' 카테고리의 다른 글

Docker image and layer  (0) 2023.06.18
Docker resource constraints  (0) 2023.06.18
Docker network  (0) 2023.06.12
Docker volume  (0) 2023.06.11
Container application example  (0) 2023.06.10

댓글