在開始這篇文章以前,首先要明確一點: Kubernetes 中對容器日誌的處理方式,都叫作 cluster-level-logging ,也就是說,這個日誌處理系統,與容器, Pod 以及 Node 的生命週期都是徹底無關的.其實想一想也能知道,這種設計就是爲了保證,不管是容器宕了, Pod 被刪除甚至是節點宕機的時候,日誌處理系統仍然能夠被正常獲取到,從而能夠分析緣由所在.
而對於一個容器來講,當應用把日誌輸出到 stdout 和 stderr 以後,容器項目在默認狀況下,就會把這些日誌輸出到宿主機上的一個 JSON 文件中,這樣,我就可以經過 kubectl logs 命令,來查看到這些容器的日誌.
可是你要明白一點,那就是 Kubernetes 自己,其實是不會作容器日誌收集工做的,因此爲了可以實現上述 cluster-level-logging ,就須要在部署集羣的時候,就提早對具體的日誌方案進行規劃.所幸, Kubernetes 項目自己提供了三種相關方案.
接下來分別講一講.web
第一種 |
在 Node 上部署 logging agent ,將日誌文件轉發到後端存儲裏保存起來.這個方案的架構圖以下所示:
從中咱們可以看到,這裏的核心在於 logging agent ,它通常都會以 DaemonSet 的方式運行在節點上,而後將宿主機上的容器日誌目錄掛載進去,最後由 logging-agent 把日誌轉發出去.那麼,這樣一來,我只須要在一個節點上部署一個 agent 便可,這樣也不會對應用和 Pod 有任何侵入性.
可是這種方案,要求應用輸出的日誌,都必須是直接輸出到容器的 stdout 和 stderr 中.
這也就引出了第二種解決方案.後端
第二種 |
第二種狀況,主要就是對上面所述缺點的一個處理,即:當容器的日誌只能輸出到某些文件中時,能夠經過一個 sidecar 容器將這些日誌文件從新輸出到 sidecar 的 stdout 和 stderr 中.
這種解決方案的架構圖以下:
由於 sidecar 和主容器之間是共享 Volume 的,因此這裏的 sidecar 方案的額外性能損耗並不高,只不過是多用了一點兒 CPU 和內存罷了.
可是要了解一點,這種方案下,宿主機上會存在兩份相同的日誌文件:一份是應用本身寫入的,另一份則是 sidecar 的 stdout 和 stderr 對應的 JSON 文件.這樣就會形成對磁盤的巨大浪費.
因此,若是不是萬不得已,也不是應用容器徹底不可能被修改,仍是建議使用方案一,或者使用下面介紹的方案三.
固然了,土豪隨意,畢竟開心纔是重要的.架構
第三種 |
第三種方案,就是經過 sidecar 容器,直接將應用的日誌文件發送到遠程存儲裏面去.也就是,方案一中的 logging agent ,放在應用 Pod 中.繼續上一張架構圖:
在這種方案下,應用能夠直接把日誌輸出到固定的文件中,而不是 stdout , logging-agent 還可使用 fluentd ,後端存儲還能夠是 ElasticSearch .
這種方案,部署簡單,對宿主機也很是友好,可是這個 sidecar 容器,頗有可能會消耗比較多的資源,甚至會拖垮應用容器,此外,因爲日誌沒有輸出到 stdout 上面,因此就算你經過命令 kubectl logs 來查看,也是看不到任何日誌輸出到.ide
以上就是關於容器日誌的收集與管理的三種方案的介紹了.
有一點須要注意的是,無論到最後選擇什麼方案,到最後,必定要及時將這些日誌文件,從宿主機上清理掉,或者給日誌目錄文件專門掛載一些容量巨大的遠程盤.要否則,一旦磁盤分區被打滿,整個系統就可能會陷入崩潰狀態,這樣形成的損失就大多了.svg
以上內容來自我學習<深刻剖析Kubernetes>專欄文章以後的一些看法,有偏頗之處,還望指出.
感謝您的閱讀~性能