| 
 上圖是EFK架構(gòu)圖,k8s環(huán)境下常見的日志采集方式。 日志需求1  集中采集微服務(wù)的日志,可以根據(jù)請(qǐng)求id追蹤到完整的日志; 2 統(tǒng)計(jì)請(qǐng)求接口的耗時(shí),超出最長響應(yīng)時(shí)間的,需要做報(bào)警,并針對(duì)性的進(jìn)行調(diào)優(yōu); 3  慢sql排行榜,并報(bào)警; 4  異常日志排行榜,并報(bào)警; 5 慢頁面請(qǐng)求排行,并告警; k8s的日志采集k8s本身不會(huì)為你做日志采集,需要自己做; k8s的容器日志處理方式采用的 集群層級(jí)日志, 即容器銷毀,pod漂移,Node宕機(jī)不會(huì)對(duì)容器日志造成影響; 
 容器的日志會(huì)輸出到stdout,stderr,對(duì)應(yīng)的存儲(chǔ)在宿主機(jī)的目錄中, 即 /var/lib/docker/container ; Node上通過日志代理轉(zhuǎn)發(fā)
 在每個(gè)node上部署一個(gè)daemonset , 跑一個(gè)logging-agent收集日志, 比如fluentd, 采集宿主機(jī)對(duì)應(yīng)的數(shù)據(jù)盤上的日志,然后輸出到日志存儲(chǔ)服務(wù)或者消息隊(duì)列; 優(yōu)缺點(diǎn)分析: 
| 對(duì)比 | 說明 |  
| 優(yōu)點(diǎn) | 1每個(gè)Node只需要部署一個(gè)Pod采集日志 2對(duì)應(yīng)用無侵入 |  
| 缺點(diǎn) | 應(yīng)用輸出的日志都必須直接輸出到容器的stdout,stderr中 |  Pod內(nèi)部通過sidecar容器轉(zhuǎn)發(fā)到日志服務(wù)
 通過在pod中啟動(dòng)一個(gè)sidecar容器,比如fluentd, 讀取容器掛載的volume目錄,輸出到日志服務(wù)端; 日志輸入源: 日志文件 日志處理: logging-agent ,比如fluentd 日志存儲(chǔ): 比如elasticSearch ,  kafka 優(yōu)缺點(diǎn)分析: 
| 對(duì)比 | 說明 |  
| 優(yōu)點(diǎn) | 1  部署簡單;2  對(duì)宿主機(jī)友好; |  
| 缺點(diǎn) | 1. 消耗較多的資源;2. 日志通過kubectl logs 無法看到 |  示例: apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox
    args:
    - /bin/sh
    - -c
    - >
        i=0;
        while true;
        do
          echo "$i:$(data)" >> /var/log/1.log
          echo "$(data) INFO $i" >> /var/log/2.log
           i=$((i+1))
          sleep 1;
        done
    volumeMounts:
    - name: varlog
        mountPath: /var/log
  - name: count-agent
    image: k8s.gcr.io/fluentd-gcp:1.30
    env:
    - name: FLUENTD_ARGS
        value: -c /etc/fluentd-config/fluentd.conf
    valumeMounts:
    - name: varlog
        mountPath: /var/log
    - name: config-volume
        mountPath: /etc/fluentd-config
  volumes:
  - name: varlog
      emptyDir: {}
  - name: config-volume
      configMap:
        name: fluentd-config
 Pod內(nèi)部通過sidecar容器輸出到stdout
 適用于應(yīng)用容器只能把日志輸出到文件,無法輸出到stdout,stderr中的場景; 通過一個(gè)sidecar容器,直接讀取日志文件,再重新輸出到stdout,stderr中, 即可使用Node上通過日志代理轉(zhuǎn)發(fā)的模式; 優(yōu)缺點(diǎn)分析: 
| 對(duì)比 | 說明 |  
| 優(yōu)點(diǎn) | 只需耗費(fèi)比較少的cpu和內(nèi)存,共享volume處理效率比較高 |  
| 缺點(diǎn) | 宿主機(jī)上存在兩份相同的日志,磁盤利用率不高 |  應(yīng)用容器直接輸出日志到日志服務(wù)
 適用于有成熟日志系統(tǒng)的場景,日志不需要通過k8s; EFK介紹fluentdfluentd是一個(gè)統(tǒng)一日志層的開源數(shù)據(jù)收集器。 flentd允許你統(tǒng)一日志收集并更好的使用和理解數(shù)據(jù); 
 四大特征: 統(tǒng)一日志層 fluentd隔斷數(shù)據(jù)源,從后臺(tái)系統(tǒng)提供統(tǒng)一日志層; 簡單靈活提供了500多個(gè)插件,連接非常多的數(shù)據(jù)源和輸出源,內(nèi)核簡單;
 廣泛驗(yàn)證5000多家數(shù)據(jù)驅(qū)動(dòng)公司以來Fluentd
 最大的客戶通過它收集5萬多臺(tái)服務(wù)器的日志
 **云原生**
 是云原生CNCF的成員項(xiàng)目 
 4大優(yōu)勢: 統(tǒng)一JSON日志 
 fluentd嘗試采用JSON結(jié)構(gòu)化數(shù)據(jù),這就統(tǒng)一了所有處理日志數(shù)據(jù)的方面,收集,過濾,緩存,輸出日志到多目的地,下行流數(shù)據(jù)處理使用Json更簡單,因?yàn)樗呀?jīng)有足夠的訪問結(jié)構(gòu)并保留了足夠靈活的scemas; 插件化架構(gòu) 
 fluntd 有靈活的插件體系允許社區(qū)擴(kuò)展功能,500多個(gè)社區(qū)貢獻(xiàn)的插件連接了很多數(shù)據(jù)源和目的地; 通過插件,你可以開始更好的使用你的日志 最小資源消耗 
 c和ruby寫的,需要極少的系統(tǒng)資源,40M左右的內(nèi)存可以處理13k/時(shí)間/秒 ,如果你需要更緊湊的內(nèi)存,可以使用Fluent bit ,更輕量的Fluentd 內(nèi)核可靠 
 Fluentd支持內(nèi)存和基于文件緩存,防止內(nèi)部節(jié)點(diǎn)數(shù)據(jù)丟失;也支持robust失敗并且可以配置高可用模式, 2000多家數(shù)據(jù)驅(qū)動(dòng)公司在不同的產(chǎn)品中依賴Fluentd,更好的使用和理解他們的日志數(shù)據(jù)
 使用fluentd的原因: 簡單靈活 10分鐘即可在你的電腦上安裝fluentd,你可以馬上下載它,500多個(gè)插件打通數(shù)據(jù)源和目的地,插件也很好開發(fā)和部署; 開源 **基于Apache2.0證書  完全開源 ** 可靠高性能 5000多個(gè)數(shù)據(jù)驅(qū)動(dòng)公司的不同產(chǎn)品和服務(wù)依賴fluentd,更好的使用和理解數(shù)據(jù),實(shí)際上,基于datadog的調(diào)查,是使用docker運(yùn)行的排行top7的技術(shù); 一些fluentd用戶實(shí)時(shí)采集上千臺(tái)機(jī)器的數(shù)據(jù),每個(gè)實(shí)例只需要40M左右的內(nèi)存,伸縮的時(shí)候,你可以節(jié)省很多內(nèi)存 社區(qū) fluentd可以改進(jìn)軟件并幫助其它人更好的使用 大公司使用背書: 微軟 , 亞馬遜; pptv ; 
 
 可以結(jié)合elasticSearch + kibana來一起組成日志套件;快速搭建EFK集群并收集應(yīng)用的日志,配置性能排行榜;
 
  elasticsearchElasticsearch 是一個(gè)分布式、RESTful 風(fēng)格的搜索和數(shù)據(jù)分析引擎, 能夠解決不斷涌現(xiàn)出的各種用例。 作為 Elastic Stack 的核心, 它集中存儲(chǔ)您的數(shù)據(jù),幫助您發(fā)現(xiàn)意料之中以及意料之外的情況。 詳細(xì)介紹:https://www./guide/cn/elasticsearch/guide/current/foreword_id.html kibanaKibana 是一款開源的數(shù)據(jù)分析和可視化平臺(tái),它是 Elastic Stack 成員之一, 設(shè)計(jì)用于和 Elasticsearch 協(xié)作。您可以使用 Kibana 對(duì) Elasticsearch 索引中的數(shù)據(jù)進(jìn)行搜索、 查看、交互操作。您可以很方便的利用圖表、表格及地圖對(duì)數(shù)據(jù)進(jìn)行多元化的分析和呈現(xiàn)。 Kibana 可以使大數(shù)據(jù)通俗易懂。它很簡單, 基于瀏覽器的界面便于您快速創(chuàng)建和分享動(dòng)態(tài)數(shù)據(jù)儀表板來追蹤 Elasticsearch 的實(shí)時(shí)數(shù)據(jù)變化. 詳細(xì)介紹:https://www./guide/cn/kibana/current/introduction.html 容器化EFK實(shí)現(xiàn)路徑https://github.com/kayrus/elk-kubernetes 直接拖代碼下來,然后配置后 context, namespace , 即可安裝; cd elk-kubernetes
./deploy.sh --watch
 下面是deploy.sh的腳本,可以簡單看一下: #!/bin/sh
CDIR=$(cd `dirname "$0"` && pwd)
cd "$CDIR"
print_red() {
  printf '%b' "\033[91m$1\033[0m\n"
}
print_green() {
  printf '%b' "\033[92m$1\033[0m\n"
}
render_template() {
  eval "echo \"$(cat "$1")\""
}
KUBECTL_PARAMS="--context=250091890580014312-cc3174dcd4fc14cf781b6fc422120ebd8"
NAMESPACE=${NAMESPACE:-sm}
KUBECTL="kubectl ${KUBECTL_PARAMS} --namespace=\"${NAMESPACE}\""
eval "kubectl ${KUBECTL_PARAMS} create namespace \"${NAMESPACE}\""
#NODES=$(eval "${KUBECTL} get nodes -l 'kubernetes.io/role!=master' -o go-template=\"{{range .items}}{{\\\$name := .metadata.name}}{{\\\$unschedulable := .spec.unschedulable}}{{range .status.conditions}}{{if eq .reason \\\"KubeletReady\\\"}}{{if eq .status \\\"True\\\"}}{{if not \\\$unschedulable}}{{\\\$name}}{{\\\"\\\\n\\\"}}{{end}}{{end}}{{end}}{{end}}{{end}}\"")
NODES=$(eval "${KUBECTL} get nodes -l 'sm.efk=data' -o go-template=\"{{range .items}}{{\\\$name := .metadata.name}}{{\\\$unschedulable := .spec.unschedulable}}{{range .status.conditions}}{{if eq .reason \\\"KubeletReady\\\"}}{{if eq .status \\\"True\\\"}}{{if not \\\$unschedulable}}{{\\\$name}}{{\\\"\\\\n\\\"}}{{end}}{{end}}{{end}}{{end}}{{end}}\"")
ES_DATA_REPLICAS=$(echo "$NODES" | wc -l)
if [ "$ES_DATA_REPLICAS" -lt 3 ]; then
  print_red "Minimum amount of Elasticsearch data nodes is 3 (in case when you have 1 replica shard), you have ${ES_DATA_REPLICAS} worker nodes"
  print_red "Won't deploy more than one Elasticsearch data pod per node exiting..."
  exit 1
fi
print_green "Labeling nodes which will serve Elasticsearch data pods"
for node in $NODES; do
  eval "${KUBECTL} label node ${node} elasticsearch.data=true --overwrite"
done
for yaml in *.yaml.tmpl; do
  render_template "${yaml}" | eval "${KUBECTL} create -f -"
done
for yaml in *.yaml; do
  eval "${KUBECTL} create -f \"${yaml}\""
done
eval "${KUBECTL} create configmap es-config --from-file=es-config --dry-run -o yaml" | eval "${KUBECTL} apply -f -"
eval "${KUBECTL} create configmap fluentd-config --from-file=docker/fluentd/td-agent.conf --dry-run -o yaml" | eval "${KUBECTL} apply -f -"
eval "${KUBECTL} create configmap kibana-config --from-file=kibana.yml --dry-run -o yaml" | eval "${KUBECTL} apply -f -"
eval "${KUBECTL} get pods $@"
 簡單分解一下部署的流程: 
 我的k8s環(huán)境中沒有搭建成功,后續(xù)搭建成功了再出詳細(xì)的安裝筆記。 小結(jié)一句話概括本篇:EFK是一種通過日志代理客戶端采集應(yīng)用日志比較常用的實(shí)現(xiàn)方式。 
 
原創(chuàng)不易,關(guān)注誠可貴,轉(zhuǎn)發(fā)價(jià)更高!轉(zhuǎn)載請(qǐng)注明出處,讓我們互通有無,共同進(jìn)步,歡迎溝通交流。 |