運行在容器內部的應用會在運行期間產生大量的日誌,這些日誌將作為我們 Debug,分析應用行為的重要依據。本文將帶大家瞭解一下 Docker 面對的和「容器日誌」有關的問題以及它的解決方案。
回想一下 Docker 的實現原理,無非是「多進程」+「隔離機制」。其中所有容器(子進程)都是由 dockerdaemon(父進程)來創建的。父進程可以收集子進程 PID Namespace 內 PID=1 進程的和標準輸出的內容。因為只有 PID = 1的進程纔是父進程創建的。如果該 PID = 1的子進程再創建孫子進程的話,父進程是無法收集到孫子進程內的標準輸出的內容的。
父進程是通過 Pipe 來獲取子進程的和標準輸出的。所以,在容器進程被創建的時候,會通過一個 Pipe 將輸出到標準輸出的日誌信息傳遞給父進程。而這一切對容器內部應用都是透明的。
當 dockerdaemon 進程從 Pipe 中拿到日誌信息之後,會將它交給一個特殊的模塊來進行處理—— Docker Log Driver。Log Driver 的職責也很簡單,既然收集到了日誌信息,那肯定需要將它寫入到一個位置,這個位置可以是一個 JSON 格式的文件(默認行為),也可以是一個有特殊含義的文件,如 syslog,甚至是一個第三方日誌的收集服務。