新聞中心
生產(chǎn)中Kubernetes的日志記錄是怎么實(shí)現(xiàn)的
譯文
作者:李睿 2021-11-17 09:00:00
云計(jì)算 人們需要了解生產(chǎn)Kubernetes集群的可擴(kuò)展日志記錄模式,以用于自己的集群級(jí)日志記錄。

【51CTO.com快譯】人們需要了解生產(chǎn)Kubernetes集群的可擴(kuò)展日志記錄模式,以用于自己的集群級(jí)日志記錄。
傳統(tǒng)上,在單體架構(gòu)中,日志直接存儲(chǔ)在裸機(jī)或虛擬機(jī)上,并且從來沒有離開過服務(wù)器磁盤,運(yùn)營團(tuán)隊(duì)將會(huì)根據(jù)需要檢查每個(gè)磁盤的日志。
這適用于內(nèi)部部署的服務(wù)器,而云中的日志是短暫的。隨著越來越多的企業(yè)在容器上運(yùn)行他們的服務(wù),并使用Kubernetes編排部署,日志不必再存儲(chǔ)在服務(wù)器上,因此實(shí)施日志管理策略至關(guān)重要。
日志是調(diào)試和監(jiān)控應(yīng)用程序的有效方法,它們需要存儲(chǔ)在單獨(dú)的后端,以便在Pod或節(jié)點(diǎn)故障時(shí)進(jìn)行查詢和分析。這些獨(dú)立的后端包括Elasticsearch、谷歌云平臺(tái)的Stackdriver和AWS的Cloudwatch等系統(tǒng)。
將集群的日志存儲(chǔ)在存儲(chǔ)后端中稱為集群級(jí)日志記錄。本文將討論企業(yè)如何在自己的Kubernetes集群中實(shí)現(xiàn)這種方法。
日志架構(gòu)
在Kubernetes集群中有兩個(gè)主要的日志源:應(yīng)用程序和系統(tǒng)組件。
應(yīng)用程序作為Kubernetes集群中的容器運(yùn)行,容器運(yùn)行時(shí)負(fù)責(zé)獲取應(yīng)用程序的日志,而Docker將這些日志重定向到stdout( 標(biāo)準(zhǔn)輸出流)和 stderr( 標(biāo)準(zhǔn)輸入流)。在Kubernetes集群中,這兩個(gè)流都被寫入集群節(jié)點(diǎn)上的JSON文件。
可以使用以下命令隨時(shí)獲取這些容器日志:
- kubectl logs podname
日志的另一個(gè)來源是系統(tǒng)組件。一些系統(tǒng)組件(即kube-scheduler和kube-proxy)作為容器運(yùn)行,并遵循與應(yīng)用程序相同的日志記錄原則。
其他系統(tǒng)組件(kubelet和容器運(yùn)行時(shí)本身)作為原生服務(wù)運(yùn)行。如果機(jī)器上的systemd可用,組件會(huì)在journald中寫入日志,否則它們會(huì)在/var/log目錄中寫入.log文件。
現(xiàn)在已經(jīng)了解了應(yīng)用程序和集群的哪些組件生成日志以及它們的存儲(chǔ)位置,接下來看看將這些日志卸載到不同存儲(chǔ)系統(tǒng)的一些常見模式。
日志記錄模式
收集日志的兩個(gè)最突出的模式是DaemonSet模式和Sidecar模式。
(1)DaemonSet模式
在DaemonSet模式中,日志代理通過Kubernetes中的DaemonSet資源部署為Pod。部署DaemonSet可確保集群中的每個(gè)節(jié)點(diǎn)都有一個(gè)運(yùn)行日志代理的Pod。這個(gè)日志代理被配置為從/var/logs目錄讀取日志并將它們發(fā)送到存儲(chǔ)后端。
(2)Sidecar模式
而在Sidecar模式中,一個(gè)專用容器與同一個(gè)Pod中的每個(gè)應(yīng)用程序容器一起運(yùn)行。Sidecar模式可以有兩種類型:Streaming Sidecar或日志代理Sidecar (Logging Agent Sidecar)。
當(dāng)運(yùn)行將日志寫入文件而不是stdout/stderr流的應(yīng)用程序,或以非標(biāo)準(zhǔn)格式寫入日志的應(yīng)用程序時(shí),將使用流Streaming Sidecar。在這種情況下,可以使用Streaming Sidecar容器將文件中的日志發(fā)布到其自己的stdout/stderr流,然后Kubernetes本身可以獲取stdout/stderr流。
Streaming Sidecar還可以通過將日志消息轉(zhuǎn)換為標(biāo)準(zhǔn)日志格式來為日志結(jié)構(gòu)帶來奇偶校驗(yàn)。
另一種方法是日志代理Sidecar,Sidecar本身將日志發(fā)送到存儲(chǔ)后端。每個(gè)Pod都包含一個(gè)日志代理,例如Fluentd或Filebeat,它從應(yīng)用程序容器中捕獲日志并將它們直接發(fā)送到存儲(chǔ)后端。
DaemonSet和Sidecar的優(yōu)缺點(diǎn)
現(xiàn)在已經(jīng)討論了DaemonSet和Sidecar方法,以下了解每種方法的優(yōu)缺點(diǎn)。
(1)DaemonSet(節(jié)點(diǎn)級(jí))
優(yōu)點(diǎn):
- 節(jié)點(diǎn)級(jí)日志更容易實(shí)現(xiàn),因?yàn)樗c現(xiàn)有的基于文件的日志相關(guān),并且由于每個(gè)節(jié)點(diǎn)運(yùn)行的容器較少,因此比Sidecar方法占用的資源更少。
- 日志可通過kubectl命令用于調(diào)試,因?yàn)槿罩疚募捎糜诜祷厝罩疚募?nèi)容的kubelet。
缺點(diǎn):
- 支持寫入日志文件而不是流的不同日志結(jié)構(gòu)或應(yīng)用程序的靈活性較低。需要修改應(yīng)用程序日志結(jié)構(gòu)以實(shí)現(xiàn)奇偶校驗(yàn),或者處理存儲(chǔ)后端中的差異。
- 由于它們作為JSON文件存儲(chǔ)在節(jié)點(diǎn)磁盤上,因此日志不能永久保存。需要有一個(gè)日志輪換機(jī)制來回收舊日志。如果使用的是容器運(yùn)行時(shí)接口,kubelet會(huì)負(fù)責(zé)輪換日志,不需要實(shí)施明確的解決方案。
(2)Sidecar
優(yōu)點(diǎn):
- 可以靈活地為每個(gè)應(yīng)用程序容器定制Sidecar。例如,應(yīng)用程序可能無法寫入stdout/stderr,或者它可能具有某些不同的日志記錄格式。在這些情況下,Sidecar容器可以為系統(tǒng)帶來奇偶校驗(yàn)。
- 如果沒有使用流式傳輸?shù)娜罩敬鞸idecar,則不需要輪換日志,因?yàn)楣?jié)點(diǎn)磁盤上沒有存儲(chǔ)任何日志。
缺點(diǎn):
- 與節(jié)點(diǎn)級(jí)別的Pod相比,為每個(gè)應(yīng)用程序容器運(yùn)行一個(gè)Sidecar非常耗費(fèi)資源。
- 為每個(gè)部署添加一個(gè)Sidecar會(huì)增加額外的復(fù)雜性。
- 如果將Streaming Sidecar用于將其日志寫入文件的應(yīng)用程序,將使用兩倍的存儲(chǔ)空間來存儲(chǔ)相同的日志,因?yàn)閷?huì)復(fù)制條目。
- 如果沒有使用流式傳輸?shù)娜罩敬鞸idecar,將無法通過kubectl訪問日志。這是因?yàn)閗ubelet不再有權(quán)訪問JSON日志。
- 使用日志代理Sidecar,還需要一個(gè)節(jié)點(diǎn)級(jí)代理,否則將無法收集系統(tǒng)組件日志。
將理論付諸實(shí)踐
現(xiàn)在已經(jīng)了解了登錄Kubernetes集群的可能模式,可以付諸實(shí)踐,部署生成日志的虛擬容器,并創(chuàng)建Kubernetes資源來實(shí)現(xiàn)上面討論的日志記錄模式。
在這個(gè)例子中,將使用Fluentd作為日志代理,將安裝Elasticsearch用于日志記錄后端和Kibana用于可視化目的。將使用Helm圖表將Elasticsearch和Kibana安裝到同一個(gè)集群中。但是需要注意的是,存儲(chǔ)后端不應(yīng)位于同一個(gè)集群上,這樣做僅用于演示目的。由于Fluentd的可插拔架構(gòu),它支持各種不同的接收器。這就是Elasticsearch后端可以被任何云原生解決方案替換的原因,包括Stackdriver或Cloudwatch。
(1)安裝Elasticsearch和Kibana
將使用找到的官方Helm圖表部署Elasticsearch和Kibana(Elasticsearch、Kibana)。要通過Helm安裝,在路徑上需要一個(gè)Helm二進(jìn)制文件,但Helm的安裝不在本文討論范圍之內(nèi)。
讓我們從添加helm repos開始。
Properties files
1 helm repo add elastic https://helm.elastic.co
接下來,將把Elasticsearch和Kibana圖表安裝到集群中。
Properties files
1 helm install elasticsearch elastic/elasticsearch
2 helm install kibana elastic/kibana
這將在集群中安裝最新版本的Elasticsearch和Kibana,然后可以將其用作日志的存儲(chǔ)后端。
在圖表中使用了默認(rèn)值,但是在生產(chǎn)中安裝它時(shí),可以根據(jù)需要更改任何參數(shù)。
(2)DaemonSet
在這里將Fluentd部署為DaemonSet,而不會(huì)創(chuàng)建單獨(dú)的Service Account和ClusterRole。但在生產(chǎn)環(huán)境中,F(xiàn)luentdpod應(yīng)該使用訪問受限的單獨(dú)服務(wù)帳戶運(yùn)行。
可以使用以下Kubernetes資源將Fluentd部署為DaemonSet:
Go
- api Version: extensions/v1beta1
- kind: DaemonSet
- metadata:
- name: fluentd
- namespace: kube-system
- labels:
- k8s-app: fluentd-logger
- spec:
- template:
- metadata:
- labels:
- k8s-app: fluentd-logger
- spec:
- containers:
- - name: fluentd
- image: fluent/fluentd-kubernetes-daemonset:elasticsearch
- env:
- - name: FLUENT\_ELASTICSEARCH\_HOST
- value: "elasticsearch-master"
- - name: FLUENT\_ELASTICSEARCH\_PORT
- value: "9200"
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- - name: dockerlogs
- mountPath: /var/lib/docker/containers
- readOnly: true
- volumes:
- - name: varlog
- hostPath:
- path: /var/log
- - name: dockerlogs
- hostPath:
- path: /var/lib/docker/containers
在這個(gè)例子中,掛載了兩個(gè)卷:一個(gè)在/var/log,另一個(gè)在/var/log/docker/containers,系統(tǒng)組件和Docker運(yùn)行時(shí)分別放置日志。
正在使用的映像已經(jīng)配置了智能默認(rèn)值以與DaemonSet一起使用,但可以更改配置。
將上述YAML資源保存在名為fluentd-ds.yaml的文件中,并通過以下命令應(yīng)用該資源:
Properties files
- kubectl apply -f fluentd-ds.yaml
這將在Kubernetes集群中的每個(gè)節(jié)點(diǎn)上啟動(dòng)一個(gè)Fluentdpod。
現(xiàn)在將看到如何實(shí)現(xiàn)流和日志代理Sidecar模式。
(3)Sidecar
首先,看看當(dāng)應(yīng)用程序?qū)⑷罩緦懭胛募皇菙?shù)據(jù)流時(shí)的Streaming Sidecar模式??梢赃\(yùn)行一個(gè)Sidecar來讀取這些日志,并將其寫回stdout/stderr流。
Go
- apiVersion: v1
- kind: Pod
- metadata:
- name: my-app
- spec:
- containers:
- - name: legacy-app
- image: busybox
- args:
- - /bin/sh
- - -c
- - >
- i=0;
- while true;
- do
- echo "$i: $(date)" >> /var/log/output.log;
- i=$((i+1));
- sleep 1;
- done
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- - name: streaming-Sidecar
- image: busybox
- args: \[/bin/sh, -c, 'tail -n+1 -f /var/log/output.log'\]
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- volumes:
- - name: varlog
- emptyDir: {}
在這個(gè)例子中,有一個(gè)虛擬容器將日志寫入容器的/var/log目錄中的文件?,F(xiàn)在,容器運(yùn)行時(shí)無法獲取這些日志,這就是實(shí)現(xiàn)了一個(gè)Streaming Sidecar來從/var/log位置跟蹤日志并將其重定向到stdout流。
這一日志流將由容器運(yùn)行時(shí)獲取并作為JSON文件存儲(chǔ)在節(jié)點(diǎn)上的/var/log目錄中,節(jié)點(diǎn)級(jí)日志代理然后將獲取該文件。
現(xiàn)在看看日志代理Sidecar。在這種模式中,將Fluentd部署為Sidecar,它將直接寫入Elasticsearch存儲(chǔ)后端。
在此沒有安裝Elasticsearch插件的預(yù)構(gòu)建鏡像,而創(chuàng)建自定義Docker鏡像超出了本文討論的范圍。與其相反,將使用在DaemonSet示例中使用的相同F(xiàn)luentd映像。
Go
- apiVersion: v1
- kind: Pod
- metadata:
- name: my-app
- spec:
- containers:
- - name: count
- image: busybox
- args:
- - /bin/sh
- - -c
- - >
- i=0;
- while true;
- do
- echo "$i: $(date)" >> /var/log/output.log;
- i=$((i+1));
- sleep 1;
- done
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- - name: logging-agent
- image: fluent/fluentd-kubernetes-daemonset:elasticsearch
- env:
- - name: FLUENT\_ELASTICSEARCH\_HOST
- value: "elastisearch-master"
- - name: FLUENT\_ELASTICSEARCH\_PORT
- value: "9200"
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- volumes:
- - name: varlog
- emptyDir: {}
結(jié)論
鑒于Pod和節(jié)點(diǎn)的短暫性,將來自Kubernetes集群的日志存儲(chǔ)在單獨(dú)的存儲(chǔ)后端中非常重要??梢允褂枚喾N模式來設(shè)置在本文中討論的日志記錄架構(gòu)。
在此建議為生產(chǎn)系統(tǒng)混合使用Sidecar和節(jié)點(diǎn)級(jí)模式。這包括使用DaemonSet模式設(shè)置集群范圍的節(jié)點(diǎn)級(jí)日志記錄,以及為不支持將日志寫入流(stdout/stderr)或不以標(biāo)準(zhǔn)日志格式寫入的應(yīng)用程序?qū)崿F(xiàn)Streaming Sidecar容器。這個(gè)流容器將自動(dòng)顯示要選取的節(jié)點(diǎn)級(jí)代理的日志。
對(duì)于存儲(chǔ)后端的選擇,可以選擇自托管的開源解決方案,例如Elasticsearch,或者可以使用云托管的Elasticsearch、Stackdriver以及Cloudwatch等選項(xiàng)選擇托管服務(wù)路線。選擇適合后端將取決于希望在架構(gòu)中實(shí)現(xiàn)的成本、查詢和日志分析要求。
原文標(biāo)題:Kubernetes Logging in Production,作者:Kentaro Wakayama
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】
網(wǎng)頁名稱:生產(chǎn)中Kubernetes的日志記錄是怎么實(shí)現(xiàn)的
瀏覽地址:http://www.dlmjj.cn/article/cdipoos.html


咨詢
建站咨詢
