「隨着 K8s 不斷更新迭代,使用 K8s 日誌系統建設的開發者,逐漸遇到了各種複雜的問題和挑戰。本篇文章中結合作者使用經驗,分析和設計 K8s 日誌收集實踐過程。」
1、回顧
隨着集羣規模不斷擴大,日誌收集問題將一直縈繞在我們耳邊,前段時間我用七篇文章安利了使用 fluentd 及 fluent-bit 好處,具體可以參考如下鏈接:
下面我就直接介紹fluent-bit整體收集架構和插件,如果對整體有不理解的部分,可以參考如上鍊接。
單純的日誌收集解決方案特別多,相對非常成熟,比如 ELK、EFK 等,這裏不在贅述,本文只針對 Kubernetes 中使用 fluent-bit 日誌收集,Kubernetes 下日誌收集相對於之前的物理機或者虛擬機的方式略有不同,很大一部分是因爲 Kubernetes 的擴容和彈性能力。日誌形式種類更多,不僅業務日誌,更要考慮 docker、Kubernetes 等組件日誌。日誌的動態性更強,Kubernetes 集羣中節點宕機導致 Pod 自動轉移、Pod 銷燬、擴容縮容、某些場景提前無法預知。這將導致線上服務出現問題之後,不能集中查看日誌、定位問題所在。
2、集中收集方案介紹
fluent-bit 以 ds 方式運行在各個節點,每個節點一個副本,收集完成後,統一發送到fluentd 進行集中日誌查看。如下圖所示:
DaemonSet 本身能夠保證集羣中所有節點(如果添加約束,可以控制在部分節點上運行)都運行一個 Pod 副本,當有 Node 加入集羣時,也會爲他們新增一個 Pod 。當有 Node 從集羣移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod。通過 Kubernetes DaemonSet 資源的特點,每個節點上運行 fluent-bit,保證每個節點的日誌能夠收集。
3、Kubernetes yaml實踐
3.1、fluent-bit的配置存儲在Kubernetes中ConfigMap中
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
labels:
k8s-app: fluent-bit
data:
# Configuration files: server, input, filters and output
# ======================================================
fluent-bit.conf: |
[SERVICE]
Flush 1
Log_Level info
Daemon off
@INCLUDE input-kubernetes.conf
@INCLUDE output-file.conf
input-kubernetes.conf: |
[INPUT]
Name tail
Path /home/logs/biz/biz*.log
Db /tmp/biz_log.db
Db.sync Full
Tag biz-${NODE_NAME}
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser docker
DB /var/log/flb_kube.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
output-file.conf: |
[OUTPUT]
Name forward
Match *
Host 110.223.1.1
Port 24221
如上利用了Kubernetes 分佈式配置 ConfigMap 的能力,其中 fluent-bit 配置主要分成了三部分;
Service 用於定義 fluent-bit 服務啓動設置;
INPUT 用於定義日誌輸入信息;
OUTPUT 用於定義日誌輸出目的地址,示例中使用了 forward,當然 fluent-bit 本身支持常見數據收集組件,比如:ES、KAFAKA 等。
3.2、 Kubernetes ds文件
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluent-bit
labels:
k8s-app: fluent-bit-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
k8s-app: fluent-bit-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
containers:
- name: fluent-bit
image: fluent/fluent-bit:1.3
imagePullPolicy: IfNotPresent
command: ["/fluent-bit/bin/fluent-bit","-c", "/fluent-bit/etc/fluent-bit.conf"]
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
resources:
requests:
cpu: 5m
memory: 20Mi
limits:
cpu: 60m
memory: 60Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: fluent-bit-config
mountPath: /fluent-bit/etc/
- name: biz-logs
mountPath: /home/logs/
- name: fluent-bit-config
mountPath: /fluent-bit/etc/
terminationGracePeriodSeconds: 10
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: biz-logs
hostPath:
path: /home/logs/
- name: fluent-bit-config
configMap:
name: fluent-bit-config
DaemonSet是Kubernetes中資源對象,在定義過程中有三點需要注意
添加resource,即Kubernetes資源配額,保證服務質量,確保正常情況下日誌的性能消耗不超過整體 CPU 佔用的 5%;
日誌輸出路徑要通過hostpath方式掛載到容器內部,否則將無法收集日誌信息;
env本身用於定義環境變量,根據自身需求,eg : 項目需要獲取具體節點信息,如上ConfigMap所示,甚至需要獲取pod或者容器信息。通過設置 env 可以在 fluent-bit 運行過程中動態獲取環境變量。
4、fluentd 服務端設置
fluentd 安裝使用具體參考:
5、總結:
本文主要介紹了 fluent-bit 通過 DaemonSet 方式運行、各個節點日誌收集存儲、集中的過程。
6、後記
當然只做這些離完成日誌系統的搭建目標差的還很遠,這些只是簡單的把日誌集中起來方便查看,更多是需要規範日誌等級、日誌內容輸出、日誌輸出目標定義等。每臺機器上部署的 DaemonSet fluent-bit 到了單 Agent 瓶頸就會出現問題,可能需要考慮換 Sidecar 、 kafaka 中間件、甚至在打印日誌時就要考慮是否影響性能,當然這都是集羣日誌每天TB級別後需要考慮的問題。
推薦
從Ice到Kubernetes容器技術,微服務架構經歷了什麼?
原創不易,隨手關注或者”在看“,誠摯感謝!