全站資源開放下載,感謝廣大網友的支持
鏈接失效請移步職業司平臺
非盈利平臺

非盈利平臺

只為分享一些優質內容

Java幫幫-微信公眾號

Java幫幫-微信公眾號

將分享做到極致

微信小程序

微信小程序

更方便的閱讀

職業司微信公眾號

職業司微信公眾號

實時動態通知

安卓APP

安卓APP

我們從此不分開

程序員生活志-公眾號

程序員生活志-公眾號

程序員生活學習圈,互聯網八卦黑料

支付寶贊助-Java幫幫社區
微信贊助-Java幫幫社區

Docker 日志管理最佳實踐!看這篇就夠了!

7
發表時間:2020-07-14 11:07
Docker-CEServer Version: 18.09.6Storage Driver: overlay2Kernel Version: 3.10.0-862.el7.x86_64Operating System: CentOS Linux 7 (Core)

Docker   日志分為兩類:

  • Docker 引擎日志(也就是 dockerd 運行時的日志),

  • 容器的日志,容器內的服務產生的日志。

一 、Docker 引擎日志

Docker 引擎日志一般是交給了 Upstart(Ubuntu 14.04) 或者 systemd (CentOS 7, Ubuntu 16.04)。前者一般位于 /var/log/upstart/docker.log 下,后者我們一般 通過 journalctl -u docker 來進行查看。


preview

二、容器日志

2.1、常用查看日志命令——docker logs

docker logs CONTAINER 顯示當前運行的容器的日志信息, UNIX 和 Linux 的命令有三種 輸入輸出,分別是 STDIN(標準輸入)、STDOUT(標準輸出)、STDERR(標準錯誤輸出),docker logs   顯示的內容包含 STOUT 和 STDERR。在生產環境,如果我們的應用輸出到我們的日志文件里,所以我們在使用   docker   logs 一般收集不到太多重要的日志信息。

  • nginx 官方鏡像,使用了一種方式,讓日志輸出到 STDOUT,也就是 創建一個符號鏈接/var/log/nginx/access.log/dev/stdout

  • httpd 使用的是 讓其輸出到指定文件 ,正常日志輸出到 /proc/self/fd/1 (STDOUT) ,錯誤日志輸出到 /proc/self/fd/2 (STDERR)。

  • 當日志量比較大的時候,我們使用 docker logs   來查看日志,會對 docker daemon 造成比較大的壓力,容器導致容器創建慢等一系列問題。

  • 只有使用了 `local 、json-file、journald`   的日志驅動的容器才可以使用 docker logs 捕獲日志,使用其他日志驅動無法使用 `docker logs`

2.2 、Docker 日志 驅動

Docker 提供了兩種模式用于將消息從容器到日志驅動。

  • (默認)拒絕,阻塞從容器到容器驅動

  • 非阻塞傳遞,日志將儲存在容器的緩沖區。

當緩沖區滿,舊的日志將被丟棄。

在 mode 日志選項控制使用 blocking(默認) 或者 non-blocking, 當設置為 non-blocking需要設置 max-buffer-size 參數(默認為 1MB)。

支持的驅動

preview

使用 Docker-CE 版本,docker logs命令 僅僅適用于以下驅動程序(前面 docker logs 詳解也提及到了)

  • local

  • json-file

  • journald



1558055133186

Docker 日志驅動常用命令

查看系統當前設置的日志驅動

docker   info |grep   "Logging Driver"   / docker info --format '{{.LoggingDriver}}'

查看單個容器的設置的日志驅動

docker inspect   -f '{{.HostConfig.LogConfig.Type}}'   容器id

Docker 日志驅動全局配置更改

修改日志驅動,在配置文件 /etc/docker/daemon.json(注意該文件內容是 JSON 格式的)進行配置即可。

示例:

{ "log-driver": "syslog"}

以上更改是針對所有的容器的日志驅動的。我們也可以單獨為單一容器設置日志驅動。

Docker 單一容器日志驅動配置

在 運行容器的時候指定 日志驅動 --log-driver

docker   run   -itd --log-driver none alpine ash # 這里指定的日志驅動為 none 

日志驅動 一 、local

local 日志驅動 記錄從容器的 STOUT/STDERR 的輸出,并寫到宿主機的磁盤。

默認情況下,local   日志驅動為每個容器保留 100MB 的日志信息,并啟用自動壓縮來保存。(經過測試,保留100MB 的日志是指沒有經過壓縮的日志)

local 日志驅動的儲存位置 /var/lib/docker/containers/容器id/local-logs/container.log 命名。

local 驅動支持的選項



全局日志驅動設置為—local

在配置文件 /etc/docker/daemon.json(注意該文件內容是 JSON 格式的)進行配置即可。

{ "log-driver": "local",   "log-opts": {   "max-size": "10m" }}

重啟 docker   即可生效。

單個容器日志驅動設置為—local

運行容器并設定為 local 驅動。

#   運行一個容器 ,并設定日志驅動為 local ,并運行命令 ping www.baidu.com[root@localhost docker]# docker run   -itd   --log-driver   local   alpine   ping www.baidu.com 3795b6483534961c1d5223359ad1106433ce2bf25e18b981a47a2d79ad7a3156#   查看運行的容器的 日志驅動是否是 local[root@localhost docker]# docker inspect   -f '{{.HostConfig.LogConfig.Type}}'   3795b6483534961clocal# 查看日志[root@localhost local-logs]# tail -f   /var/lib/docker/containers/3795b6483534961c1d5223359ad1106433ce2bf25e18b981a47a2d79ad7a3156/local-logs/container.log NNdout????:64 bytes from 14.215.177.38: seq=816 ttl=55 time=5.320 msNNdout?μ???:64 bytes from 14.215.177.38: seq=817 ttl=55 time=4.950 ms

注意事項:經過測試,當我們產生了100 MB 大小的日志時 會有 四個壓縮文件和一個container.log

[root@localhost local-logs]# ls -ltotal 32544-rw-r-----. 1 root root 18339944 May 16 09:41 container.log-rw-r-----. 1 root root   3698660 May 16 09:41 container.log.1.gz-rw-r-----. 1 root root   3726315 May 16 09:41 container.log.2.gz-rw-r-----. 1 root root   3805668 May 16 09:41 container.log.3.gz-rw-r-----. 1 root root   3744104 May 16 09:41 container.log.4.gz

那么當超過了 100MB 的日志文件,日志文件會繼續寫入到 container.log,但是會將 container.log 日志中老的日志刪除,追加新的,也就是 當寫滿 100MB 日志后 ,再產生一條新日志,會刪除 container.log 中的一條老日志,保存 100MB 的大小。這個 對我們是會有一些影響的,

當我運行系統時 第一天由于bug產生了 100MB 日志,那么之前的日志就已經有 80MB 日志變成的壓縮包,所以我在后續的運行中,只能獲取最近的 20MB日志。

日志驅動 二、 默認的日志驅動—JSON

所有容器默認的日志驅動 json-file

json-file 日志驅動 記錄從容器的 STOUT/STDERR 的輸出 ,用 JSON 的格式寫到文件中,日志中不僅包含著 輸出日志,還有時間戳和 輸出格式。下面是一個 ping www.baidu.com 對應的 JSON 日志

{"log":"64 bytes from 14.215.177.39: seq=34 ttl=55 time=7.067 ms\r\n","stream":"stdout","time":"2019-05-16T14:14:15.030612567Z"}

json-file   日志的路徑位于 /var/lib/docker/containers/container_id/container_id-json.log

json-file 的 日志驅動支持以下選項:

preview

json-file 的日志驅動示例

# 設置 日志驅動為 json-file ,我們也可以不設置,因為默認就是 json-filedocker run   -itd   --name   test-log-json   --log-driver json-file   alpine   ping www.baidu.com199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e# 查看日志,日志名稱就是 容器名稱-json.logtail -f /var/lib/docker/containers/199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e/199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e-json.log{"log":"64 bytes from 14.215.177.39: seq=13 ttl=55 time=15.023 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:54.003118877Z"}{"log":"64 bytes from 14.215.177.39: seq=14 ttl=55 time=9.640 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:54.999011017Z"}{"log":"64 bytes from 14.215.177.39: seq=15 ttl=55 time=8.938 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:55.998612636Z"}{"log":"64 bytes from 14.215.177.39: seq=16 ttl=55 time=18.086 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:57.011235913Z"}{"log":"64 bytes from 14.215.177.39: seq=17 ttl=55 time=12.615 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:58.007104112Z"}{"log":"64 bytes from 14.215.177.39: seq=18 ttl=55 time=11.001 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:59.007559413Z"}

日志驅動 三、syslog

syslog 日志驅動將日志路由到 syslog 服務器,syslog 以原始的字符串作為 日志消息元數據,接收方可以提取以下的消息:

  • level   日志等級 ,如debugwarningerrorinfo

  • timestamp   時間戳

  • hostname   事件發生的主機

  • facillty   系統模塊

  • 進程名稱和進程 ID

syslog 日志驅動全局配置

編輯 /etc/docker/daemon.json 文件

{    "log-driver": "syslog",   "log-opts":   {       "syslog-address": "udp://1.2.3.4:1111"   }}

重啟 docker   即可生效。

preview

preview

單個容器日志驅動設置為—syslog

Linux 系統中 我們用的系統日志模塊時 rsyslog ,它是基于syslog 的標準實現。我們要使用 syslog 驅動需要使用 系統自帶的 rsyslog 服務。

# 查看當前 rsyslog 版本和基本信息[root@localhost harbor]# rsyslogd   -vrsyslogd 8.24.0, compiled with:   PLATFORM:               x86_64-redhat-linux-gnu   PLATFORM (lsb_release -d):         FEATURE_REGEXP:             Yes    GSSAPI Kerberos 5 support:      Yes    FEATURE_DEBUG (debug build, slow code): No    32bit Atomic operations supported:   Yes   64bit Atomic operations supported:   Yes    memory allocator:           system default    Runtime Instrumentation (slow code):    No   uuid support:               Yes    Number of Bits in RainerScript integers: 64See http://www.rsyslog.com for more information.

配置 syslog , 在配置文件 /etc/rsyslog.conf 大約14-20行,我們可以看到兩個配置,一個udp,一個tcp ,都是監聽 514 端口,提供 syslog 的接收。選擇 tcp 就將 tcp 的兩個配置的前面 # 號注釋即可。

# Provides UDP syslog reception#$ModLoad imudp#$UDPServerRun 514# Provides TCP syslog reception#$ModLoad imtcp   #$InputTCPServerRun 514

然后重啟 rsyslog,我們可以看到514端口在監聽。

systemctl restart   rsyslog[root@localhost harbor]# netstat -ntul |grep 514tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN     tcp6       0      0 :::514                  :::*                    LISTEN   

啟動一個以 syslog 為驅動的容器。

docker   run -d -it   -p 87:80 --log-driver syslog --log-opt syslog-address=tcp://127.0.0.1:514   --name nginx-syslog   nginx

訪問并查看日志

# 訪問nginxcurl 127.0.0.1:87# 查看訪問日志tail -f   /var/log/messagesMay 17 15:56:48 localhost fe18924aefde[6141]: 172.17.0.1 - - [17/May/2019:07:56:48 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"#015May 17 15:58:16 localhost fe18924aefde[6141]: 172.17.0.1 - - [17/May/2019:07:58:16 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"#015

日志驅動 四、Journald

journald 日志驅動程序將容器的日志發送到 systemd journal, 可以使用 journal API 或者使用 docker logs 來查日志。

除了日志本身以外, journald 日志驅動還會在日志加上下面的數據與消息一起儲存。

Field



選項



journald 日志驅動全局配置

編輯 /etc/docker/daemon.json 文件

{   "log-driver": "journald"}

單個容器日志驅動設置為—journald

docker   run   -d -it --log-driver=journald \    --log-opt labels=location \    --log-opt env=TEST \    --env "TEST=false" \    --label location=china \    --name   nginx-journald\    -p 80:80\    nginx

查看日志 journalctl

# 只查詢指定容器的相關消息 journalctl CONTAINER_NAME=webserver# -b 指定從上次啟動以來的所有消息 journalctl -b CONTAINER_NAME=webserver# -o 指定日志消息格式,-o json 表示以json 格式返回日志消息 journalctl -o json CONTAINER_NAME=webserver# -f 一直捕獲日志輸出 journalctl -f CONTAINER_NAME=webserver

如果我們的容器在啟動的時候加了 -t 參數,啟用了 TTY 的話,那么我查看日志是會像下面一樣

May 17 17:19:26 localhost.localdomain 2a338e4631fe[6141]: [104B blob data]May 17 17:19:32 localhost.localdomain 2a338e4631fe[6141]: [104B blob data]

顯示[104B blob data] 而不是完整日志原因是因為有 \r 的存在,如果我們要完整顯示,需要加上參數 --all

三、 生產環境中該如何儲存容器中的日志

我們在上面看到了 Docker 官方提供了 很多日志驅動,但是上面的這些驅動都是針對的 標準輸出的日志驅動。

容器日志分類

容器的日志實際是有兩大類的:

  • 標準輸出的 ,也就是 STDOUT 、STDERR ,這類日志我們可以通過 Docker 官方的日志驅動進行收集。

    示例:Nginx 日志,Nginx 日志有 access.logerror.log ,我們在 Docker Hub 上可以看到   Nginx 的 dockerfile   對于這兩個日志的處理是:

    RUN ln -sf /dev/stdout /var/log/nginx/access.log \   && ln -sf /dev/stderr /var/log/nginx/error.log

    都軟連接到 /dev/stdout/dev/stderr ,也就是標準輸出,所以這類 容器是可以使用 Docker 官方的日志驅動。

  • 文本日志,存在在于容器內部,并沒有重定向到 容器的標準輸出的日志。

    示例:Tomcat 日志,Tomcat 有 catalina、localhost、manager、admin、host-manager,我們可以在 Docker Hub 看到 Tomcat 的 dockerfile 只有對于 catalina 進行處理,其它日志將儲存在容器里。

    CMD ["catalina.sh", "run"]

    我們運行了一個 Tomcat 容器 ,然后進行訪問后,并登陸到容器內部,我們可以看到產生了文本日志:

    root@25ba00fdab97:/usr/local/tomcat/logs# ls -ltotal 16-rw-r-----. 1 root root 6822 May 17 14:36 catalina.2019-05-17.log-rw-r-----. 1 root root    0 May 17 14:36 host-manager.2019-05-17.log-rw-r-----. 1 root root   459 May 17 14:36 localhost.2019-05-17.log-rw-r-----. 1 root root 1017 May 17 14:37 localhost_access_log.2019-05-17.txt-rw-r-----. 1 root root    0 May 17 14:36 manager.2019-05-17.log

    這類容器我們下面有專門的方案來應對。

一、當是完全是標準輸出的類型的容器

我們可以選擇   json-file 、syslog、local 等 Docker 支持的日志驅動。

二、當有文件文本日志的類型容器

方案一 掛載目錄   bind

創建一個目錄,將目錄掛載到 容器中產生日志的目錄。

--mount   type=bind,src=/opt/logs/,dst=/usr/local/tomcat/logs/ 

示例:

# 創建掛載目錄/opt/logs[root@fy-local-2 /]# mkdir   /opt/logs# 創建容器tomcat-bind 并將 /opt/logs 掛載至 /usr/local/tomcat/logs/[root@fy-local-2 /]# docker   run -d   --name   tomcat-bind   -P   --mount   type=bind,src=/opt/logs/,dst=/usr/local/tomcat/logs/   tomcat[root@fy-local-2 /]# ls -l /opt/logs/total 12-rw-r----- 1 root root 6820 May 22 17:31 catalina.2019-05-22.log-rw-r----- 1 root root    0 May 22 17:31 host-manager.2019-05-22.log-rw-r----- 1 root root   459 May 22 17:31 localhost.2019-05-22.log-rw-r----- 1 root root    0 May 22 17:31 localhost_access_log.2019-05-22.txt-rw-r----- 1 root root    0 May 22 17:31 manager.2019-05-22.log

方案二 使用數據卷 volume

創建數據卷,創建容器時綁定數據卷,

--mount   type=volume   src=volume_name   dst=/usr/local/tomcat/logs/ 

示例:

# 創建tomcat應用數據卷名稱為 tomcat[root@fy-local-2 /]# docker volume   create   tomcat# 創建容器tomcat-volume 并指定數據卷為 tomcat,綁定至 /usr/local/tomcat/logs/[root@fy-local-2 /]# docker   run -d   --name   tomcat-volume   -P   --mount   type=volume,src=tomcat,dst=/usr/local/tomcat/logs/   tomcat# 查看數據卷里面的內容[root@fy-local-2 /]# ls -l /var/lib/docker/volumes/tomcat/_data/total 12-rw-r----- 1 root root 6820 May 22 17:33 catalina.2019-05-22.log-rw-r----- 1 root root    0 May 22 17:33 host-manager.2019-05-22.log-rw-r----- 1 root root   459 May 22 17:33 localhost.2019-05-22.log-rw-r----- 1 root root    0 May 22 17:33 localhost_access_log.2019-05-22.txt-rw-r----- 1 root root    0 May 22 17:33 manager.2019-05-22.log

方案三 計算容器 rootfs 掛載點

此方案的文字內容摘抄于

使用掛載宿主機目錄的方式采集日志對應用會有一定的侵入性,因為它要求容器啟動的時候包含掛載命令。如果采集過程能對用戶透明那就太棒了。事實上,可以通過計算容器 rootfs 掛載點來達到這種目的。

和容器 rootfs 掛載點密不可分的一個概念是 storage driver。實際使用過程中,用戶往往會根據 linux 版本、文件系統類型、容器讀寫情況等因素選擇合適的 storage driver。不同 storage driver 下,容器的 rootfs 掛載點遵循一定規律,因此我們可以根據 storage driver 的類型推斷出容器的 rootfs 掛載點,進而采集容器內部日志。下表展示了部分 storage dirver 的 rootfs 掛載點及其計算方法。



示例:

# 創建容器 tomcat-test[root@fy-local-2 /]# docker   run -d   --name   tomcat-test   -P   tomcat36510dd653ae7dcac1d017174b1c38b3f9a226f9c4e329d0ff656cfe041939ff   # 查看tomcat-test 容器的 掛載點位置[root@fy-local-2 /]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' 36510dd653ae7dcac1d017174b1c38b3f9a226f9c4e329d0ff656cfe041939ff   /var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/merged# 查看掛載點的目錄結構[root@fy-local-2 /]# ls -l /var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/mergedtotal 4drwxr-xr-x 1 root root   179 May   8 13:05 bindrwxr-xr-x 2 root root    6 Mar 28 17:12 bootdrwxr-xr-x 1 root root   43 May 22 17:27 devlrwxrwxrwx 1 root root   33 May   8 13:08 docker-java-home -> /usr/lib/jvm/java-8-openjdk-amd64drwxr-xr-x 1 root root   66 May 22 17:27 etcdrwxr-xr-x 2 root root    6 Mar 28 17:12 homedrwxr-xr-x 1 root root    6 May 16 08:50 libdrwxr-xr-x 2 root root   34 May   6 08:00 lib64drwxr-xr-x 2 root root    6 May   6 08:00 mediadrwxr-xr-x 2 root root    6 May   6 08:00 mntdrwxr-xr-x 2 root root    6 May   6 08:00 optdrwxr-xr-x 2 root root    6 Mar 28 17:12 procdrwx------ 1 root root   27 May 22 17:29 rootdrwxr-xr-x 3 root root   30 May   6 08:00 rundrwxr-xr-x 2 root root 4096 May   6 08:00 sbindrwxr-xr-x 2 root root    6 May   6 08:00 srvdrwxr-xr-x 2 root root    6 Mar 28 17:12 sysdrwxrwxrwt 1 root root   29 May 16 08:50 tmpdrwxr-xr-x 1 root root   19 May   6 08:00 usrdrwxr-xr-x 1 root root   41 May   6 08:00 var# 查看日志[root@fy-local-2 /]# ls -l /var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/merged/usr/local/tomcat/logs/total 20-rw-r----- 1 root root 14514 May 22 17:40 catalina.2019-05-22.log-rw-r----- 1 root root     0 May 22 17:27 host-manager.2019-05-22.log-rw-r----- 1 root root   1194 May 22 17:40 localhost.2019-05-22.log-rw-r----- 1 root root     0 May 22 17:27 localhost_access_log.2019-05-22.txt-rw-r----- 1 root root     0 May 22 17:27 manager.2019-05-22.log

方案四   在代碼層中實現直接將日志寫入redis

docker   ——》redis ——》Logstash——》Elasticsearch,通過代碼層面,直接將日志寫入redis,最后寫入 Elasticsearch

以上就是對 Docker 日志的所有的概念解釋和方提供,具體采用什么方案,根據公司的具體的業務來選擇。合適的才是最好的。


Java幫幫學習群生態

Java幫幫學習群生態

總有一款能幫到你

Java學習群

Java學習群

與大牛一起交流

大數據學習群

大數據學習群

在數據中成長

九點編程學習群

九點編程學習群

深夜九點學編程

python學習群

python學習群

人工智能,爬蟲

測試學習群

測試學習群

感受測試的魅力

Java幫幫生態承諾

Java幫幫生態承諾

一直堅守,不負重望

初心
勤儉
誠信
正義
分享
友鏈交換:加幫主QQ2524138991 留言即可 24小時內答復  
業司
教育資訊
會員登錄
獲取驗證碼
登錄
登錄
我的資料
留言
回到頂部