日志采集工具—VictoriaLogs初体验
日志采集工具—VictoriaLogs初体验
作者:阳明 2023-07-07 07:29:53
云计算
云原生 VictoriaLogs 是一个日志存储和查询的后端,并没有提供直接的日志采集功能,而是兼容其他常见的日志采集工具,比如 fluentbit、filebeat、logstash 等,这里我们使用 fluentbit 来采集日志。
前面我们介绍了 VictoriaMetrics 发布了其日志解决方案 VictoriaLogs,只是简单介绍了其特性,但是并没有介绍其使用方法,本文我们就来体验下 VictoriaLogs。
VictoriaLogs 是一个日志存储和查询的后端,并没有提供直接的日志采集功能,而是兼容其他常见的日志采集工具,比如 fluentbit、filebeat、logstash 等,这里我们使用 fluentbit 来采集日志。
日志采集
比如现在我们需要采集 Kubernetes 集群的日志,然后将其存入到 VictoriaLogs 中去,我们这里的环境采用的是 containerd 这种容器运行时,所以在使用的时候需要和 docker 进行区分,这里我们使用 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,这是默认的容器日志路径,我们可以在节点上去查看,但是需要注意的是该路径下面的日志只是一个软连接,真正的日志路径在 /var/log/pods 下面,所以我们在 fluentbit 的 pod 中需要挂载宿主机的 /var/log 目录,只挂载 /var/log/containers/ 目录则无法获取到真正的日志。
此外我们还为日志打上了 kube.* 标签,这是为了方便后续的日志过滤,我们可以根据标签来过滤日志进行相应的处理。
日志经过各种处理后,最重要的就是 OUTPUT 输出源的配置,在调试阶段我们可以先配置一个 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 参数,这个参数是 VictoriaLogs 的插入接口 /insert/jsonline?_stream_fields=stream&_msg_field=message&,这里我们需要注意的是 uri 参数中的 _stream_fields、_msg_field、_time_field 这三个参数,这三个参数是 VictoriaLogs 的插入接口所必须的,其中 _stream_fields 是指定日志流的字段,这里我们指定为 stream,_msg_field 是指定日志内容的字段,这里我们指定为 message,_time_field 是指定日志时间的字段,这里我们指定为 time,具体要取什么字段需要根据我们的日志来决定,这样我们就可以将日志采集到 VictoriaLogs 中了。当然还有两个字段 AccountID 和 ProjectID,可以用来区分不同的租户,这里我们暂时不用,所以设置为 0。
直接部署上面的资源清单即可,部署完成后我们可以查看 fluentbit 的 pod 日志,如果日志中没有报错,那么就说明我们的 fluentbit 部署成功了,接下来就可以部署 VictoriaLogs 了。
安装 VictoriaLogs
由于 VictoriaLogs 目前预览版本仅仅是一个单节点的应用,所以我们只需要部署一个 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,可以通过参数 -storageDataPath 进行指定,如果想要持久化日志数据,则需要将该路径进行挂载,比如我们这里就指定了一个 PVC 进行关联。另外由于上面 fluentbit 我们输出到了 VictoriaLogs 的 host 地址为 victorialogs,所以我们还需要创建名为 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 就可以跳转到 VictoriaLogs 的 Logs Explorer 界面了,如下所示:
然后我们就可以根据自己的需求来进行日志的查询了,比如查询日志中包含 alog
关键字的日志:
此外还有 Table 和 JSON 两种展示模式:
日志查询使用的是 VictoriaLogs 的 LogsQL 语法,具体语法可以参考官方文档: https://docs.victoriametrics.com/VictoriaLogs/LogsQL.html。
目前 VictoriaLogs 还处于预览版本,所以还有很多功能没有完善,只有简单的日志查询功能,比如目前还不支持日志的告警,可视化图表等等功能,但是 VictoriaLogs 的开发者已经在开发中了,相信很快就会支持了。