談一下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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM