Docker日誌管理(十一)--技術流ken
Docker logs
對於一個執行的容器,Docker 會將日誌傳送到 容器的 標準輸出裝置(STDOUT)和標準錯誤裝置(STDERR),STDOUT 和 STDERR 實際上就是容器的控制檯終端。
舉個例子,用下面的命令執行 httpd 容器:
[root@host1 ~]# docker run -p 80:80 httpd Unable to find image 'httpd:latest' locally latest: Pulling from library/httpd 5e6ec7f28fb7: Pull complete 566e675a8212: Pull complete ef5a8026039b: Pull complete 22ecb0106557: Pull complete 91cc511c603e: Pull complete Digest: sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3 Status: Downloaded newer image for httpd:latest AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message [Mon Jan 28 08:55:25.168252 2019] [mpm_event:notice] [pid 1:tid 140652308325568] AH00489: Apache/2.4.38 (Unix) configured -- resuming normal operations [Mon Jan 28 08:55:25.182578 2019] [core:notice] [pid 1:tid 140652308325568] AH00094: Command line: 'httpd -D FOREGROUND'
因為我們在啟動日誌的時候沒有用-d 引數,httpd 容器以前臺方式啟動,日誌會直接列印在當前的終端視窗。
如果加上-d 引數以後臺方式執行容器,我們就看不到輸出的日誌了。
[root@host1 ~]# docker run -d -p 80:80 httpd 98d1fe5f1d074c345f578ef7767e8b2543977e61bb241f5629509c54502a7218
這種情況下,檢視容器日誌推薦的方法是用docker logs 命令。
[root@host1 ~]# docker logs -f 98d1fe5f1d07 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message [Mon Jan 28 08:56:09.352502 2019] [mpm_event:notice] [pid 1:tid 139863955322048] AH00489: Apache/2.4.38 (Unix) configured -- resuming normal operations [Mon Jan 28 08:56:09.353740 2019] [core:notice] [pid 1:tid 139863955322048] AH00094: Command line: 'httpd -D FOREGROUND'
docker logs能夠打印出自容器啟動以來完整的日誌,並且-f 引數可以繼續打印出新產生的日誌,效果上與 Linux 命令tail -f 一樣。
logging driver
Docker 提供了多種日誌機制幫助使用者從執行的容器中提取日誌資訊。這些機制被稱作 logging driver。
Docker 的預設 logging driver 是json-file 。
[root@host1 ~]# docker info | grep 'Logging Driver' Logging Driver: json-file
jason-file會將容器的日誌儲存在 json 檔案中,Docker 負責格式化其內容並輸出到 STDOUT 和 STDERR。
我們可以在 Host 的容器目錄中找到這個檔案,器路徑為 /var/lib/docker/containers/<contariner ID>/<contariner ID>-json.log
比如我們可以檢視前面 httpd 容器 json 格式的日誌檔案。
可以看到下面四條日誌記錄
[root@host1 ~]# cat /var/lib/docker/containers/c633eb9e8ddd2f4fe134ebfdc157398d97c281552c8ae357f4f4879f8dc6483b/c633eb9e8ddd2f4fe134ebfdc157398d97c281552c8ae357f4f4879f8dc6483b-json.log {"log":"AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message\n","stream":"stderr","time":"2019-01-28T09:08:22.784008521Z"} {"log":"AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.12. Set the 'ServerName' directive globally to suppress this message\n","stream":"stderr","time":"2019-01-28T09:08:22.792051336Z"} {"log":"[Mon Jan 28 09:08:22.792515 2019] [mpm_event:notice] [pid 1:tid 139740890547392] AH00489: Apache/2.4.38 (Unix) configured -- resuming normal operations\n","stream":"stderr","time":"2019-01-28T09:08:22.798741115Z"} {"log":"[Mon Jan 28 09:08:22.793583 2019] [core:notice] [pid 1:tid 139740890547392] AH00094: Command line: 'httpd -D FOREGROUND'\n","stream":"stderr","time":"2019-01-28T09:08:22.798792809Z"}
ELK介紹
在開源的日誌管理方案中,最出名的莫過於 ELK 了。ELK 是三個軟體的合稱: E lasticsearch、 L ogstash、 K ibana。
Elasticsearch
一個近乎實時查詢的全文搜尋引擎。Elasticsearch 的設計目標就是要能夠處理和搜尋巨量的日誌資料。
Logstash
讀取原始日誌,並對其進行分析和過濾,然後將其轉發給其他元件(比如 Elasticsearch)進行索引或儲存。Logstash 支援豐富的 Input 和 Output 型別,能夠處理各種應用的日誌。
Kibana
一個基於 JavaScript 的 Web 圖形介面程式,專門用於視覺化 Elasticsearch 的資料。Kibana 能夠查詢 Elasticsearch 並通過豐富的圖表展示結果。使用者可以建立 Dashboard 來監控系統的日誌。
接下來討論如何用 ELK 這組黃金搭檔來監控 Docker 容器的日誌。
ELK日誌處理流程
下圖展示了 Docker 部署環境下典型的 ELK 日誌處理流程:
Logstash 負責從各個 Docker 容器中提取日誌,Logstash將日誌轉發到 Elasticsearch 進行索引和儲存,Kibana 分析和視覺化資料。
部署ELK
第一步:安裝
[root@host1 ~]# docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk
我們使用的是 sebp/elk 這個現成的 image ,裡面已經包含了整個 ELK stack 。容器啟動後 ELK 各元件將分別監聽如下埠:
5601 - Kibana web 介面
9200 - Elasticsearch JSON 介面
5044 - Logstash 日誌接收介面
如果出現下面的錯誤
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
執行下面的命令
sysctl -w vm.max_map_count=262144
第二步:瀏覽器訪問
先訪問一下 Kibana http://[Host IP]:5601/ 看看效果
當前 Kibana 沒有可顯示的資料,因為當前 Elasticsearch 還沒有任何日誌資料。
訪問一下 Elasticsearch 的 JSON 介面 http://[Host IP]:9200
確實,目前 Elasticsearch 沒有與日誌相關的 index
。
接下來的工作就是將 Docker 的日誌匯入 ELK
filebeat
前面我們已經知道 Docker 會將容器日誌記錄到 /var/lib/docker/containers/<contariner ID>/<contariner ID>-json.log ,那麼只要我們能夠將此檔案傳送給 ELK 就可以實現日誌管理。
要實現這一步其實不難,因為 ELK 提供了一個配套小工具 Filebeat,它能將指定路徑下的日誌檔案轉發給 ELK。同時 Filebeat 很聰明,它會監控日誌檔案,當日志更新時,Filebeat 會將新的內容傳送給 ELK。
第一步:安裝filebeat
[root@ken ~]# curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.5.4-x86_64.rpm [root@ken ~]# rpm -vi filebeat-6.5.4-x86_64.rpm
Filebeat 可能已經有了更新的版本,請參考最新的安裝文件 https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-installation.html
第二步:配置filebeat
Filebeat 的配置檔案為 /etc/filebeat/filebeat.yml,我們需要告訴 Filebeat 兩件事:
-
監控哪些日誌檔案?
-
將日誌傳送到哪裡?
首先回答第一個問題。
在 paths 中我們配置了兩條路徑:
/var/lib/docker/containers/*/*.log 是所有容器的日誌檔案。
/var/log/syslog 是 Host 作業系統的 syslog。
接下來告訴 Filebeat 將這些日誌傳送給 ELK。
Filebeat 可以將日誌傳送給 Elasticsearch 進行索引和儲存;也可以先發送給 Logstash 進行分析和過濾,然後由 Logstash 轉發給 Elasticsearch。
為了不引入過多的複雜性,我們這裡將日誌直接傳送給 Elasticsearch。
下面的內容不需要任何的修改
第三步:啟動filebeat
[root@ken ~]# systemctl start filebeat
第四步:首先需要配置一個index pattern 即告訴 Kibana 查詢和分析 Elasticsearch 中的哪些日誌。
指定 index pattern 為 filebeat-* ,這與 Elasticsearch 中的 index 一致。
Time-field name 選擇 @timestamp。
點選 Create 建立 index pattern。
第五步:檢視日誌
點選 Kibana 左側Discover 選單,便可看到容器和 syslog 日誌資訊。
第六步:測試
下面我們啟動一個新的容器,該容器將向控制檯列印資訊,模擬日誌輸出。
[root@ken ~]# docker run busybox sh -c 'while true; do echo "This is a log message from container busybox!"; sleep 10; done;' This is a log message from container busybox! This is a log message from container busybox!
重新整理 Kibana 頁面 馬上就能看到 busybox 的日誌。
Kibana 也提供了強大的查詢功能,比如輸入關鍵字busybox 能搜尋出所有匹配的日誌條目。