- 출처: 시작하세요! 도커/쿠버네티스 - 컨테이너 로깅
- 출처: 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 |
댓글