在K8s中由規模大到小有三種收集logs的方式
DaemonSet 是一種K8s在Node上運行daemon的一種機制, 確保每台Node上都有運行一個Pod.
若有新的Node加入cluster, K8s會確保Node上有運行此Pod.
通常在一個Node中會運行Prometheus Node Exporter, Collectd, Flentd, Logstash等Daemon來收集這台主機的訊息
比如說Rancher的(K8s的UI工具)Cluster監控圖就是透過這種方式收集Nodes的資訊
以上這張圖可以很好的解釋所謂的SideCar.
所謂SideCar便是在一份Pod中運行兩個以上的Containers
同時可以透過volume的方式共用同一個檔案目錄, 例如上圖中的api container可以產生log到某個檔案目錄, 再由filebeat這個sidecar來讀取這個目錄的log並輸出至ElasticSearch
這種方式就是在將App打包成Image之前, 將filebeat的Config加入App
這樣App在運行時, log就會直接送到ElasticSearch, 當然也可以使用Fluentd先format再送到ElasticSearch
方式一 | 方式二 | 方式三 | |
---|---|---|---|
說明 | cluster-level安裝agent在Node上 | pod-level又稱為SideCar mode | app-level 將filebeat等套件直接包進Image |
優點 | 所有的App都有logs產生, 且不需要客製化image | 稍微比第三種方式省下一點記憶體, 在main container有很多replicas時可以共用一個檔案目錄去讀檔 | 直接在App寫filebeat的設定也可以, 自己包好image也可以, 不用花太多心力去研究log collector deployment怎麼寫 |
缺點 | 如果是多人共用Cluster, 可能會很難查找自己服務的logs, 除非format log, 但要怎麼 format也是問題 | 需要額外花心力去編寫volume設定, fluentd的deployment | 每個Container都會耗用更多的Resources, replicas一多起來資源可能吃很兇(JAVA App更是) |
在實務上的應用, 我們是將不同的專案用namespace做區分.
不是每個專案都需要收集logs, 倘若用第一種方式就會導致ElasticSearch收到全部服務的log
然而用第三種方式又會導致每個image變大+記憶體吃更多, 所以會建議如果只是部分專案需要用到log collection的話, 就使用第二種方式
在接下來的三天我會分別Demo這三種收集log的方式.
DaemonSet: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
Kubernetes中文指南/云原生应用架构实践手:
https://jimmysong.io/kubernetes-handbook/concepts/daemonset.html
Logging Architecture:
https://kubernetes.io/docs/concepts/cluster-administration/logging/
實務上都是二搭一多,第三種基本上揚棄不用。就只是觀念上的問題:管理者是不是接受得了任何軟體都可以是 pod,包括 agent / driver。
第三種的弊病在於,如果沒有 CICD pipeline,看到效能好的新 logging agent 沒有辦法馬上嘗試。例如一開始 lift-n-ship 用了 logstash,覺得太肥或者不太好配置,想轉 fluentd,那樣就得重新建置部署(dev -> prod 慢慢推)。用 sidecar 什麼時候想換就什麼時候換,改條 deployment 不需要花多少時間。
如果採用的是第一種方法,大家是怎麼做 rate limit 的?
fluentd: