談一下Docker與Kubernetes集羣的日誌和日誌管理

本文的測試環境爲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來進行管理。
  • 一類是容器日誌。容器中的應用產生的日誌默認都輸出到stdoutstderr中,可以通過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 非容器化的組件日誌管理。

系統組件也分爲兩種,一種是運行在容器中的應用,包括schedulerkube-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 流式處理方案

參考資料

  1. Logging Architecture
  2. Docker日誌都在哪裏?怎麼收集?
  3. Systemd之journalctl
  4. Kubectl logs
  5. Docker Logging Overview
  6. fluentd
  7. Stackdriver
  8. TLDC
  9. Kubernetes日誌收集
  10. Kubernetes容器集羣中的日誌系統集成實踐
  11. Where are the Kubernetes kublet logs located?
  12. Kubernetes Log Analysis with Fluentd, Elasticsearch and Kibana
  13. Kubernetes Log File Locations
  14. Kubernetes Logs
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章