Filebeat Kubernetes 处理器和过滤
Filebeat Kubernetes Processor and filtering
我正在尝试使用 Filebeat 将我的 K8s pod 日志发送到 Elasticsearch。
我正在按照此处的在线指南进行操作:https://www.elastic.co/guide/en/beats/filebeat/6.0/running-on-kubernetes.html
一切都按预期工作,但我想从系统 pods 中过滤掉事件。我的更新配置如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-prospectors
namespace: kube-system
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
data:
kubernetes.yml: |-
- type: log
paths:
- /var/lib/docker/containers/*/*.log
multiline.pattern: '^\s'
multiline.match: after
json.message_key: log
json.keys_under_root: true
processors:
- add_kubernetes_metadata:
in_cluster: true
namespace: ${POD_NAMESPACE}
- drop_event.when.regexp:
or:
kubernetes.pod.name: "weave-net.*"
kubernetes.pod.name: "external-dns.*"
kubernetes.pod.name: "nginx-ingress-controller.*"
kubernetes.pod.name: "filebeat.*"
我试图通过以下方式忽略 weave-net
、external-dns
、ingress-controller
和 filebeat
事件:
- drop_event.when.regexp:
or:
kubernetes.pod.name: "weave-net.*"
kubernetes.pod.name: "external-dns.*"
kubernetes.pod.name: "nginx-ingress-controller.*"
kubernetes.pod.name: "filebeat.*"
但是他们继续到达 Elasticsearch。
我正在使用一种不同的方法,该方法在日志记录管道中传输的日志数量方面效率较低。
与您的做法类似,我使用守护程序集在我的节点上部署了一个 filebeat 实例。这里没什么特别的,这是我使用的配置:
apiVersion: v1
data:
filebeat.yml: |-
filebeat.config:
prospectors:
# Mounted `filebeat-prospectors` configmap:
path: ${path.config}/prospectors.d/*.yml
# Reload prospectors configs as they change:
reload.enabled: false
modules:
path: ${path.config}/modules.d/*.yml
# Reload module configs as they change:
reload.enabled: false
processors:
- add_cloud_metadata:
output.logstash:
hosts: ['logstash.elk.svc.cluster.local:5044']
kind: ConfigMap
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat-config
这是给探矿者的:
apiVersion: v1
data:
kubernetes.yml: |-
- type: log
paths:
- /var/lib/docker/containers/*/*.log
json.message_key: log
json.keys_under_root: true
processors:
- add_kubernetes_metadata:
in_cluster: true
namespace: ${POD_NAMESPACE}
kind: ConfigMap
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat-prospectors
Daemonset 规范:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat
spec:
selector:
matchLabels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
command:
- /usr/share/filebeat/filebeat
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
image: docker.elastic.co/beats/filebeat:6.0.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/prospectors.d
name: prospectors
readOnly: true
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- configMap:
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- configMap:
defaultMode: 384
name: filebeat-prospectors
name: prospectors
- emptyDir: {}
name: data
基本上,来自所有容器的所有日志的所有数据都被转发到 logstash,可在服务端点访问:logstash.elk.svc.cluster.local:5044
(在 "elk" 命名空间中称为 "logstash" 的服务)。
为简洁起见,我将只为您提供 logstash 的配置(如果您需要更具体的 kubernetes 帮助,请在评论中提问):
logstash.yml 文件非常基础:
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
只是表示我挂载管道配置文件的目录的挂载点,如下:
10-beats.conf:
为 filebeat 声明一个输入(必须使用名为 "logstash" 的服务公开端口 5044)
input {
beats {
port => 5044
ssl => false
}
}
49-过滤器-logs.conf:
此过滤器基本上会删除来自 pods 且没有 "elk" 标签的日志。对于确实具有 "elk" 标签的 pods,它保留来自 pod 的 "elk" 标签中命名的容器的日志。例如,如果一个 Pod 有两个容器,分别称为 "nginx" 和 "python",将标签 "elk" 的值为 "nginx" 将只保留来自 nginx 容器的日志并丢弃python 个。日志的类型设置为 pod 所在的命名空间 运行。
这可能不适合所有人(您将在 elasticsearch 中为属于命名空间的所有日志创建一个索引)但它对我有用,因为我的日志是同源的。
filter {
if ![kubernetes][labels][elk] {
drop {}
}
if [kubernetes][labels][elk] {
# check if kubernetes.labels.elk contains this container name
mutate {
split => { "kubernetes[labels][elk]" => "." }
}
if [kubernetes][container][name] not in [kubernetes][labels][elk] {
drop {}
}
mutate {
replace => { "@metadata[type]" => "%{kubernetes[namespace]}" }
remove_field => [ "beat", "host", "kubernetes[labels][elk]", "kubernetes[labels][pod-template-hash]", "kubernetes[namespace]", "kubernetes[pod][name]", "offset", "prospector[type]", "source", "stream", "time" ]
rename => { "kubernetes[container][name]" => "container" }
rename => { "kubernetes[labels][app]" => "app" }
}
}
}
其余配置与日志解析有关,与此上下文无关。
唯一重要的部分是输出:
99-output.conf:
向elasticsearch发送数据:
output {
elasticsearch {
hosts => ["http://elasticsearch.elk.svc.cluster.local:9200"]
manage_template => false
index => "%{[@metadata][type]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
希望你明白了。
这种方法的优点
- 一旦部署了filebeat和logstash,只要不需要解析新类型的日志,就不需要更新filebeat和logstash的配置来获取kibana中的新日志。您只需要在广告连播模板中添加标签即可。
- 默认情况下会删除所有日志文件,只要您没有明确放置标签。
这种方法的缺点
- 来自所有 pods 的所有日志都通过 filebeat 和 logstash,并且仅在 logstash 中被删除。这对 logstash 来说是很多工作,并且可能会消耗资源,具体取决于集群中 pods 的数量。
我确信这个问题有更好的方法,但我认为这个解决方案非常方便,至少对于我的用例而言。
条件需要是列表:
- drop_event.when.regexp:
or:
- kubernetes.pod.name: "weave-net.*"
- kubernetes.pod.name: "external-dns.*"
- kubernetes.pod.name: "nginx-ingress-controller.*"
- kubernetes.pod.name: "filebeat.*"
我不确定你的参数顺序是否有效。我的一个工作示例如下所示:
- drop_event:
when:
or:
# Exclude traces from Zipkin
- contains.path: "/api/v"
# Exclude Jolokia calls
- contains.path: "/jolokia/?"
# Exclude pinging metrics
- equals.path: "/metrics"
# Exclude pinging health
- equals.path: "/health"
这在 filebeat 6.1.3 中对我有用
- drop_event.when:
or:
- equals:
kubernetes.container.name: "filebeat"
- equals:
kubernetes.container.name: "prometheus-kube-state-metrics"
- equals:
kubernetes.container.name: "weave-npc"
- equals:
kubernetes.container.name: "nginx-ingress-controller"
- equals:
kubernetes.container.name: "weave"
我正在尝试使用 Filebeat 将我的 K8s pod 日志发送到 Elasticsearch。
我正在按照此处的在线指南进行操作:https://www.elastic.co/guide/en/beats/filebeat/6.0/running-on-kubernetes.html
一切都按预期工作,但我想从系统 pods 中过滤掉事件。我的更新配置如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-prospectors
namespace: kube-system
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
data:
kubernetes.yml: |-
- type: log
paths:
- /var/lib/docker/containers/*/*.log
multiline.pattern: '^\s'
multiline.match: after
json.message_key: log
json.keys_under_root: true
processors:
- add_kubernetes_metadata:
in_cluster: true
namespace: ${POD_NAMESPACE}
- drop_event.when.regexp:
or:
kubernetes.pod.name: "weave-net.*"
kubernetes.pod.name: "external-dns.*"
kubernetes.pod.name: "nginx-ingress-controller.*"
kubernetes.pod.name: "filebeat.*"
我试图通过以下方式忽略 weave-net
、external-dns
、ingress-controller
和 filebeat
事件:
- drop_event.when.regexp:
or:
kubernetes.pod.name: "weave-net.*"
kubernetes.pod.name: "external-dns.*"
kubernetes.pod.name: "nginx-ingress-controller.*"
kubernetes.pod.name: "filebeat.*"
但是他们继续到达 Elasticsearch。
我正在使用一种不同的方法,该方法在日志记录管道中传输的日志数量方面效率较低。
与您的做法类似,我使用守护程序集在我的节点上部署了一个 filebeat 实例。这里没什么特别的,这是我使用的配置:
apiVersion: v1
data:
filebeat.yml: |-
filebeat.config:
prospectors:
# Mounted `filebeat-prospectors` configmap:
path: ${path.config}/prospectors.d/*.yml
# Reload prospectors configs as they change:
reload.enabled: false
modules:
path: ${path.config}/modules.d/*.yml
# Reload module configs as they change:
reload.enabled: false
processors:
- add_cloud_metadata:
output.logstash:
hosts: ['logstash.elk.svc.cluster.local:5044']
kind: ConfigMap
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat-config
这是给探矿者的:
apiVersion: v1
data:
kubernetes.yml: |-
- type: log
paths:
- /var/lib/docker/containers/*/*.log
json.message_key: log
json.keys_under_root: true
processors:
- add_kubernetes_metadata:
in_cluster: true
namespace: ${POD_NAMESPACE}
kind: ConfigMap
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat-prospectors
Daemonset 规范:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
name: filebeat
spec:
selector:
matchLabels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
k8s-app: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
command:
- /usr/share/filebeat/filebeat
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
image: docker.elastic.co/beats/filebeat:6.0.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/prospectors.d
name: prospectors
readOnly: true
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- configMap:
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- configMap:
defaultMode: 384
name: filebeat-prospectors
name: prospectors
- emptyDir: {}
name: data
基本上,来自所有容器的所有日志的所有数据都被转发到 logstash,可在服务端点访问:logstash.elk.svc.cluster.local:5044
(在 "elk" 命名空间中称为 "logstash" 的服务)。
为简洁起见,我将只为您提供 logstash 的配置(如果您需要更具体的 kubernetes 帮助,请在评论中提问):
logstash.yml 文件非常基础:
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
只是表示我挂载管道配置文件的目录的挂载点,如下:
10-beats.conf: 为 filebeat 声明一个输入(必须使用名为 "logstash" 的服务公开端口 5044)
input {
beats {
port => 5044
ssl => false
}
}
49-过滤器-logs.conf: 此过滤器基本上会删除来自 pods 且没有 "elk" 标签的日志。对于确实具有 "elk" 标签的 pods,它保留来自 pod 的 "elk" 标签中命名的容器的日志。例如,如果一个 Pod 有两个容器,分别称为 "nginx" 和 "python",将标签 "elk" 的值为 "nginx" 将只保留来自 nginx 容器的日志并丢弃python 个。日志的类型设置为 pod 所在的命名空间 运行。 这可能不适合所有人(您将在 elasticsearch 中为属于命名空间的所有日志创建一个索引)但它对我有用,因为我的日志是同源的。
filter {
if ![kubernetes][labels][elk] {
drop {}
}
if [kubernetes][labels][elk] {
# check if kubernetes.labels.elk contains this container name
mutate {
split => { "kubernetes[labels][elk]" => "." }
}
if [kubernetes][container][name] not in [kubernetes][labels][elk] {
drop {}
}
mutate {
replace => { "@metadata[type]" => "%{kubernetes[namespace]}" }
remove_field => [ "beat", "host", "kubernetes[labels][elk]", "kubernetes[labels][pod-template-hash]", "kubernetes[namespace]", "kubernetes[pod][name]", "offset", "prospector[type]", "source", "stream", "time" ]
rename => { "kubernetes[container][name]" => "container" }
rename => { "kubernetes[labels][app]" => "app" }
}
}
}
其余配置与日志解析有关,与此上下文无关。 唯一重要的部分是输出:
99-output.conf: 向elasticsearch发送数据:
output {
elasticsearch {
hosts => ["http://elasticsearch.elk.svc.cluster.local:9200"]
manage_template => false
index => "%{[@metadata][type]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
希望你明白了。
这种方法的优点
- 一旦部署了filebeat和logstash,只要不需要解析新类型的日志,就不需要更新filebeat和logstash的配置来获取kibana中的新日志。您只需要在广告连播模板中添加标签即可。
- 默认情况下会删除所有日志文件,只要您没有明确放置标签。
这种方法的缺点
- 来自所有 pods 的所有日志都通过 filebeat 和 logstash,并且仅在 logstash 中被删除。这对 logstash 来说是很多工作,并且可能会消耗资源,具体取决于集群中 pods 的数量。
我确信这个问题有更好的方法,但我认为这个解决方案非常方便,至少对于我的用例而言。
条件需要是列表:
- drop_event.when.regexp:
or:
- kubernetes.pod.name: "weave-net.*"
- kubernetes.pod.name: "external-dns.*"
- kubernetes.pod.name: "nginx-ingress-controller.*"
- kubernetes.pod.name: "filebeat.*"
我不确定你的参数顺序是否有效。我的一个工作示例如下所示:
- drop_event:
when:
or:
# Exclude traces from Zipkin
- contains.path: "/api/v"
# Exclude Jolokia calls
- contains.path: "/jolokia/?"
# Exclude pinging metrics
- equals.path: "/metrics"
# Exclude pinging health
- equals.path: "/health"
这在 filebeat 6.1.3 中对我有用
- drop_event.when:
or:
- equals:
kubernetes.container.name: "filebeat"
- equals:
kubernetes.container.name: "prometheus-kube-state-metrics"
- equals:
kubernetes.container.name: "weave-npc"
- equals:
kubernetes.container.name: "nginx-ingress-controller"
- equals:
kubernetes.container.name: "weave"