開發者在面對 kubernetes 分佈式集羣下的日誌需求時,經常會感到頭疼,既有容器自身特性的緣由,也有現有日誌採集工具的桎梏,主要包括:node
採集目標多:容器自己的特性致使採集目標多,須要採集容器內日誌、容器 stdout。對於容器內部的文件日誌採集,如今並無一個很好的工具可以去動態發現採集。針對每種數據源都有對應的採集軟件,但缺少一站式的工具。
彈性伸縮難:kubernetes 是分佈式的集羣,服務、環境的彈性伸縮對於日誌採集帶來了很大的困難,沒法像傳統虛擬機環境下那樣,事先配置好日誌的採集路徑等信息,採集的動態性以及數據完整性是很是大的挑戰。nginx
缺少動態配置的能力。目前的採集工具都須要事先手動配置好日誌採集方式和路徑等信息,由於它沒法可以自動感知到容器的生命週期變化或者動態漂移,因此它沒法動態地去配置。
日誌採集重複或丟失的問題。由於如今的一些採集工具基本上是經過 tail 的方式來進行日誌採集的,那麼這裏就可能存在兩個方面的問題:一個是可能致使日誌丟失,好比採集工具在重啓的過程當中,而應用依然在寫日誌,那麼就有可能致使這個窗口期的日誌丟失;而對於這種狀況通常保守的作法就是,默認往前多采集 1M 日誌或 2M 的日誌,那麼這就又會可能引發日誌採集重複的問題。
未明確標記日誌源。由於一個應用可能有不少個容器,輸出的應用日誌也是同樣的,那麼當咱們將全部應用日誌收集到統一日誌存儲後端時,在搜索日誌的時候,咱們就沒法明確這條日誌具體是哪個節點上的哪個應用容器產生的。git
本文檔將介紹一種 Docker 日誌收集工具 log-pilot,結合 Elasticsearch 和 kibana 等工具,造成一套適用於 kubernetes 環境下的一站式日誌解決方案。github
log-Pilot 是一個智能容器日誌採集工具,它不只可以高效便捷地將容器日誌採集輸出到多種存儲日誌後端,同時還可以動態地發現和採集容器內部的日誌文件。apache
針對前面提出的日誌採集難題,log-pilot 經過聲明式配置實現強大的容器事件管理,可同時獲取容器標準輸出和內部文件日誌,解決了動態伸縮問題,此外,log-pilot 具備自動發現機制,CheckPoint 及句柄保持的機制,自動日誌數據打標,有效應對動態配置、日誌重複和丟失以及日誌源標記等問題。json
目前 log-pilot 在 Github 徹底開源,項目地址是 https://github.com/AliyunContainerService/log-pilot 。您能夠深刻了解更多實現原理。後端
Log-Pilot 支持容器事件管理,它可以動態地監聽容器的事件變化,而後依據容器的標籤來進行解析,生成日誌採集配置文件,而後交由採集插件來進行日誌採集。api
在 kubernetes 下,Log-Pilot 能夠依據環境變量 aliyun_logs_$name = $path 動態地生成日誌採集配置文件,其中包含兩個變量:tomcat
$name 是咱們自定義的一個字符串,它在不一樣的場景下指代不一樣的含義,在本場景中,將日誌採集到 ElasticSearch 的時候,這個 $name 表示的是 Index。
另外一個是 $path,支持兩種輸入形式,stdout 和容器內部日誌文件的路徑,對應日誌標準輸出和容器內的日誌文件。
第一種約定關鍵字 stdout 表示的是採集容器的標準輸出日誌,如本例中咱們要採集 tomcat 容器日誌,那麼咱們經過配置標籤 aliyun.logs.catalina=stdout 來採集 tomcat 標準輸出日誌。
第二種是容器內部日誌文件的路徑,也支持通配符的方式,經過配置環境變量 aliyun_logs_access=/usr/local/tomcat/logs/*.log來採集 tomcat 容器內部的日誌。固然若是你不想使用 aliyun 這個關鍵字,Log-Pilot 也提供了環境變量 PILOT_LOG_PREFIX 能夠指定本身的聲明式日誌配置前綴,好比 PILOT_LOG_PREFIX: "aliyun,custom"。bash
此外,Log-Pilot 還支持多種日誌解析格式,經過 aliyun_logs_$name_format=
Log-Pilot 同時支持自定義 tag,咱們能夠在環境變量裏配置 aliyun_logs_$name_tags="K1=V1,K2=V2",那麼在採集日誌的時候也會將 K1=V1 和 K2=V2 採集到容器的日誌輸出中。自定義 tag 可幫助您給日誌產生的環境打上 tag,方便進行日誌統計、日誌路由和日誌過濾。
本文檔採用 node 方式進行部署,經過在每臺機器上部署一個 log-pilot 實例,收集機器上全部 Docker 應用日誌。
該方案跟在每一個 Pod 中都部署一個 logging 容器的模式相比,最明顯的優點就是佔用資源較少,在集羣規模比較大的狀況下表現出的優點越明顯,這也是社區推薦的一種模式。
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/elasticsearch.yml
[root@kube-master log-pilot]# kubectl get svc,sts -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/elasticsearch-api ClusterIP 10.245.246.19 <none> 9200/TCP 83m service/elasticsearch-discovery ClusterIP 10.245.235.227 <none> 9300/TCP 83m service/kibana NodePort 10.245.82.6 <none> 80:31526/TCP 83m NAME READY AGE statefulset.apps/elasticsearch 3/3 83m
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/log-pilot.yml
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/kibana.yml
在 elasticsearch + log-pilot + Kibana 這套日誌工具部署完畢後,如今開始部署一個日誌測試應用 tomcat,來測試日誌是否能正常採集、索引和顯示。
編排模板以下。
[root@kube-master log-pilot]# cat tomcat.yaml apiVersion: v1 kind: Pod metadata: name: tomcat namespace: default labels: name: tomcat spec: containers: - image: tomcat name: tomcat-test volumeMounts: - mountPath: /usr/local/tomcat/logs name: accesslogs env: - name: aliyun_logs_catalina-stdout value: "stdout" - name: aliyun_logs_catalina value: "/usr/local/tomcat/logs/catalina.*.log" - name: aliyun_logs_access value: "/usr/local/tomcat/logs/localhost_access_log.*.txt" volumes: - name: accesslogs emptyDir: {}
omcat 鏡像屬於少數同時使用了 stdout 和文件日誌的 Docker 鏡像,適合本文檔的演示。在上面的編排中,經過在 pod 中定義環境變量的方式,動態地生成日誌採集配置文件,環境變量的具體說明以下:
[root@kube-master log-pilot]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch-api ClusterIP 10.245.246.19 <none> 9200/TCP 89m elasticsearch-discovery ClusterIP 10.245.235.227 <none> 9300/TCP 89m kibana NodePort 10.245.82.6 <none> 80:31526/TCP 89m
單擊左側導航欄中的management ,而後單擊Index Patterns > Create Index Pattern。具體的索引名稱會在 $name變量後綴一個時間字符串,您能夠配合通配符 * 進行建立。本例中使用 $name* 來建立 Index Pattern。
您也能夠執行如下命令,進入 elasticsearch 對應的 pod,在 index 下列出 elasticsearch 的全部索引
[root@kube-master log-pilot]# kubectl get pods -A -l app=es NAMESPACE NAME READY STATUS RESTARTS AGE kube-system elasticsearch-0 1/1 Running 0 87m kube-system elasticsearch-1 1/1 Running 0 86m kube-system elasticsearch-2 1/1 Running 0 85m [root@kube-master log-pilot]# kubectl exec -it elasticsearch-0 -n kube-system -- bash elasticsearch@elasticsearch-0:/usr/share/elasticsearch$ curl 'localhost:9200/_cat/indices?v' health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .kibana uzM03HQiSfapnZXkgq2vWg 1 1 4 0 48.6kb 24.3kb green open catalina-2019.08.29 5EZoJzmPRXS9X4TInJ2oqQ 5 1 44 0 203.8kb 101.9kb green open access-2019.08.29 Q2mtVT2vThSomv9XQmuYjg 5 1 9 0 151.3kb 75.6kb green open catalina-stdout-2019.08.29 VmepvHN6Sq6UvP-RH81Qgw 5 1 44 0 211kb 105.4kb
索引建立完畢後,單擊左側導航欄中的Discover,而後選擇前面建立的 Index,選擇合適的時間段,在搜索欄輸入相關字段,就能夠查詢相關的日誌。
配置nginx 代理到負載均衡的訪問地址 ,nginx配置一層用戶認證,須要密碼輸入, 域名解析再解析到 nginx的代理服務器
具體配置以下: server { listen 8000; server_name localhost; location / { auth_basic "kibana auth"; auth_basic_user_file /etc/nginx/conf.d/.htpasswd; proxy_pass http://192.168.0.139; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } yum install -y httpd (安裝 htpasswd命令) 相似apache建立密碼文件 htpasswd -c /etc/nginx/conf.d/.htpasswd weifeng New password:123456 或者經過openssl passwd [root@test ~]# openssl passwd 12345 [root@test ~]# echo "admin:fIHcRVEKijgoM" > htpasswd [root@test ~]# cat htpasswd admin:fIHcRVEKijgoM nginx -t nginx -s reload