Docker日志收集最佳实践
傳統日志處理
說到日志,我們以前處理日志的方式如下:
· 日志寫到本機磁盤上
· 通常僅用于排查線上問題,很少用于數據分析
·需要時登錄到機器上,用grep、awk等工具分析
?
那么,這種方式有什么缺點呢?
?
第一,???它的效率非常低,因為每一次要排查問題的時候都要登到機器上去,當有幾十臺或者是上百臺機器的時候,每一臺機器去登陸這是一個沒辦法接受的事情,可能一臺機器浪費兩分鐘,整個幾小時就過去了。
?
第二,???如果要進行一些比較復雜的分析,像grep、awk兩個簡單的命令不能夠滿足需求時,就需要運行一些比較復雜的程序進行分析。
?
第三,???日志本身它的價值不光在于排查一些系統問題上面,可能在一些數據的分析上,可能利用日志來做一些用戶的決策,這也是它的價值,如果不能把它利用起來,價值就不能充分的發揮出來。
?
所以,現在很多公司會采用集中式日志收集的日志處理方式,我們會把日志分布式收集,集中來存儲,我們會在所有機器上面把日志都收集起到一個中心,在中心里面做一個日志全文索引搜索,可以通過一個界面去查詢,同時這個日志系統后端可以對接一些更復雜的數據處理系統,可以對接監控、報警系統,對接數據挖掘數據分析系統,充分發揮日志的價值。
?
Docker的日志處理
?
使用過Docker的人尤其是使用過容器編排系統,比如說我們的容器服務,可能已經注意到這樣的一些特點:
?
容器編排跟傳統的布置方式是不一樣的,在容器編排里面,資源分配應用跑到哪臺機器上面的決策是由容器層來做的,所以你事先不知道你的容器應用會跑到哪臺機器上面;還有自動伸縮,根據負載自動增加或者減少容器數量;另外,在整個運行過程中,系統發生一些情況時,比如說你的容器宕掉了,容器服務會自動把容器應用遷到其他的機器上去,整個過程非常動態,如果像傳統方式去配制日志的收集工具,從一臺機器上面收集某一個應用,在這個動態下面,很難用原來的方式去配置。
?
基于這些特點,在Docker的日志里面,?我們只能夠采用中心化的日志收集方案,你已經沒辦法再像原來登到一臺機器上面去看它的日志是什么,因為你不知道它其實在哪個機器上面。
?
stdout和文件日志
?
Docker的日志我們可以把它分成兩類,一類是stdout標準輸出,另外一類是文件日志。stdout是寫在標準輸出里面的日志,比如你在程序里面,通過print或者echo來輸出的時候,這種輸出標準在linux上面其實是往一個ID為零的文件表述書里面去寫;另外的就是文件日志,文件日志就是寫在磁盤上的日志,一般來說我們會在傳統的應用里面會用得多一些。
?
stdout
?
在Docker的場景里面,目前比較推崇這種標準輸出的日志,標準輸出日志具體過程如圖。標準輸出日志的原理在于,當在啟動進程的時候,進程之間有一個父子關系,父進程可以拿到子進程的標準輸出。拿到子進程標準輸出的后,父進程可以對標準輸出做所有希望的處理。
例如,我們通過exec.Command啟動了一個命令,帶一些參數,然后就可以通過標準的pipeline拿到標準輸出,后面就可以拿到程序運行過程中產生標準輸出。?Docker也是用這個原理來拿的,所有的容器通過Docker Daemon啟動,實際上屬于Docker的一個子進程,?它可以拿到你的容器里面進程的標準輸出,然后拿到標準輸出之后,會通過它自身的一個叫做LogDriver的模塊來處理,LogDriver就是Docker用來處理容器標準輸出的一個模塊。?Docker支持很多種不同的處理方式,比如你的標準輸出之后,在某一種情況下會把它寫到一個日志里面,Docker默認的JSON File日志,除此之外,Docker還可以把它發送到syslog里面,或者是發送到journald里面去,或者是gelf的一個系統。
?
怎么配置log driver呢?
?
用Docker來啟動容器的話,你有兩種方式來配置LogDriver:
?
第一種方式是在Daemon上配置,對所有的容器生效。你配置之后,所有的容器啟動,如果沒有額外的其他配制,默認情況下就會把所有容器標準輸出全部都發送給Syslog服務,這樣就可以在這個Syslog服務上面收集這臺機器上的所有容器的標準輸出;
第二種方式是在容器上配置,只對當前容器生效。如果你希望這個配置只對一個容器生效,不希望所有容器都受到影響,你可以在容器上面配置。啟動一個容器,單獨配置它自身使用的logdriver。
其實Docker之前已經支持了很多的logdriver,圖中列表是直接從Docker的官方文檔上面拿到的。
?
文件日志
?
對于stdout的這種日志,在Docker里面現在處理起來還是比較方便的,如果沒有現成Logdriver的也可以自己實現一個,但是對于文件日志處理起來就沒有這么簡單了。如果在一個容器里面寫了日志,文件位于容器內部,從宿主機上無法訪問,的確你是可以根據Docker用的devicemapper、overlayfs訪問到它里面的一個文件,但是這種方式跟Docker的實現機制是有關系的,將來它如果改變,你的方案就失效了;另外,容器運行非常動態,日志收集程序難以配置,如果有一個日志收集的程序,在機器上面配置要收集哪個文件,它的格式是什么樣子的、發送到哪兒?因為一臺機器上面容器是一直在動態變的,它隨時可能在增加一個或者刪除一個,事先你并不知道這臺機器上會跑了多少個容器,他們的配置是怎么樣子的,他們的日志是寫在哪兒的,所以沒辦法預先在一臺機器上面把這個采集程序配好,這就是文件收集比較難的兩個地方。
?
最簡單的一個方案,給每個容器弄一個日志采集進程,這個進程跑到容器里面,就可以解決以上的兩個問題,第一因為它跑到容器里面,就可以訪問到容器里面所有的文件,包括日志文件;第二它跟容器在一起,當容器啟動的時候,收集日志的進程也啟動了,當容器銷毀的時候,進程也就被銷毀掉了。
?
這個方案非常簡單,但是其實會有很多的缺點:
?
第一,???因為每個容器都有一個日志的進程,意味著你的機器上面有100個容器,就需要啟動一百個日志設備的程序,資源的浪費非常厲害。
?
第二,???在做鏡像的時候,需要把容器里面日志采集程序做到鏡像里面去,對你的鏡像其實是有入侵的,為了日志采集,不得不把自己的日志程序再做個新鏡像,然后把東西放進去,所以對你的鏡像過程是有入侵性的。
?
第三,???當一個容器里面好多個進程的時候,對于容器的資源管理,會干擾你對容器的資源使用的判斷,包括對于在做資源分配和監控的時候,都會有一些這樣的干擾。
?
fluentd-pilot
?
在容器服務上面,我們新開發了一個工具,稱之為fluentd-pilot。
?
fluentd-pilot是一個開源的日志采集工具,適合直接在一臺機器上面跑單個進程模式。fluentd-pilot有這樣的一些特點:
?
· 一個單獨fluentd進程,收集機器上所有容器的日志。不需要為每個容器啟動一個fluentd進程;
?
· 聲明式配置。使用label聲明要收集的日志文件的路徑;
?
· 支持文件和stdout;
?
· 支持多種后端存儲:elasticsearch,?阿里云日志服務, graylog2…
?
具體是怎么做呢?如圖,這是一個簡單的結構,在Docker宿主機上面部署一個fluentd-pilot容器,然后在容器里面啟動的時候,我們要聲明容器的日志信息,fluentd-pilot會自動感知所有容器的配置。每次啟動容器或者刪除容器的時候,它能夠看得到,當看到容器有新容器產生之后,它就會自動給新容器按照你的配置生成對應的配置文件,然后去采集,最后采集回來的日志同樣也會根據配置發送到后端存儲里面去,這里面后端主要指的elasticsearch或者是SLS這樣的系統,接下來你可以在這個系統上面用一些工具來查詢等等。整個這一塊在Docker宿主機上面,外面的就是外部系統,由這兩個部分來組成。
?
我們既然要用fluentd-pilot,就得先把它啟動起來。還要有一個日志系統,日志要集中收集,必然要有一個中間服務去收集和存儲,所以要先把這種東西準備好,然后我們在每一個收集日志的機器上面部署一個fluentd-pilot,用這個命令來部署,其實現在它是一個標準的Docker鏡像,內部支持一些后端存儲,可以通過環境變量來指定日志放到哪兒去,這樣的配置方式會把所有的收集到的日志全部都發送到elasticsearch里面去,當然兩個管掛載是需要的,因為它連接Docker,要感知到Docker里面所有容器的變化,它要通過這種方式來訪問宿主機的一些信息。
配置好之后啟動應用,我們看應用上面要收集的日志,我該在上面做什么樣的聲明?關鍵的配置有兩個,一是label catalina,聲明的時候要收集容器的日志,所有的名字都可以;二是聲明access,這也是個名字,都可以用你喜歡的名字。這樣一個路徑的地址,當你通過這樣的配置來去啟動fluentd-pilot容器之后,它就能夠感覺到這樣一個容器的啟動事件,它會去看容器的配置是什么,要收集這個目錄下面的文件日志,然后告訴fluentd-pilot去中心配置并且去采集,這里有一個-V,實際上跟Logs是一致的,在容器外面實際上沒有一種通用的方式能夠獲取到容器里面的文件,所有我們主動把目錄從宿主機上掛載進來,這樣就可以在宿主機上看到目錄下面所有的東西。
?
除了最簡單的場景之外,你的日志可能會有一些更復雜的特性,比如你的日志格式是什么樣子,你可能希望在收集之后加一些內容,便于搜索,當你在真用的時候,它不光是一個非常簡單的容器,它可能屬于某一個業務或者屬于某一個應用,那么,你希望在收集的時候能夠有一些關聯信息,所以你可以指定日志格式是什么樣子,然后可以在日志里添加tag,這些tag相當于一些關鍵信息,可以附加任何需要的關聯信息,這樣將來在搜索的時候可以更方便的把這些日志聚在一塊;而且,它可以指定很多的后端,fluetnd-pilot支持多種后端,使用環境變量FLUENTD_OUTPUT指定后端類型。
?
fluent-pilot已經開源,如果功能不滿足需求,可以自己定制,自己修改代碼實現需要的功能。它的結構比較簡單,有這樣幾個模塊:
?
最上層是容器事件管理,這一塊跟Docker進行交互,它會感知Docker的創建容器,然后做出相應的生成配置或者清理配置上的事情;解析容器label跟容器配置,當你創建一個新容器之后,就會用這個模塊拿到新容器的配置,然后生成對應的配置文件;FluentdController主要是用來維護對應進程,包括控制什么時候加載新配置,然后檢測一些健康狀態等等;再下面就是Fluentd的一些插件,如果你需要增加一些日志的后端,就可以自己實現一些插件,放在這個里面,然后再生成跟對應的插件相關的一些配置。? ?
?
fleuntd-pilot+阿里云容器服務
?
以上是fleuntd-pilot本身的一些能力,現在你可以在任何地方使用它,但是在容器服務上面我們針對它做了一些更加靈活方便、更酷的一些事情,容器服務為fluentd-pilot進行優化:
第一,???自動識別aliyun.logs標簽,并創建Volume;
第二,???重新部署,新容器自動復用已有的Volume,避免日志丟失。
?
原生支持SLS
?
容器服務有一個很棒的特點,它會跟其他的云產品做一些非常方便的集成,這對于用戶來說,在使用容器服務的時候,云產品能夠更加方便的使用。比如說在日志方面,阿里云容器服務專為SLS做了優化,讓用戶更簡單的在容器服務上使用SLS。SLS是阿里云提供的日志服務,性能強悍,使用方便,還可以對接ODPS等數據系統;支撐1W臺物理機,一天12TB日志數據,IOPS>= 2W,采集平均<1 S;單機:在1個CPU core情況下,可以實時采集15-18MB/S??日志量;如果配置中增加可以用線程數目,可水平擴展;是阿里云環境下的最佳日志方案。
?
優化優點具體體現在:自動創建sls的project, logstore;同時支持stdout和文件日志,使用同樣的方式配置。
?
容器服務日志方案
?
比如在容器服務上面布一個tomcat,可能會寫如圖的一個標準Docker的模板。??
?
當你通過部署之后,就可以在日志服務上面看到會生成兩個東西,都是創建好的,加一些前綴來區分,不用管一些配置,你唯一要做的事是什么呢?點日志索引查詢,然后到日志搜索界面,剛才啟動的時候一些日志,可以看到從哪過來的,這條日志的內容是什么,這些信息都已經很快的出現了,包括需要檢索可以選中一個時間段,輸入關健詞去做一些搜索,自動在日志服務上創建并配置logstore。
?
我們在容器服務上面做到了對于文件日志的收集,并且方式也都非常簡單,都是你可以設立一個label,通過label方式可以收集到所有的日志。
?
日志存儲方案
?
最后簡單的介紹幾種日志存儲方案的對比,圖為現在比較流行的日志方案Elasticsearch,它本身并不提供界面,ELK中的E,基于Lucene,主要用于日志索引、存儲和分析;通常配合Kibana展示日志,免費,支持集群模式,可以搭一個Docker用的生產環境可用的系統。
接下來是graylog2,目前不算很流行,但是也是功能很強大的系統,它不像Elasticsearch還需要配合其它去使用,它自身擁有日志存儲、索引以及展示所有的功能,都在一個系統里面實現,它可以設置一些報警規則,當日志里面出現一些關鍵字的時候自動報警,這個功能還是非常有用的,免費、支持集群模式,可以在生產環境里面搭一個Docker用的生產系統。
阿里云的日志服務SLS特點如下:
· 阿里云托管,不需要自己維護
· 支持多用戶和權限管理
· 可以對接ODPS等系統
· 支撐1W臺物理機,一天12TB日志數據,IOPS>= 2W,采集平均<1 S;單機:在1個CPU core情況下,可以實時采集15-18MB/S??日志量;如果配置中增加可以用線程數目,可水平擴展
?
用正確的方式寫日志
?
那么,我們怎么樣去收集日志、存儲日志,用什么樣的系統,日志的源頭和寫日志我們又該怎么來做,有這樣幾個建議:
?
1. ?選擇合適的日志框架,不要直接print;
2. ?為每一條日志選擇正確的level,該debug的不要用info;
3. ?附加更多的上下文信息;
4. ?使用json、csv等日志格式,方便工具解析;
5. ?盡量不要使用多行日志(Java Exception Stack)。
?
? ? ? ?(--轉載 :云棲社區--)
轉載于:https://www.cnblogs.com/jingjulianyi/p/6637801.html
總結
以上是生活随笔為你收集整理的Docker日志收集最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css 外边距合并
- 下一篇: CSS3 Flex布局(伸缩布局盒模型)