本文的測試環境為CentOS 7.3,Kubernetes集群為1.11.2,安裝步驟參見kubeadm安裝kubernetes V1.11.1 集群
日志對於我們管理Kubernetes集群及其上的應用具有非常重要的作用,特別是在出現故障或者Bug的時候。如果你能回答下面幾個問題,那么可以不用再看本文了,如果不能回答,本文可能正好適合你。
- Docker都會產生哪些日志?
- Docker產生的日志都放在哪里?
- Docker的日志的分割、清理策略默認為什么?
- 如何配置Docker日志的分割、清理策略?
- Kubernetes都會產生哪些日志?
- Kubernetes產生的日志都存放在那里?
- 如何集中管理Kubernetes產生的日志?
1. Docker的日志處理方案
Docker產生的日志有兩類:
- 一類是Docker引擎日志。Docker引擎日志在不同的操作系統下管理方式不一樣,在Centos中是通過journalctl來進行管理。
- 一類是容器日志。容器中的應用產生的日志默認都輸出到
stdout
和stderr
中,可以通過docker logs
來訪問。Docker為容器日志提供了多種實現機制稱為logging driver。通過docker info
可以查看本機使用的logging driver,默認為json-file
形式,這種形式下每個容器的日志默認以json格式存儲在/var/lib/docker/containers/<容器id>/<容器id>-json.log
下。下面兩種情況使用docker logs
看不到什么有用的信息:- 容器內的應用不是交互式應用,而是實現了自己的日志輸出,例如對於Apache、Nginx等Web服務,通常會將訪問日志和錯誤日志記錄到不同的文件,而不是打到標准輸出和錯誤輸出。
- 使用不同的logging driver將日志送到了文件、外部服務器、數據庫等集中的日志后台。
Docker目前支持的logging driver類型:
- none
- json-file
- syslog
- journald
- gelf
- fluentd
- awslogs
- splunk
- etwlogs
- gcplogs
- logentries
1.1 配置logging driver
運行容器時,可以通過命令行參數指定logging driver的類型。
bogon:log rousseau$ docker run -it --log-driver none alpine sh
/ # ls
#切換一個終端
bogon:log rousseau$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ec61e8feb61 alpine "sh" 13 seconds ago Up 12 seconds xenodochial_ptolemy
bogon:log rousseau$ docker logs 8ec61e8feb61
Error response from daemon: configured logging driver does not support reading
bogon:log rousseau$ docker inspect -f '{{.HostConfig.LogConfig.Type}}' 8ec61e8feb61
none
對於日志輸出到文件的應用,可以通過軟連接的方式將日志輸出到標准輸出和標准錯誤輸出。例如:The official nginx image creates a symbolic link from /var/log/nginx/access.log to /dev/stdout, and creates another symbolic link from /var/log/nginx/error.log to /dev/stderr, overwriting the log files and causing logs to be sent to the relevant special device instead.
對於多行格式的日志信息,有一點需要特別關注。The Docker json logging driver treats each line as a separate message. When using the Docker logging driver, there is no direct support for multi-line messages. You need to handle multi-line messages at the logging agent level or higher.
1.3 日志分割策略配置
在CentOS中,可以通過修改/etc/docker/daemon.json
來配置Docker的日志分割策略。
{
"log-driver": "json-file",
"log-opts": {
"max-size": "9m", # Max size of the log files.
"max-file": "5" # The maximum number of log files that can be present.
}
}
總結:對於單機的Docker來說,可以將日志以json-file的形式存儲到本地磁盤,同時提供了根據文件大小進行文件分割的配置,也提供了根據文件數量進行文件清理的策略。配置好這兩個參數,基本上就不需要擔心容器應用將磁盤寫滿的風險了。而Docker引擎本身的日志則是通過journald來進行管理的。
2. Kubernetes的日志處理方案
Kubernetes的日志管理方式與Docker有所不同,因為容器封裝在Pod中,當遇到Pod被刪除或者Node節點故障的情況下,日志會被刪除,單純依靠Docker本身的日志機制將無法在故障后查詢日志,因此在管理集群時需要認真考慮日志的管理問題。
Kubernetes集群的日志包括以下幾種:
- 各種event事件,可以通過
kubectl describe pod
查看到詳細信息 - 容器應用產生的日志
- Node節點上Docker Daemon產生的日志
- Node節點上kubelet產生的日志
2.1 日志的位置
Kubernetes集群中包含眾多組件,在用kubeadm方式安裝的集群上,有些組件不是容器化運行的,包括Master節點的kubelet、kube-scheduler、kube-controller-manager、kube-apiserver,Node節點上運行了kubelet和kube-proxy。有些組件是容器化方式運行的,當然包括我們的應用。因此日志就分為兩類:容器化組件及應用的日志,非容器化組件的日志。
2.1.1 容器化組件及應用的日志管理
對於容器化的組件和應用,其日志的管理方式都通過Docker的log-driver來進行指定,因此Kubernetes本身並不提供日志分割的功能。有兩種方式來實現日志的分割:
- 通過Docker配置
log-opt
參數,與上一節的方式相同。 - 通過其他的腳本,例如kube-up.sh來分割日志文件。
如果使用外部工具對日志進行了分割,再通過
docker logs
目錄查看日志時,僅返回最新的文件中的內容。
2.1.2 非容器化的組件日志管理。
系統組件也分為兩種,一種是運行在容器中的應用,包括scheduler
、kube-proxy
等;一種是沒有運行在容器中的應用,包括kubelet
和容器運行環境。這些組件的日志都是通過journald
來進行管理的。
2.2 集群級別的日志管理
Kubernetes本身沒有提供集群級別的日志管理功能,如想實現集群級別的日志管理有三種方案:
- 在每個Node中運行日志采集代理,將日志收集到集中的日志管理平台。這種方案對應用沒有侵入性,是優選方案。
- 在前一種方案的基礎上,在每個應用Pod中增加Sidecar容器來實現日志的分離。
- 應用直接將日志輸出到統一的日志管理平台,不在本地落地,這種方案對於應用的侵入性較大
2.3.1 日志采集代理方案
這種方案在每台Node上運行一個專用的日志采集代理,可以是容器化的應用(需要能夠在容器內訪問節點上的日志文件),可以采用DaemonSet
來確保代理在每個Node中都運行。
2.3.2 Sidecar方案
Sidecar的本意是挎斗摩托車,這種車型在摩托車旁邊加了一個邊斗來提高運載量,是二戰時期日軍廣泛使用的一種運輸工具。
類似於挎斗摩托車,Sidecar方案是在應用Pod中增加一個或多個負責處理日志的容器,根據增加容器的作用,可以分為日志分離和容器內代理。
2.3.2.1 日志分離
盡管CPU和內存資源的消耗非常少,但是讀取日志文件並且重寫到標准輸出會加倍磁盤的負載,這一點需要特別注意。
2.3.2.2 容器內代理
采用這種方案,通過容器內代理直接將應用的日志上傳到統一的日志管理平台,會增加Pod的資源消耗,同時無法通過kubectl logs
命令來查看日志。
2.3.3 流式處理方案
參考資料
- Logging Architecture
- Docker日志都在哪里?怎么收集?
- Systemd之journalctl
- Kubectl logs
- Docker Logging Overview
- fluentd
- Stackdriver
- TLDC
- Kubernetes日志收集
- Kubernetes容器集群中的日志系統集成實踐
- Where are the Kubernetes kublet logs located?
- Kubernetes Log Analysis with Fluentd, Elasticsearch and Kibana
- Kubernetes Log File Locations
- Kubernetes Logs