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 是三個軟件的合稱:Elasticsearch、Logstash、Kibana。
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
第一步:安裝
調整內存4個G以上
[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 還沒有任何日志數據。
接下來的工作就是將 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/*.log 是 Host 操作系統的 log。
接下來告訴 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 能搜索出所有匹配的日志條目。