背景
傳統項目里面記錄日志大多數都是將日志記錄到日志文件,升級到分布式架構以后,日志開始由文件轉移到elasticsearch(es)中來存儲,達到集中管理。在kubernetes平台里面把日志記錄到es有兩種簡單的方案:
- 容器外記錄。
首先在docker容器里面做掛載,指定一個固定的虛擬機目錄,然后應用程序把日志寫入到這個目錄,虛擬機上開啟logstash服務來收集日志文件,然后把日志傳輸到es,在通過kibana做展示,這種方案也是最傳統的ELK的做法。
優點:應用程序耦合相對較低,使用傳統的日志組件比如log4net就能把日志輸出到文件,對於系統的改造成本來說較低。也沒有語言依賴。
缺點:需要在宿主機上面做很多額外的配置,每增加一台宿主機,這個工作就要重復做一次,需要運維人員參與。 - 容器內記錄。
直接在代碼層面把日志寫入es。
優點:日志在應用層面處理了,不需要虛擬機上做額外的工作。
缺點:日志和應用程序耦合的非常高,每個應用程序都需要單獨的配置,配置有變化都可能導致日志收集失敗。如果一個項目由多種語言開發需要開發各種語言的SDK來支持日志的寫入。
回到我們的標題的問題。有沒有一種方案能夠不依賴日志組件,就單純的把日志輸出到控制台就能記錄日志呢?在應用層面不依賴各種組件,在宿主機上面也不用大量額外的配置就能統一的收集日志呢?答案是有的。
log-pilot
介紹我們今天的主角:log-pilot
log-pilot是阿里雲開發的一款開源的容器日志采集工具,可以直接獲取容器的標准輸入和內部文件日志,在每台機器上都安裝一個log-pilot實例,這樣就能收集整個kubernetes集群的docker容器的日志。該項目地址是 https://github.com/AliyunContainerService/log-pilot
下面我們一步一步將log-pilot部署出來。
阿里雲提供了一些安裝腳本,感興趣的同學可以看腳本源碼
下面的演示基於阿里雲的kubernetes集群
演示
安裝es
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/elasticsearch.yml
部署log-polot
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/log-pilot.yml
因為要在集群所有的機器上面都安裝log-polot,所以要指定
kind: DaemonSet
為了方便展示我們再部署一個kibana
kubectl apply -f https://acs-logging.oss-cn-hangzhou.aliyuncs.com/kibana.yml
a) 要讓kibana能夠外網展示所以還需要配置一個ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kibana-ingress
namespace: kube-system
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: kibana
servicePort: 80
b) 創建成功以后獲取訪問地址
kubectl get ingress -n=kube-system
准備一個應用程序通過logger打印日志,並部署到kubernetes
任意語言應用程序都行,日志輸出到控制台即可,筆者用的的一個dotnet core應用程序
修改這個應用程序的kubernetes編排文件
apiVersion: v1
kind: Pod
metadata:
name: testapi
namespace: default
labels:
name: testapi
spec:
containers:
env:
- name: aliyun_logs_catalina
value: "stdout"
上面配置不是一個真實的編排文件,核心代碼只有這兩句
- name: aliyun_logs_catalina
value: "stdout"
aliyun_logs_catalina=stdout表示要收集容器的 stdout 日志。也可以收集保存到文件的日志,請自行參考官方文檔
訪問kibana,查詢日志
a) 先查看容器內記錄的日志,為正式環境的一部分截圖

b) kibana查詢日志

結語
通過這種方案,能讓我們快速的把整個kubernetes集群內的應用程序日志接入到es,遷移和維護成本非常低,極大提升運維效率。
后記
筆者目前在武漢工作,不知道是否有.net相關的線下組織,主要想推動一下.net在武漢地區的發展,有這方面經驗的朋友可以給我發下私信,非常感謝。
