1. 程式人生 > >如何更優雅的在kubernetes平臺下記錄日誌

如何更優雅的在kubernetes平臺下記錄日誌

背景

傳統專案裡面記錄日誌大多數都是將日誌記錄到日誌檔案,升級到分散式架構以後,日誌開始由檔案轉移到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) 先檢視容器內記錄的日誌,為正式環境的一部分截圖
image

b) kibana查詢日誌
image

結語

通過這種方案,能讓我們快速的把整個kubernetes叢集內的應用程式日誌接入到es,遷移和維護成本非常低,極大提升運維效率。

後記

筆者目前在武漢工作,不知道是否有.net相關的線下組織,主要想推動一下.net在武漢地區的發展,有這方面經驗的朋友可以給我發下私信,非常感謝。