本文的測試環境爲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