將日誌文件轉發到後端存儲裏保存起來json
logging agent
,它通常都會以DaemonSet
的方式運行在節點上,而後將宿主機上的容器日誌目錄掛載進去,最後由logging-agent
把日誌轉發出去。Fluentd
項目做爲宿主機上的logging-agent
,而後把日誌轉發到遠端的ElasticSearch
裏保存起來供未來進行檢索。具體的操做過程官網不少kubernetes
的部署裏,會自動爲你啓用logrotate
,在日誌文件超過10MB的時候自動對日誌文件進行roate操做。如今個人應用pod只有一個容器,它會把日誌輸出到容器裏的/var/log/1.log和2.log這兩個文件裏。這個pod的YAML文件以下所示:後端
apiVersion: v1 kind: Pod metadata: name: counter spec: containers: - name: count image: busybox args: - /bin/sh - -c - > i=0; while true; do echo "$i: $(date)" >> /var/log/1.log; echo "$(date) INFO $i" >> /var/log/2.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
在這種狀況下,你用kubectl logs
命令是看不到應用的任何日誌的。這時咱們就能夠爲這個pod添加兩個sidecar容器,分別將上述兩個日誌文件裏的內容從新以stdout和stderr
的方式輸出來,這個YAML文件的寫法以下:api
apiVersion: v1 kind: Pod metadata: name: counter spec: containers: - name: count image: busybox args: - /bin/sh - -c - > i=0; while true; do echo "$i: $(date)" >> /var/log/1.log; echo "$(date) INFO $i" >> /var/log/2.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log - name: count-log-1 image: busybox args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log'] volumeMounts: - name: varlog mountPath: /var/log - name: count-log-2 image: busybox args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log'] volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
因爲sidecar跟主容器之間是共享Volume的,因此這裏的sidecar方案的額外性能損耗並不高,也就多佔用一點cpu和內存。可是,這時候宿主機上實際會存在兩份相同的日誌文件:一份是應用本身寫入的;另外一份是sidecar的stdout和stderr對應的json文件。這對磁盤是很大的浪費。因此說,除非萬不得已或者應用容器徹底不能修改,不然仍是建議你直接使用方案一,或者直接使用方案三。app
在這種方案裏,你的應用還能夠直接把日誌輸出到固定的文件裏而不是stdout,你的logging-agent還可使用fluentd,後端存儲還能夠是ElasticSearch。只不過,fluentd的輸入源變成了應用的日誌文件。通常來講,咱們會把fluentd的輸入源配置保存在一個ConfigMap裏,以下因此:elasticsearch
apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config data: fluentd.conf: | <source> type tail format none path /var/log/1.log pos_file /var/log/1.log.pos tag count.format1 </source> <source> type tail format none path /var/log/2.log pos_file /var/log/2.log.pos tag count.format2 </source> <match **> type google_cloud </match> 複製代碼
咱們在應用pod的定義裏,就能夠聲明一個Fluentd容器做爲sidecar,專門負責將應用生成的1.log和2.log轉發到ElasticSearch中,這個配置,以下所示:ide
apiVersion: v1 kind: Pod metadata: name: counter spec: containers: - name: count image: busybox args: - /bin/sh - -c - > i=0; while true; do echo "$i: $(date)" >> /var/log/1.log; echo "$(date) 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 volumeMounts: - name: varlog mountPath: /var/log - name: config-volume mountPath: /etc/fluentd-config volumes: - name: varlog emptyDir: {} - name: config-volume configMap: name: fluentd-config
如上所示,這個Fluentd容器使用的輸入源,就是經過引用咱們前面寫的ConfigMap來指定的。這裏用到了Volume來把ConfigMap掛在到Pod裏。post
這種方案部署簡單,而且對宿主機很是友好,可是這個sidecar容器極可能會消耗較多的資源,甚至拖垮應用容器。因爲日誌沒有輸出到stdout上,因此你經過kubectl logs
是看不到日誌信息的。性能
以上,就是k8s最經常使用的三種收集日誌的手段了,綜合對比以上方案,比較建議你將應用日誌輸出到stdout和stderr,而後經過在宿主機上部署logging-agent的方式集中處理日誌、這種方案不但簡單,並且kubectl logs依然可使用,也是官方推薦的一種。google