0%

利用开源组件Log-pilot搭建Kubernetes日志解决方案

Log-Pilot

关于 Log-Pilot

Log-Pilot 是一个阿里开源的智能容器日志采集工具,它不仅能够高效便捷地将容器日志采集输出到多种存储日志后端,同时还能够动态地发现和采集容器内部的日志文件。

项目地址是 github.com/AliyunContainerService/log-pilot

阿里介绍 https://help.aliyun.com/document_detail/86552.html

采集模式

传统采集模式中需要在每个 Pod 中起一个专门用来采集日志的容器。在集群规模大的情况下,会造成资源的过多占用。
而Log-Pilot 采用的是 Node 采集模式,这个模式中只需要在每个节点上部署一个专门用来采集此节点上所有容器的日志的 Pod,可以避免资源的浪费。

Log-Pilot 特性

  • 声明式配置

    Log-Pilot 支持声明式日志配置,可以依据容器的 Label 或者 ENV 来动态地生成日志采集配置文件。示例:

    • Label:aliyun.logs.$name=$path
    • ENV:aliyun_logs_$name=$path

    含义:

    • $name:自定义的字符串,不同场景下有不同含义,如
    • 输出到 ElasiticSearch 表示 index
    • 输出到 Kafka 表示 topic
    • $path:表示标准输出日志或者日志路径
    • aliyun_logs_$name=stdout 表示采集容器的标准输出日志
    • aliyun_logs_$name=/usr/local/tomcat/logs/* 表示采集容器的内部日志文件

    如果不想使用 aliyun 这个前缀,还可以在 Log-Pilot 中配置 PILOT_LOG_PREFIX 环境变量来自定义前缀。

    数据自动打标

    Log-Pilot 在 Kubernetes 中采集容器日志的时候,同时也会收集容器的元数据信息:

    • k8s_pod
    • k8s_pod_namespace
    • k8s_node_name
    • k8s_container_name

    多种解析格式

    常用:

    • none:默认格式,指不对日志记录做任何解析,整行采集出来直接输出到日志存储后端
    • json:Log-Pilot 在采集日志的时候同时会将每一行日志以 json 的方式进行解析,解析出多个 KV 对,然后输出到日志存储后端

    需要配置 fluentd 插件:

    • csv:主要是针对csv格式的日志采集配置
    • nginx:主要是针对Nginx的日志采集配置
    • apache2:主要是针对Apache的日志采集配置
    • regexp:用户可以通过 format 标签来自定义正则表达式,告诉 Log-Pilot 在解析日志记录的时候以什么样的拆分格式来进行解析拆分

    自定义输出 target

    格式:aliyun_logs_$name_target=$target
    $target 和 前面的 $name 一样,不同的场景下有不同含义,如

    • 输出到 ElasiticSearch 表示 index
    • 输出到 Kafka 表示 topic

    使用示例:ElasticSearch 场景下,有一个容器在测试环境中定义了 aliyun_logs_svc=stdout ,表示该容器的标准输出日志被采集到 index=svc中。当该容器应用于生产环境中时,可以添加一条 aliyun_logs_svc_target=svc-pro 定义来使标准输出日志被采集到 index=svc-pro 中,而不用去修改原先每条定义的 $name 。

    多插件多后端

    目前 Log-Pilot 支持两种采集插件:一个是CNCF社区的Fluentd插件,一个是Elastic的Filebeat插件;其同时其支持对接多种存储后端,目前 Fluentd 和 Filebeat 都支持 Elasticsearch、Kafka、File、Console 作为日志存储后端,而 Fluentd 还支持 Graylog、阿里云日志服务 以及 Mongodb 作为存储后端。

    其他特性

    • 自动发现机制
    • 句柄保持机制

部署示例

以下部署过程中的集群环境和 YAML 文件仅为展示 Log-Pilot 采集效果,实际部署以具体情况为准。

部署 Log-Pilot

log-pilot.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-pilot
labels:
app: log-pilot
# 设置期望部署的namespace。
namespace: kube-system
spec:
selector:
matchLabels:
app: log-pilot
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: log-pilot
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
spec:
# 是否允许部署到Master节点上tolerations。
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: log-pilot
# 版本请参考https://github.com/AliyunContainerService/log-pilot/releases。
image: registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.6-filebeat
resources:
limits:
memory: 500Mi
requests:
cpu: 200m
memory: 200Mi
env:
- name: "NODE_NAME"
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: "LOGGING_OUTPUT"
value: "elasticsearch"
# 请确保集群到ES网络可达。
- name: "ELASTICSEARCH_HOSTS"
value: "{es_endpoint}:{es_port}"
# 配置ES访问权限。
- name: "ELASTICSEARCH_USER"
value: "{es_username}"
- name: "ELASTICSEARCH_PASSWORD"
value: "{es_password}"
volumeMounts:
- name: sock
mountPath: /var/run/docker.sock
- name: root
mountPath: /host
readOnly: true
- name: varlib
mountPath: /var/lib/filebeat
- name: varlog
mountPath: /var/log/filebeat
- name: localtime
mountPath: /etc/localtime
readOnly: true
livenessProbe:
failureThreshold: 3
exec:
command:
- /pilot/healthz
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
securityContext:
capabilities:
add:
- SYS_ADMIN
terminationGracePeriodSeconds: 30
volumes:
- name: sock
hostPath:
path: /var/run/docker.sock
- name: root
hostPath:
path: /
- name: varlib
hostPath:
path: /var/lib/filebeat
type: DirectoryOrCreate
- name: varlog
hostPath:
path: /var/log/filebeat
type: DirectoryOrCreate
- name: localtime
hostPath:
path: /etc/localtime

log-pilot.yml 自应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: log-pilot
name: filebeat-conf
data:
filebeat.tpl: |-
{{range .configList}}
- type: log
enabled: true
multiline.pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:|^...'
multiline.negate: false
multiline.match: after
paths:
- {{ .HostDir }}/{{ .File }}
scan_frequency: 10s
fields_under_root: true
{{if .Stdout}}
docker-json: true
{{end}}
{{if eq .Format "json"}}
json.keys_under_root: true
{{end}}
fields:
{{range $key, $value := .Tags}}
{{ $key }}: {{ $value }}
{{end}}
{{range $key, $value := $.container}}
{{ $key }}: {{ $value }}
{{end}}
tail_files: false
close_inactive: 2h
close_eof: false
close_removed: true
clean_removed: true
close_renamed: false
{{end}}
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: log-pilot
labels:
k8s-app: log-pilot
spec:
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
k8s-app: log-pilot
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- vpsz-dce-dmp01

containers:
- name: log-pilot
image: 10.0.7.130/toolkit/log-pilot:0.9.6-filebeat
resources:
limits:
cpu: 200m
memory: 1000Mi
env:
- name: "LOGGING_OUTPUT"
value: "logstash"
- name: "LOGSTASH_HOST"
value: "10.0.7.18"
- name: "LOGSTASH_PORT"
value: "5044"
- name: "LOGSTASH_LOADBALANCE"
value: "true"
- name: "NODE_NAME"
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: sock
mountPath: /var/run/docker.sock
- name: logs
mountPath: /var/log/filebeat
- name: state
mountPath: /var/lib/filebeat
- name: root
mountPath: /host
readOnly: true
- name: localtime
mountPath: /etc/localtime
- name: filebeat-tpl
mountPath: /pilot/filebeat.tpl
subPath: filebeat.tpl
securityContext:
capabilities:
add:
- SYS_ADMIN
terminationGracePeriodSeconds: 30
volumes:
- name: sock
hostPath:
path: /var/run/docker.sock
- name: logs
hostPath:
path: /var/log/filebeat
- name: state
hostPath:
path: /var/lib/filebeat
- name: root
hostPath:
path: /
- name: localtime
hostPath:
path: /etc/localtime
- name: filebeat-tpl
configMap:
name: filebeat-conf