Kubernetes(k8s)那些套路之日誌收集

關於容器日誌

Docker的日誌分爲兩類,一類是 Docker引擎日誌;另一類是容器日誌。引擎日誌一般都交給了系統日誌,不同的操作系統會放在不同的位置。本文主要介紹容器日誌,容器日誌可以理解是運行在容器內部的應用輸出的日誌,默認情況下,docker logs 顯示當前運行的容器的日誌信息,內容包含 STOUT(標準輸出) 和 STDERR(標準錯誤輸出)。日誌都會以 json-file 的格式存儲於 /var/lib/docker/containers/<容器id>/<容器id>-json.log ,不過這種方式並不適合放到生產環境中。

  • 默認方式下容器日誌並不會限制日誌文件的大小,容器會一直寫日誌,導致磁盤爆滿,影響系統應用。(docker log-driver 支持log文件的rotate)
  • Docker Daemon 收集容器的標準輸出,當日志量過大時會導致Docker Daemon 成爲日誌收集的瓶頸,日誌的收集速度受限。
  • 日誌文件量過大時,利用docker logs -f 查看時會直接將Docker Daemon阻塞住,造成docker ps等命令也不響應。

Docker提供了logging drivers配置,用戶可以根據自己的需求去配置不同的log-driver,可參考官網 Configure logging drivers 。但是上述配置的日誌收集也是通過Docker Daemon收集,收集日誌的速度依然是瓶頸。

  • log-driver 日誌收集速度
  • syslog 14.9 MB/s
  • json-file 37.9 MB/s

能不能找到不通過Docker Daemon收集日誌直接將日誌內容重定向到文件並自動 rotate的工具呢?答案是肯定的採用S6基底鏡像。

S6-log 將 CMD 的標準輸出重定向到/.../default/current,而不是發送到 Docker Daemon,這樣就避免了 Docker Daemon 收集日誌的性能瓶頸。本文就是採用S6基底鏡像構建應用鏡像形成統一日誌收集方案。

S6:http://skarnet.org/software/s6/

關於k8s日誌

k8s日誌收集方案分成三個級別:

  • 應用(Pod)級別
  • 節點級別
  • 集羣級別

應用(Pod)級別

Pod級別的日誌 , 默認是輸出到標準輸出和標誌輸入,實際上跟docker 容器的一致。使用 kubectl logs pod-name -n namespace 查看。

節點級別

Node級別的日誌 , 通過配置容器的log-driver來進行管理 , 這種需要配合logrotare來進行 , 日誌超過最大限制 , 自動進行rotate操作。

集羣級別

集羣級別的日誌收集,有三種

  • 節點代理方式,在node級別進行日誌收集。一般使用DaemonSet部署在每個node中。這種方式優點是耗費資源少,因爲只需部署在節點,且對應用無侵入。缺點是隻適合容器內應用日誌必須都是標準輸出。
  • 使用 sidecar container作爲容器日誌代理,也就是在pod中跟隨應用容器起一個日誌處理容器,有兩種形式:

一種是直接將應用容器的日誌收集並輸出到標準輸出(叫做Streaming sidecar container),但需要注意的是,這時候,宿主機上實際上會存在兩份相同的日誌文件:一份是應用自己寫入的;另一份則是 sidecar 的 stdout 和 stderr 對應的 JSON 文件。這對磁盤是很大的浪費 , 所以說,除非萬不得已或者應用容器完全不可能被修改。

另一種是每一個pod中都起一個日誌收集agent(比如logstash或fluebtd)也就是相當於把方案一里的 logging agent放在了pod裏。但是這種方案資源消耗(cpu,內存)較大,並且日誌不會輸出到標準輸出,kubectl logs 會看不到日誌內容。

應用容器中直接將日誌推到存儲後端,這種方式就比較簡單了,直接在應用裏面將日誌內容發送到日誌收集服務後端。

日誌架構

通過上文對k8s日誌收集方案的介紹,要想設計一個統一的日誌收集系統,可以採用節點代理方式收集每個節點上容器的日誌,日誌的整體架構如圖所示。

解釋如下:

  • 1、所有應用容器都是基於s6基底鏡像的,容器應用日誌都會重定向到宿主機的某個目錄文件下比如/data/logs/namespace/appname/podname/log/xxxx.log
  • 2、log-agent 內部 包含 filebeat ,logrotate 等工具,其中filebeat是作爲日誌文件收集的agent
  • 3、通過filebeat將收集的日誌發送到kafka
  • 4、kafka在把日誌發送的es日誌存儲/kibana檢索層
  • 5、logstash 作爲中間工具主要用來在es中創建index和消費kafka 的消息

整個流程很好理解,但是需要解決的是

  • 1、用戶部署的新應用,如何動態更新filebeat配置,
  • 2、如何保證每個日誌文件都被正常的rotate,
  • 3、如果需要更多的功能則需要二次開發filebeat,使filebeat 支持更多的自定義配置。

付諸實踐

解決上述問題,就需要開發一個log-agent應用以daemonset形式運行在k8s集羣的每個節點上,應用內部包含filebeat,logrotate,和需要開發的功能組件。

第一個問題,如何動態更新filebeat配置,可以利用http://github.com/fsnotify/fsnotify 工具包監聽日誌目錄變化create、delete事件,利用模板渲染的方法更新filebeat配置文件

第二個問題,利用http://github.com/robfig/cron 工具包 創建cronJob,定期rotate日誌文件,注意應用日誌文件所屬用戶,如果不是root用戶所屬,可以在配置中設置切換用戶

/var/log/xxxx/xxxxx.log {
      su www-data www-data
      missingok
      notifempty
      size 1G
      copytruncate
    }

第三個問題,關於二次開發filebeat,可以參考博文 https://www.jianshu.com/p/fe3ac68f4

總結

本文只是對k8s日誌收集提供了一個簡單的思路,關於日誌收集可以根據公司的需求,因地制宜。

參考文獻

  • 1、kubernetes.io/docs/concepts/cluster-administration/logging/
  • 2、https://support.rackspace.com/how-to/understanding-logrotate-utility/
  • 3、https://github.com/elastic/beats/tree/master/filebeat
  • 4、http://skarnet.org/software/s6/
  • 作者:知道又忘了
  • 原文出處:https://zhuanlan.zhihu.com/p/70662744

熱門文章推薦

最後

  • 後臺回覆 【 列表】,可獲取本公衆號所有文章列表
  • 歡迎您加我微信【 ypxiaozhan01 】,拉您進技術羣,一起交流學習
  • 歡迎您關注【 YP小站 】,學習互聯網最流行的技術,做個專業的技術人

  【文章讓您有收穫,👇  或者 在看 支持我吧】

本文分享自微信公衆號 - YP小站(ypxiaozhan)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章