雷驚鵬,唐雅文,顏世波,王 勝
(1.安徽國防科技職業(yè)學(xué)院 信息技術(shù)學(xué)院,安徽 六安 237011;2.錦江酒店(中國區(qū)) 信息技術(shù)中心,上海 110934)
各類日志包含了設(shè)備、資源、進程、服務(wù)等對象的運行狀態(tài)數(shù)據(jù),是運維人員應(yīng)予關(guān)注的主要信息集合。日志信息為開展性能測試、實施故障診斷和排除提供重要參考,例如記錄程序執(zhí)行情況以定位故障點[1]。充分發(fā)揮日志數(shù)據(jù)的價值至少需要關(guān)注兩個層面:一是需要采集的數(shù)據(jù)類型;二是合適的數(shù)據(jù)分析工具。例如在訪問由Nginx[2]提供的Web服務(wù)時,服務(wù)端將訪問情況和錯誤情況分別記錄在access.log和error.log文件。在大數(shù)據(jù)時代,由于各類組織和平臺的復(fù)雜性,業(yè)務(wù)系統(tǒng)產(chǎn)生的日志數(shù)據(jù)具有很強的分散性,且數(shù)據(jù)容量巨大。數(shù)據(jù)格式的多樣性,又為數(shù)據(jù)存儲、交換、檢索[3]等處理流程帶來了新挑戰(zhàn)。
傳統(tǒng)的日志分析手段主要基于時間軸,利用統(tǒng)計學(xué)理論與方法采集運行狀態(tài)隨時間變化的主要特征信息,效率低下,難以適應(yīng)網(wǎng)絡(luò)發(fā)展新時代日志數(shù)據(jù)分析的實時性要求??煽康娜罩竟芾砥脚_一般需要集成多個組件,以Scribe、Flume等為代表的收集系統(tǒng)[4],以Redis、HDFS等為代表的存儲系統(tǒng),以Kibana為代表的分析系統(tǒng),是目前應(yīng)用中較為典型的開源平臺。本文采用開源的Elasticsearch(分布式搜索引擎)、Logstash(日志收集)、Kibana(可視化平臺)為代表的技術(shù)棧,結(jié)合Docker和Kubernetes技術(shù),對Nginx服務(wù)器日志的分析系統(tǒng)進行了研究和實踐。
一般而言,功能完善的日志分析平臺應(yīng)至少包含日志收集、處理、存儲、展示等4個功能組件。日志數(shù)據(jù)處理流程如圖1所示。生產(chǎn)環(huán)境下的各類業(yè)務(wù)平臺將會產(chǎn)生大量日志數(shù)據(jù),以反映服務(wù)的運行狀態(tài)、被訪問情況以及安全信息。
圖1 日志處理流程Fig.1 The flow of log processing
對來自不同平臺或服務(wù)的日志進行收集、匯總,是開展日志分析工作的前提。輸入、過濾、輸出3個環(huán)節(jié)形成了Logstash處理的事件流。
文獻[5]描述了Logstash的數(shù)據(jù)收集引擎功能,以及完善的插件生態(tài)系統(tǒng)。Logstash可以在網(wǎng)絡(luò)中多節(jié)點進行部署以避免形成性能瓶頸,其豐富的插件系統(tǒng)使得日志收集和預(yù)處理較為靈活。此外,可以為Logstash單獨配置輸入/輸出的編碼解碼器,而無需單獨過濾。
Input插件用于配置數(shù)據(jù)輸入流。Logstash運行需要JVM(Java Virtual Machine)支持,消耗比較多的服務(wù)資源,因此可通過設(shè)置管道入口接收文件格式的Web日志信息。Filebeat插件提供了按行獲取Web日志的能力。該插件基于GO語言開發(fā),具有較高的可靠性和低延遲,且占用較少的系統(tǒng)資源,通常以代理形式運行在應(yīng)用服務(wù)器上。以下記錄是在生產(chǎn)環(huán)境中自定義的Nginx服務(wù)器日志信息格式的示例:
{"@timestamp":"2020-06-16T13:54:32+08:00","cookie-id":"-","client-ip":"122.112.208.240","remote-user":"-","request-method":"POST","domain":"ms.jj-inn.com","xff":"114.84.80.84,22.112.208.240","upstream-addr":"10.0.41.180:30101","upstream-response-time":"2.172","request-time":"2.171","size":"75","idc-tag":"tjtx","status":"200","upstream-status":"200","host":"ecs","via":"-","protocol":"http","request-uri":"/api//CardService/ReadyForWrite","http-referer":"-"}
日志分析所需的字段并不需要上述示例的全部內(nèi)容,因此利用Filter插件對日志數(shù)據(jù)進行過濾十分必要。文獻[6]對典型的過濾插件mutate和grok做了說明。日志過濾首先需要對上述示例格式的行記錄進行切分,利用mutate插件從中提取關(guān)鍵字,通過grok插件正則庫或自定義正則表達式進行調(diào)試。上例中半結(jié)構(gòu)化的日志信息如下所示:
122.112.208.240--[16/06/2020:13:54:32+08:00]ms.jj-inn.com POST "/api/" "/CardService/ReadyForWrite"
mutate插件修改配置文件中的split部分(僅適用于字符串字段)實現(xiàn)轉(zhuǎn)變,通過分隔符將字段拆分為數(shù)組。對上例所示記錄進行切分,取記錄中涉及http-request域的值相應(yīng)部分,代碼段如下:
mutate {
split=> ["http-request","/"]#http-request以“/”為切割點
add-field=> ["request-url","%{http-request[0]}"]#取出數(shù)組中第一個值,同時添加request-url為新的字段
}
經(jīng)過mutate處理后,進一步由grok確定相應(yīng)的正則表達式,例如可定義主機名的正則表達式:
HOSTNAME1(?:[a-zA-Z0-9--][a-zA-Z0-9---]{0,62})(?:.(?:[a-zA-Z0-9--][a-zA-Z0-9-:--]{0,62}))*(.?|)
output插件配置日志輸出。通過在相應(yīng)的配置文件中應(yīng)用字符串格式化命令來定義自定義的輸出路徑和名稱。以下代碼定義了將某天的Nginx日志按原始格式保存到/var/log目錄下:
output {
file {
path=> "/var/log/%{+yyyy/MM/dd}/%{host}.log "
message-format=> "%{message}"
}
}
除保存到本地外,output還支持通過http協(xié)議、node協(xié)議或transport協(xié)議將日志傳輸?shù)骄W(wǎng)絡(luò)中的其他節(jié)點。
文獻[7]研究了Elasticsearch的存儲結(jié)構(gòu)。Elasticsearch提供了分布式實時文件存儲的能力,具有很強的擴展性,可以在多達幾百臺服務(wù)器上進行部署,處理數(shù)據(jù)的能力達到PB級,且具有良好的交互性,管理接口可集成命令行、客戶端或者RESTful應(yīng)用程序接口等形式。
Elasticsearch基于Apache Lucene[8](TM)實現(xiàn)。Lucene在功能和性能上得到了業(yè)界的普遍承認,但用戶必須使用Java才能將其與第三方應(yīng)用有效集成。Elasticsearch向外提供了index(索引)的方式供用戶查詢,其分布式主要體現(xiàn)在每個索引由若干shard組成,結(jié)構(gòu)如圖2所示。
圖2 Elasticsearch分布式系統(tǒng)Fig.2 Distributed systems of Elasticsearch
經(jīng)過收集、存儲、分析過的日志信息,通過kibana組件以圖表方式進行可視化分析。Kibana提供了web形式的接口,其主要功能是搜索、查看、可視化、分析存儲在Elasticsearch索引節(jié)點中的日志數(shù)據(jù)。少量日志的分析很難讓運維人員從中找出數(shù)據(jù)的隱藏規(guī)律。將海量日志數(shù)據(jù)進行可視化處理,通過較為直觀的諸如直方圖、餅圖、柱狀圖、線狀圖等圖形,或是表格、地圖等高級形式進行展示,使得管理者對各類日志之間的關(guān)聯(lián)、變化認知更為清晰,為下一步的處理決策提供更為有效的指導(dǎo)。
Kibana基于ApacheLicense2.0 開源協(xié)議開發(fā)[9]。與Elasticsearch類似,其查詢語法設(shè)計也是基于Lucene,數(shù)據(jù)搜索可通過布爾值、字段值或通配符實施。
從第1部分分析可知,ELK系統(tǒng)由于其自身組件的復(fù)雜性,使得運維人員在部署該系統(tǒng)時耗費較多時間。虛擬化技術(shù)為ELK部署提供了更為便捷的實現(xiàn)思路。
Docker[10]技術(shù)主要解決開發(fā)環(huán)境與生產(chǎn)環(huán)境的一致性問題,在自動化部署應(yīng)用方面具有獨特優(yōu)勢。其本質(zhì)是提供一個虛擬的、輕量級的Linux操作系統(tǒng)環(huán)境,業(yè)務(wù)運行所需的應(yīng)用系統(tǒng)及應(yīng)用所依賴的運行環(huán)境被集成到分層的虛擬文件系統(tǒng)中,從而實現(xiàn)應(yīng)用在不同環(huán)境下的運行。相對于傳統(tǒng)的虛擬機技術(shù)(例如KVM),Docker的性能更接近原生,且由于每個Docker容器具有自身運行所需的資源,與其他容器相互隔離,所以Docker的安全性、隔離性更佳。運維人員在物理主機上可以部署多個Docker容器,容器間支持相互通信。
Image(鏡像)、Container(容器)、Repository(倉庫)是Docker運行機制的主要概念。Image具有分層和只讀的特征,容器在運行時所依賴的庫、配置文件、資源信息等內(nèi)容包含在其中。通過Dockerfile可以修改Image的內(nèi)容。每個經(jīng)修改的Image可以設(shè)置獨特的標簽信息,并存儲在私有倉庫或公有倉庫中,供其他用戶下載使用。Container提供了Image運行的實例。上述三者之間的關(guān)系如圖3所示。
圖3 Docker運行機制Fig.3 The operating mechanism of Docker
由于Docker服務(wù)是以進程形式運行在服務(wù)器上,當進程結(jié)束后,Docker容器內(nèi)的數(shù)據(jù)也會隨之丟失,因此在生產(chǎn)環(huán)境中需要考慮數(shù)據(jù)持久化存儲。
Docker的基本操作包括鏡像管理、容器管理等。如前述圖3所示,通過pull操作可從倉庫中將鏡像下載至本地,通過run操作可啟動鏡像實例。結(jié)合網(wǎng)絡(luò)情況,從公有倉庫中下載鏡像時,可預(yù)先通過修改/etc/docker目錄下的daemon.json文件配置加速器,從而減少鏡像下載的時間。本文在實現(xiàn)中使用的是阿里云提供的加速器。daemon.json文件內(nèi)容按如下內(nèi)容修改:
"registry-mirrors":["https://ef8u7llg.mirror.aliyuncs.com"]
通過search操作搜索所需的ELK安裝包,打包安裝的方式較為簡單,便于部署。通過STARS指標可幫助管理者判斷鏡像的權(quán)威性,如圖4所示。
圖4 搜索ELK軟件包Fig.4 Search for ELK packages
將軟件包下載至本地服務(wù)器后,可查看到其容量大約在2.3 GB左右,如圖5所示。這也是前期配置加速器的原因。ELK所需的運行環(huán)境集成在該軟件包內(nèi)。
圖5 可運行的ELK鏡像Fig.5 The runnable ELK image
ELK各組件在運行中應(yīng)用了不同的TCP/IP端口與配置文件,如表1所示。
表1 ELK組件配置文件與應(yīng)用端口Table1 The configuration file and application port of ELK components
構(gòu)造如下形式的命令啟動ELK鏡像,其中sebp/elk為鏡像名,并映射本地卷實現(xiàn)持久化存儲。
docker run-p 9200:9200-p 5044:5044-p 5601:5601-v/hostData:/ELKdata-it-d sebp/elk
圖6顯示了ELK系統(tǒng)啟動后的運行狀態(tài),其啟動速度一般為秒級,相對于傳統(tǒng)方式部署有很大優(yōu)化。
圖6 ELK組件的運行狀態(tài)Fig.6 The operation status of ELK components
Docker主要用于容器的創(chuàng)建,是典型的應(yīng)用容器引擎工具。在一些較大、較復(fù)雜的業(yè)務(wù)系統(tǒng)中,容器的編排、調(diào)度和管理等操作十分復(fù)雜,需要更加高級和靈活的管理方式。Kubernetes提供了基于容器的集群管理平臺。Kubernetes的前身是Google公司內(nèi)部使用多年的Borg系統(tǒng),是一個功能強大的容器編排系統(tǒng)[11]。Google使用GO語言開發(fā)Kubernetes系統(tǒng)及相關(guān)的生態(tài)系統(tǒng)(包括管理工具、模塊、插件等),其構(gòu)成組件包括Pod、Node(節(jié)點)、Label(標簽)與Annotation(注解)、Service Discovery(服務(wù)發(fā)現(xiàn))、ReplicaSet(副本集)、DaemonSet(守護進程集)、StatefulSet(有狀態(tài)集)、Job、ConfigMap(配置映射)與 Secret(機密配置)、Deployment(部署)、Storage(存儲)等11個組成部分。
在集成了Docker和Kubernetes的業(yè)務(wù)系統(tǒng)(K8s集群)中,主要包括1個Master節(jié)點(主節(jié)點)和一群Node節(jié)點(計算節(jié)點)。Master節(jié)點用于管理Node節(jié)點,而實現(xiàn)不同功能的容器則被封裝在pod中運行于Node節(jié)點上。每個pod表示集群中運行的一個進程,內(nèi)部封裝了若干相互聯(lián)系的容器,是操作的基本單元。通過Kubernetes實現(xiàn)容器集群的自動化部署及維護能力。
本文重點驗證ELK系統(tǒng)在Kubernetes集群中部署的整體有效性及處理效率。集群環(huán)境由3個Master節(jié)點和3個Node節(jié)點組成,軟硬件資源環(huán)境配置如表2所示。
表2 集群部署環(huán)境Table 2 The deployment environment of cluster
基于上述環(huán)境建立測試平臺,數(shù)據(jù)集為業(yè)務(wù)系統(tǒng)實際應(yīng)用所產(chǎn)生的Nginx日志,測試時集中向待收集的日志文件中寫入數(shù)據(jù)。Kubernetes集群節(jié)點運行狀態(tài)如圖7所示。
圖7 集群節(jié)點的運行狀態(tài)Fig.7 The running status of cluster nodes
通過構(gòu)造不同查詢語句,將日志數(shù)據(jù)并發(fā)導(dǎo)入后通過prometheus軟件監(jiān)控Kubernetes集群中ELK環(huán)境的CPU占用比例。構(gòu)造語句如下(以100 000條數(shù)據(jù)為例):
sum(rate(container-cpu-usage-seconds-total{image!=""}[1m]))by(pod-name,namespace)/(sum(container-spec-cpu-quota{image!=""}/100 000)by(pod-name,namespace))*100
構(gòu)造內(nèi)存占比監(jiān)控的語句如下:
sum(container-memory-rss{image!=""})by(pod-name,namespace)/sum(container-spec-memory-limit-bytes{image!=""})by(pod-name,namespace)*100!=+inf
通過elasticsearch組件獲取搜索數(shù)據(jù)如圖8所示,查詢時間為毫秒級。
圖8 查詢elasticsearch獲取搜索數(shù)據(jù)Fig.8 Get searched data by querying elasticsearch
處理500 000條數(shù)據(jù)的性能監(jiān)測如圖9所示。
圖9 查詢500 000 條數(shù)據(jù)的性能監(jiān)測情況Fig.9 Query the performance monitoring status of 500 000 pieces of data
基于單服務(wù)器系統(tǒng)的日志處理過程,軟硬件資源利用率、系統(tǒng)可靠性較弱,在大數(shù)據(jù)環(huán)境下容易產(chǎn)生問題。基于Docker和Kubernetes集群的日志處理系統(tǒng),具有優(yōu)異的部署效率和處理性能,并具備良好的可擴展性。
本文基于Kubernetes集群對典型的Web日志處理系統(tǒng)進行了研究,利用Elasticsearch 、Kibana和Docker等開源技術(shù)實現(xiàn)了日志數(shù)據(jù)的采集、處理、存儲和展示。通過在生產(chǎn)環(huán)境中進行部署,對實驗數(shù)據(jù)進行分析,驗證了本文所述技術(shù)路線和方法的可靠性、可用性。在后續(xù)研究中,結(jié)合典型的大數(shù)據(jù)分析技術(shù)對海量Web日志信息進行更深層次的處理,進一步提升挖掘到的信息價值。