【做者barnett】本文介紹了k8s官方提供的日誌收集方法,並介紹了Fluentd日誌收集器並與其餘產品作了比較。最後介紹了好雨雲幫如何對k8s進行改造並使用ZeroMQ以消息的形式將日誌傳輸到統一的日誌處理中心。node
目前容器日誌有兩種輸出形式:git
這種形式的日誌輸出咱們能夠直接使用docker logs
查看日誌,k8s集羣中一樣集羣可使用kubectl logs
相似的形式查看日誌。github
日誌文件記錄golang
這種日誌輸出咱們沒法從以上方法查看日誌內容,只能tail
日誌文件查看。docker
在k8s官方文檔中,對於以上兩種形式的日誌形式咱們若是想收集並分析日誌的話,官方推薦如下兩種對策: 對於第一種文檔中這樣說:json
When a cluster is created, the standard output and standard error output of each container can be ingested using a Fluentd agent running on each node into either Google Cloud Logging or into Elasticsearch and viewed with Kibana.後端
When a Kubernetes cluster is created with logging to Google Cloud Logging enabled, the system creates a pod called fluentd-cloud-logging on each node of the cluster to collect Docker container logs. These pods were shown at the start of this blog article in the response to the first get pods command.緩存
就說說集羣啓動時會在每一個機器啓動一個Fluentd agent
收集日誌而後發送給 Elasticsearch
。
實現方式是每一個agent掛載目錄/var/lib/docker/containers
使用fluentd
的tail
插件掃描每一個容器日誌文件,直接發送給Elasticsearch
。網絡
對於第二種:架構
- A second container, using the gcr.io/google_containers/fluentd-sidecar-es:1.2 image to send the logs to Elasticsearch. We recommend attaching resource constraints of 100m CPU and 200Mi memory to this container, as in the example.
- A volume for the two containers to share. The emptyDir volume type is a good choice for this because we only want the volume to exist for the lifetime of the pod.
- Mount paths for the volume in each container. In your primary container, this should be the path that the applications log files are written to. In the secondary container, this can be just about anything, so we put it under /mnt/log to keep it out of the way of the rest of the filesystem.
- The FILES_TO_COLLECT environment variable in the sidecar container, telling it which files to collect logs from. These paths should always be in the mounted volume.
其實跟第一種相似,可是是把Fluentd agent
起在業務同一個pod中共享volume而後實現對日誌文件的收集發送給Elasticsearch
對於fluentd官方對其的定義是:
Fluentd經過在後端系統之間提供統一的日誌記錄層來從後端系統中解耦數據源。 此層容許開發人員和數據分析人員在生成日誌時使用多種類型的日誌。 統一的日誌記錄層可讓您和您的組織更好地使用數據,並更快地在您的軟件上進行迭代。 也就是說fluentd是一個面向多種數據來源以及面向多種數據出口的日誌收集器。另外它附帶了日誌轉發的功能。
引用一張圖對比這兩個日誌收集工具。具體它們兩個項目的對比請參考:
Fluentd vs. Logstash: A Comparison of Log Collectors
把這兩個產品放在一塊兒比較實屬不怎麼合適,由於它們屬於不一樣的陣營,完成不一樣的功能需求。因爲fluentd具備消息轉發的功能,姑且將其與以zeroMQ爲例的消息中間件的關係作個說明: 在大型系統架構中,有使用zeroMQ進行大量的日誌轉發工做。在fluentd中有兩個項目完成日誌的中轉路由的任務:golang編寫的:fluentd-forwarder 和c寫的fluent-bit
那麼是否意味着你須要作出選擇呢?其實否則。 着眼fluentd的定義和zeroMQ的定義。其實它們是一種合做關係。若是你是大型的架構系統,日誌量很龐大。我推薦你使用fluentd進行日誌收集,將zeroMQ做爲fluentd的出口。就是說fluentd完成統一收集,zeroMQ完成日誌傳輸。若是你的系統並不龐大,你就無需zeroMQ來傳輸了。
所以你也無需關注這兩個產品的性能比較。雖然它們都有高性能的定義。
zeroMQ的性能測試結果:zeroMQ 與JeroMQ性能對比
如上所描述的同樣,不管你的業務容器日誌呈現方式有什麼不一樣,你均可以使用統一的日誌收集器收集。如下簡介三種狀況下日誌手機方式推薦:
docker cloud
提供了與kubectrl logs
相似的機制查看stdout的日誌。目前尚未fluentd插件直接對服務進行日誌收集,暫時考慮直接使用使用跟容器同樣的機制收集。docker service create
支持--log-driver
fluentd
log driver。以以下的形式啓動容器,容器stdout/stderr日誌將發往配置的fluentd。若是配置後,docker logs
將沒法使用。另外默認模式下若是你配置得地址沒有正常服務,容器沒法啓動。你也可使用fluentd-async-connect
形式啓動,docker daemon則能在後臺嘗試鏈接並緩存日誌。docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224
一樣若是是日誌文件,將文件暴露出來直接使用fluentd收集。
雲幫的公有云服務,平臺上跑着有企業級應用和小型用戶應用。咱們怎麼作到統一的日誌收集和展現?又怎麼作到面對企業級應用的日誌輸出和分析?
上面提到的方式不能徹底解決咱們的問題。
首先目前kubernetes版本(v1.5.1)還不支持pod級別的日誌log-driver設置,可是咱們知道容器是能夠設置log-driver的。這裏也有關於這個問題的討論。咱們爲了實如今用戶網絡(即pod容器網絡)下的可配置日誌轉發方式。咱們暫時修改了kubernetes源碼使其支持設置容器的log-driver。默認狀況下咱們使用本身實現的zeroMQ-driver直接將容器日誌經過0MQ發到日誌統一處理中心。在處理中心統一完成下一步處理。若是平臺用戶須要將日誌向外輸出或者直接對接平臺內日誌分析應用,咱們的處理是在應用pod中啓動日誌收集插件容器(封裝擴展的fluentd),根據用戶的須要配置日誌出口,實現應用級日誌收集。這裏你須要明確的是:容器日誌首先是由docker-daemon收集到,再根據容器log-driver配置進行相應操做,也就是說若是你的宿主機網絡與容器網絡不通(k8s集羣),日誌從宿主機到pod中的收集容器只有兩種方式:走外層網絡,文件掛載。 咱們採用文件掛載方式。
若是您對本文提到的k8s官方收集、處理日誌以及對好雨雲幫的日誌收集方式有疑問或問題,歡迎留言,做者會在第一時間解答。
雲盟認證成員:barnett