日志采集工具—VictoriaLogs初體驗
前面我們介紹了 VictoriaMetrics 發(fā)布了其日志解決方案 VictoriaLogs,只是簡單介紹了其特性,但是并沒有介紹其使用方法,本文我們就來體驗下 VictoriaLogs。
VictoriaLogs 是一個日志存儲和查詢的后端,并沒有提供直接的日志采集功能,而是兼容其他常見的日志采集工具,比如 fluentbit、filebeat、logstash 等,這里我們使用 fluentbit 來采集日志。
日志采集
比如現(xiàn)在我們需要采集 Kubernetes 集群的日志,然后將其存入到 VictoriaLogs 中去,我們這里的環(huán)境采用的是 containerd 這種容器運行時,所以在使用的時候需要和 docker 進行區(qū)分,這里我們使用 fluentbit 來采集日志,同樣這里我們也將其部署到我們的 Kubernetes 集群中,完整的部署文件如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: monitor
labels:
k8s-app: fluentbit-logging
kubernetes.io/cluster-service: "true"
data:
fluent-bit.conf: |
[SERVICE]
Flush 1
Log_Level info
Daemon off
Parsers_File parsers.conf
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_Port 2020
@INCLUDE input-kubernetes.conf
@INCLUDE filter-kubernetes.conf
@INCLUDE output.conf
output.conf: |
# [OUTPUT]
# Name stdout
# Match kube.var.log.containers.*.*
[OUTPUT]
Name http
Match kube.var.log.containers.*.*
host victorialogs
port 9428
compress gzip
uri /insert/jsonline?_stream_fields=stream&_msg_field=message&_time_field=time
format json_lines
json_date_format iso8601
header AccountID 0
header ProjectID 0
input-kubernetes.conf: |
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser cri
DB /var/log/flb_kube.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
filter-kubernetes.conf: |
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Kube_Tag_Prefix kube.var.log.containers.
Merge_Log On
Merge_Log_Trim On
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude Off
Annotations Off
Labels On
[FILTER]
Name nest
Match kube.*
Operation lift
Nested_under kubernetes
Add_prefix kubernetes_
[FILTER]
Name nest
Match kube.*
Operation lift
Nested_under kubernetes_labels
Add_prefix kubernetes_labels_
parsers.conf: |
[PARSER]
Name json
Format json
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
Time_Keep Off
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%d %H:%M:%S
Time_Keep Off
[PARSER]
Name cri
Format regex
Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<log>.*)$
Time_Key time
Time_Format %Y-%m-%d %H:%M:%S
---
# fluentbit rbac
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentbit
namespace: monitor
labels:
k8s-app: fluentbit-logging
kubernetes.io/cluster-service: "true"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentbit
namespace: monitor
labels:
k8s-app: fluentbit-logging
kubernetes.io/cluster-service: "true"
rules:
- apiGroups: [""]
resources:
- namespaces
- pods
- pods/log
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "apps"]
resources:
- deployments
- replicasets
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fluentbit
namespace: monitor
labels:
k8s-app: fluentbit-logging
kubernetes.io/cluster-service: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fluentbit
subjects:
- kind: ServiceAccount
name: fluentbit
namespace: monitor
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentbit
namespace: monitor
labels:
k8s-app: fluentbit-logging
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: fluentbit-logging
template:
metadata:
labels:
k8s-app: fluentbit-logging
spec:
serviceAccount: fluentbit
serviceAccountName: fluentbit
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers:
- name: fluentbit
image: cr.fluentbit.io/fluent/fluent-bit:2.1.4
imagePullPolicy: Always
ports:
- containerPort: 2020
volumeMounts:
- name: varlog
mountPath: /var/log
- name: fluent-bit-config
mountPath: /fluent-bit/etc/fluent-bit.conf
subPath: fluent-bit.conf
- name: fluent-bit-config
mountPath: /fluent-bit/etc/input-kubernetes.conf
subPath: input-kubernetes.conf
- name: fluent-bit-config
mountPath: /fluent-bit/etc/filter-kubernetes.conf
subPath: filter-kubernetes.conf
- name: fluent-bit-config
mountPath: /fluent-bit/etc/output.conf
subPath: output.conf
volumes:
- name: varlog
hostPath:
path: /var/log
- name: fluent-bit-config
configMap:
name: fluent-bit-config
首先在 ConfigMap 中我們配置了要采集的日志,日志源路徑為 /var/log/containers/*.log,這是默認的容器日志路徑,我們可以在節(jié)點上去查看,但是需要注意的是該路徑下面的日志只是一個軟連接,真正的日志路徑在 /var/log/pods 下面,所以我們在 fluentbit 的 pod 中需要掛載宿主機的 /var/log 目錄,只掛載 /var/log/containers/ 目錄則無法獲取到真正的日志。
此外我們還為日志打上了 kube.* 標簽,這是為了方便后續(xù)的日志過濾,我們可以根據(jù)標簽來過濾日志進行相應(yīng)的處理。
日志經(jīng)過各種處理后,最重要的就是 OUTPUT 輸出源的配置,在調(diào)試階段我們可以先配置一個 stdout 的輸出源。
[OUTPUT]
Name stdout
Match kube.var.log.containers.*.*
這樣我們就可以通過 fluentbit 的 pod 日志來查看日志是否被采集到了。
如果采集到了,那么我們就可以配置其他的輸出源了,比如 elasticsearch、kafka、redis 等等,當然我們這里是要將日志輸出到 VictoriaLogs 中,所以我們需要配置 VictoriaLogs 的輸出源,如下所示:
[OUTPUT]
Name http
Match kube.var.log.containers.*.*
host victorialogs
port 9428
compress gzip
uri /insert/jsonline?_stream_fields=stream&_msg_field=message&_time_field=time
format json_lines
json_date_format iso8601
header AccountID 0
header ProjectID 0
這里我們配置了 VictoriaLogs 的 host 和 port,其中最重要的是 uri 參數(shù),這個參數(shù)是 VictoriaLogs 的插入接口 /insert/jsonline?_stream_fields=stream&_msg_field=message&,這里我們需要注意的是 uri 參數(shù)中的 _stream_fields、_msg_field、_time_field 這三個參數(shù),這三個參數(shù)是 VictoriaLogs 的插入接口所必須的,其中 _stream_fields 是指定日志流的字段,這里我們指定為 stream,_msg_field 是指定日志內(nèi)容的字段,這里我們指定為 message,_time_field 是指定日志時間的字段,這里我們指定為 time,具體要取什么字段需要根據(jù)我們的日志來決定,這樣我們就可以將日志采集到 VictoriaLogs 中了。當然還有兩個字段 AccountID 和 ProjectID,可以用來區(qū)分不同的租戶,這里我們暫時不用,所以設(shè)置為 0。
直接部署上面的資源清單即可,部署完成后我們可以查看 fluentbit 的 pod 日志,如果日志中沒有報錯,那么就說明我們的 fluentbit 部署成功了,接下來就可以部署 VictoriaLogs 了。
安裝 VictoriaLogs
由于 VictoriaLogs 目前預(yù)覽版本僅僅是一個單節(jié)點的應(yīng)用,所以我們只需要部署一個 Deployment 即可,如下所示:
# deploy victorialogs
apiVersion: apps/v1
kind: Deployment
metadata:
name: victorialogs
namespace: monitor
labels:
app: victorialogs
spec:
selector:
matchLabels:
app: victorialogs
template:
metadata:
labels:
app: victorialogs
spec:
containers:
- name: victorialogs
image: victoriametrics/victoria-logs:latest
# command:
# - -storageDataPath=/vlogs # 指定日志存儲路徑
ports:
- containerPort: 9428
volumeMounts:
- name: logs
mountPath: victoria-logs-data # 默認日志存儲路徑
volumes:
- name: logs
persistentVolumeClaim:
claimName: victorialogs-pvc
---
# deploy victorialogs service
apiVersion: v1
kind: Service
metadata:
name: victorialogs
namespace: monitor
labels:
app: victorialogs
spec:
ports:
- port: 9428
targetPort: 9428
type: NodePort
selector:
app: victorialogs
---
# deploy victorialogs pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: victorialogs-pvc
namespace: monitor
spec:
accessModes:
- ReadWriteOnce
storageClassName: cfsauto
resources:
requests:
storage: 10Gi
這里我們需要注意的是 VictoriaLogs 的存儲路徑,VictoriaLogs 默認的存儲路徑是 victoria-logs-data,可以通過參數(shù) -storageDataPath 進行指定,如果想要持久化日志數(shù)據(jù),則需要將該路徑進行掛載,比如我們這里就指定了一個 PVC 進行關(guān)聯(lián)。另外由于上面 fluentbit 我們輸出到了 VictoriaLogs 的 host 地址為 victorialogs,所以我們還需要創(chuàng)建名為 victorialogs 的 Service 對象將其暴露出去,并且要和 fluentbit 在同一個命名空間下,此外 VictoriaLogs 本身還自帶一個 Web 界面,這里我們通過 NodePort 來對外進行暴露,這樣我們就可以通過 NodeIP:NodePort 來訪問 VictoriaLogs 了。
同樣直接部署上面的資源清單即可,部署完成后我們可以查看 VictoriaLogs 的 pod 日志,如果日志中沒有報錯,那么就說明我們的 VictoriaLogs 部署成功了。
$ kubectl get pods -n monitor
NAME READY STATUS RESTARTS AGE
fluentbit-6rmp8 1/1 Running 0 28m
fluentbit-bbgxb 1/1 Running 0 28m
fluentbit-xwrzs 1/1 Running 0 28m
victorialogs-5856895b4c-mcffw 1/1 Running 0 41m
$ kubectl get svc -n monitor
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
victorialogs NodePort 10.101.31.122 <none> 9428:30694/TCP 48m
部署完成后我們就可以通過 NodeIP:30694 來訪問 VictoriaLogs 如下所示:
點擊 select/vmui 就可以跳轉(zhuǎn)到 VictoriaLogs 的 Logs Explorer 界面了,如下所示:
然后我們就可以根據(jù)自己的需求來進行日志的查詢了,比如查詢?nèi)罩局邪?span> alog
關(guān)鍵字的日志:
此外還有 Table 和 JSON 兩種展示模式:
日志查詢使用的是 VictoriaLogs 的 LogsQL 語法,具體語法可以參考官方文檔: https://docs.victoriametrics.com/VictoriaLogs/LogsQL.html。
目前 VictoriaLogs 還處于預(yù)覽版本,所以還有很多功能沒有完善,只有簡單的日志查詢功能,比如目前還不支持日志的告警,可視化圖表等等功能,但是 VictoriaLogs 的開發(fā)者已經(jīng)在開發(fā)中了,相信很快就會支持了。