Работа с логами (Logs) в Docker
Логи в докере нужны в первую очередь для траблшутинга тех или иных проблем которые возникают у вас в ходе работы с контейнером.
Надеюсь что у вас уже имеется докер на хостевой машине, если нет, вот полезные статьи:
Установка Docker на Debian/Ubuntu
Установка Docker на CentOS/RedHat/Fedora
Установка docker-compose в Unix/Linux
Запуск docker контейнеров в Unix/Linux
Установка docker machine в Unix/Linux
Настройка docker swarm кластера в Unix/Linux
Запуск GUI-приложения в Docker
Запустить bash/SSH в контейнере с Docker
Создание base image для docker в Unix/Linux
Создание docker контейнера в Unix/Linux
Остановить/Удалить все Docker контейнеры/images
Работа с сетью (Networking) в Docker
Работа с томами (Volumes) в Docker
И так, приступим.
Работа с логами (Logs) в Docker
-=== СПОСОБ 1 ===-
Стандартное использование будет следующим:
$ docker logs $(docker ps -aql) Version: v0.4.9 Git commit: c4de4ad0 OS/Arch: linux/amd64 Built: Wed Aug 29 12:32:14 2018 time="2018-10-31T10:58:45Z" level=info msg="Controller ready"
Или если задали контейнер_нейм:
$ docker logs vault
-=== СПОСОБ 2 ===-
Логи монтируются на хостевую машину, по этому гегко понять где лежат логи:
$ docker inspect vault | grep -E "LogPath" "LogPath": "/var/lib/docker/containers/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b-json.log",
И после чего, выполняем:
$ cat /var/lib/docker/containers/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b/4e65e9b0f1412af155e30d0c50c52933d989c08346d9405e75c5945b53182b3b-json.log
-=== СПОСОБ 3 ===-
Иногда бывает так, что приложенько не умеет выводить логи. Рассмотрим наглядный пример. Запустим контейнер:#
$ docker run -d -P myhttpd:latest 791c65b5aed05a11a40a953779675b5b94d090e691730c5c0bceaa33143fcbc4
Пробуем поулчить логи:
$ docker logs $(docker ps -lq) AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.17. Set the 'ServerName' directive globally to suppress this message
Как видно с вывода, докер не может считать логи с контейнера. Первое что приходит в голову, — это не рабочий контейнер, да? Но пробуем получить данные:
$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2) my httpd container
Этим самым, видно что контейнер работает, но все еще не может отдавать логи.
Делов в том, что логи для Nginx лежат:
$ docker run nginx ls -l /var/log/nginx total 0 lrwxrwxrwx 1 root root 11 Oct 2 19:20 access.log -> /dev/stdout lrwxrwxrwx 1 root root 11 Oct 2 19:20 error.log -> /dev/stderr
Для Apache лежат вот тут:
# docker run httpd cat conf/httpd.conf | egrep '^ *(Error|Custom)Log' ErrorLog /proc/self/fd/2 CustomLog /proc/self/fd/1 common
Пофиксим это дело следующим образом, в докерфайл (нужно дописать\переопределить вывод):
FROM centos LABEL maintainer="Vitaliy Natarov" RUN yum install -y httpd web-assets-httpd && yum clean all RUN echo "logs are sending to stdout" > /var/www/html/index.html RUN ln -s /dev/stdout /var/log/httpd/access_log && \ ln -s /dev/stderr /var/log/httpd/error_log EXPOSE 80 CMD httpd -DFOREGROUND
Билдаем образ:
$ docker build -t myhttpd:2.0 .
Запускаем контейнер:
$ docker run -d -P myhttpd:2.0 1b0c3a82d0687519ffcd2ee06d345a4d3ad8d475dc0d7710fb279bdd836e5e88
Проверим:
$ docker logs $(docker ps -lq) AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.17. Set the 'ServerName' directive globally to suppress this message
Дернем курл:
$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2) logs are sending to stdout
И прверим что пишется в лог:
$ docker logs $(docker ps -lq) AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.18. Set the 'ServerName' directive globally to suppress this message 172.17.0.1 - - [29/Jul/2018:22:07:24 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
Ага! То что нужно было! Вот такой вот юзкейс.
Настройка Log Driver
Запустим контейнер с заданным именем и лог-драйвером, например:
$ docker run -d -P --name=myhttpd --log-driver=journald myhttpd:2.0 5748f3078b647c43a335bdc1f8bc7c8d9db31a491e635effd58b31b1429c8ee7
Проверим что вышло:
$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2) logs are sending to stdout
Получите log-и контейнера через journald ( с указанием CONTAINER_NAME), например:
# journalctl -b CONTAINER_NAME=myhttpd -- Logs begin at Sat 2018-07-28 19:14:07 BST, end at Sun 2018-07-29 23:19:52 BST. -- Jul 29 23:19:29 localhost.localdomain 5748f3078b64[2806]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17. Jul 29 23:19:50 localhost.localdomain 5748f3078b64[2806]: 172.17.0.1 - - [29/Jul/2018:22:19:50 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
Запускаем кнтейнер с log-driver-ом и log-tag-ом:
$ docker run -d -P --log-driver=journald \ --log-opt tag=myhttpd \ myhttpd:latest 0555d7a41ab6af098dfea296e2fa7b4f1c6b73424e2156c387930b13bfcefb24
Чекаем:
$ curl localhost:$(docker port $(docker ps -lq) | cut -d: -f2) logs are sending to stdout
С такой командой, теперь можно получить логи через указанный тег:
$ journalctl -b CONTAINER_TAG=myhttpd
Поддерживаемые Log Driver-ы:
- none — Логи не доступны для контейнера, и логи самого докера не возвращают никакого вывода.
- json-file- Log-и отформатированы как JSON. Данный драйвер используется по умолчанию в Docker.
- syslog — Записывает логи в syslog. Демон syslog должен быть запущен на самом хосте.
- journald — Записывает логи в journald. Демон journald должен быть запущен на самом хосте.
- gelf — Записывает сообщения в Graylog (GELF) или Logstash.
- fluentd — Записывает сообщения на fluentd (forward input). Демон fluentd должен быть запущен на самом хосте.
- awslogs- Записывает сообщения в Amazon CloudWatch.
- splunk — Записывает сообщения в splunk с помощью сборщика HTTP событий (HTTP Event Collector).
- gcplogs — Записывает сообщения в Google Cloud Platform (GCP).
- logentries — Записывает сообщения в Rapid7 Logentries.
Проверим что используется поумолчанию:
$ docker info --format '{{.LoggingDriver}}' json-file
Меняем на нужный:
# cat << EOF > /etc/docker/daemon.json { "log-driver": "journald" } EOF
Перезапустим сервисы:
# systemctl daemon-reload && systemctl restart docker.service
Проверяем, изменилось ли у нас что-то:
$ docker info --format '{{.LoggingDriver}}' journald
Можно запустить контейнер:
$ docker run -d -P --name=myweb --log-opt tag=myweb_tag myhttpd:2.0
Проверим логи одним из способов:
$ journalctl -b CONTAINER_NAME=myweb $ journalctl -b CONTAINER_TAG=myweb_tag
Вот и все, статья «Работа с логами (Logs) в Docker» завершена.