1. deploy 文件
curl -L -O https://raw.githubusercontent.com/elastic/beats/8.14/deploy/kubernetes/filebeat-kubernetes.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: filebeatnamespace: kube-systemlabels:k8s-app: filebeat
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: filebeatlabels:k8s-app: filebeat
rules:
- apiGroups: [""] # "" indicates the core API groupresources:- namespaces- pods- nodesverbs:- get- watch- list
- apiGroups: ["apps"]resources:- replicasetsverbs: ["get", "list", "watch"]
- apiGroups: ["batch"]resources:- jobsverbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: filebeat# should be the namespace where filebeat is runningnamespace: kube-systemlabels:k8s-app: filebeat
rules:- apiGroups:- coordination.k8s.ioresources:- leasesverbs: ["get", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: filebeat-kubeadm-confignamespace: kube-systemlabels:k8s-app: filebeat
rules:- apiGroups: [""]resources:- configmapsresourceNames:- kubeadm-configverbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: filebeat
subjects:
- kind: ServiceAccountname: filebeatnamespace: kube-system
roleRef:kind: ClusterRolename: filebeatapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: filebeatnamespace: kube-system
subjects:- kind: ServiceAccountname: filebeatnamespace: kube-system
roleRef:kind: Rolename: filebeatapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: filebeat-kubeadm-confignamespace: kube-system
subjects:- kind: ServiceAccountname: filebeatnamespace: kube-system
roleRef:kind: Rolename: filebeat-kubeadm-configapiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ConfigMap
metadata:name: filebeat-confignamespace: kube-systemlabels:k8s-app: filebeat
data:filebeat.yml: |-filebeat.inputs:- type: filestreamid: kubernetes-container-logspaths:- /var/log/containers/*.logparsers:- container: ~prospector:scanner:fingerprint.enabled: truesymlinks: truefile_identity.fingerprint: ~processors:- add_kubernetes_metadata:host: ${NODE_NAME}matchers:- logs_path:logs_path: "/var/log/containers/"# To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:# filebeat.autodiscover:# providers:# - type: kubernetes# node: ${NODE_NAME}# hints.enabled: true# hints.default_config:# type: filestream# id: kubernetes-container-logs-${data.kubernetes.pod.name}-${data.kubernetes.container.id}# paths:# - /var/log/containers/*-${data.kubernetes.container.id}.log# parsers:# - container: ~# prospector:# scanner:# fingerprint.enabled: true# symlinks: true# file_identity.fingerprint: ~processors:- add_cloud_metadata:- add_host_metadata:cloud.id: ${ELASTIC_CLOUD_ID}cloud.auth: ${ELASTIC_CLOUD_AUTH}output.elasticsearch:hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']username: ${ELASTICSEARCH_USERNAME}password: ${ELASTICSEARCH_PASSWORD}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:name: filebeatnamespace: kube-systemlabels:k8s-app: filebeat
spec:selector:matchLabels:k8s-app: filebeattemplate:metadata:labels:k8s-app: filebeatspec:serviceAccountName: filebeatterminationGracePeriodSeconds: 30hostNetwork: truednsPolicy: ClusterFirstWithHostNetcontainers:- name: filebeatimage: docker.elastic.co/beats/filebeat:8.14.1args: ["-c", "/etc/filebeat.yml","-e",]env:- name: ELASTICSEARCH_HOSTvalue: elasticsearch- name: ELASTICSEARCH_PORTvalue: "9200"- name: ELASTICSEARCH_USERNAMEvalue: elastic- name: ELASTICSEARCH_PASSWORDvalue: changeme- name: ELASTIC_CLOUD_IDvalue:- name: ELASTIC_CLOUD_AUTHvalue:- name: NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeNamesecurityContext:runAsUser: 0# If using Red Hat OpenShift uncomment this:#privileged: trueresources:limits:memory: 200Mirequests:cpu: 100mmemory: 100MivolumeMounts:- name: configmountPath: /etc/filebeat.ymlreadOnly: truesubPath: filebeat.yml- name: datamountPath: /usr/share/filebeat/data- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: true- name: varlogmountPath: /var/logreadOnly: truevolumes:- name: configconfigMap:defaultMode: 0640name: filebeat-config- name: varlibdockercontainershostPath:path: /var/lib/docker/containers- name: varloghostPath:path: /var/log# data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart- name: datahostPath:# When filebeat runs as non-root user, this directory needs to be writable by group (g+w).path: /var/lib/filebeat-datatype: DirectoryOrCreate
---
2. 配置
默认情况下,Filebeat会将事件发送到现有的Elasticsearch部署(如果存在)。要指定不同的目标,请更改清单文件中的以下参数:
- name: ELASTICSEARCH_HOSTvalue: elasticsearch
- name: ELASTICSEARCH_PORTvalue: "9200"
- name: ELASTICSEARCH_USERNAMEvalue: elastic
- name: ELASTICSEARCH_PASSWORDvalue: changeme
3. 在控制平面节点上运行Filebeat
Kubernetes控制平面节点可以使用污点来限制可以在其上运行的工作负载。要在控制平面节点上运行Filebeat,您可能需要更新Daemoset规范以包括适当的容忍度:
spec:tolerations:- key: node-role.kubernetes.io/control-planeeffect: NoSchedule
4. Deploy
要部署 Filebeat 到 Kubernetes 中,执行如下命令
kubectl apply -f filebeat-kubernetes.yaml
默认 Filebeat 以 DaemonSet 方式部署在 kube-system 名称空间
kubectl --namespace=kube-system get ds/filebeat
日志事件应该开始流向Elasticsearch。事件用 add_kubernetes_medata
处理器添加的元数据进行注释。
5. 解析json日志
从运行在Kubernetes上的工作负载收集日志时,这些应用程序以json格式进行日志记录是很常见的情况。在这种情况下,可以应用特殊处理,以便正确解析这些json日志并将其解码为字段。Bellow提供了两种不同的方式来配置filebeat的自动发现,以便识别和解析json日志。我们将使用一个带有两个容器的Pod的示例,其中只有一个日志是json格式的。
示例日志:
{"type":"log","@timestamp":"2020-11-16T14:30:13+00:00","tags":["warning","plugins","licensing"],"pid":7,"message":"License information could not be obtained from Elasticsearch due to Error: No Living connections error"}
- 将
json.*
选项与模板一起使用
filebeat.autodiscover:providers:- type: kubernetesnode: ${NODE_NAME}templates:- condition: # 条件contains: # 包含kubernetes.container.name: "no-json-logging"config:- type: containerpaths:- "/var/log/containers/*-${data.kubernetes.container.id}.log"- condition:contains:kubernetes.container.name: "json-logging"config:- type: containerpaths:- "/var/log/containers/*-${data.kubernetes.container.id}.log"json.keys_under_root: truejson.add_error_key: truejson.message_key: message
- 使用带有
hints
的json.*
选项
这里的关键部分是正确地注释Pod,以仅将正确容器的日志解析为json日志。在这种情况下,注释(annotation )应该这样构造:
co.elastic.logs.<container_name>/json.keys_under_root: "true"
Autodiscovery configuration:
filebeat.autodiscover:providers:- type: kubernetesnode: ${NODE_NAME}hints.enabled: truehints.default_config:type: containerpaths:- /var/log/containers/*${data.kubernetes.container.id}.log
然后对 Pod 进行注释
annotations:co.elastic.logs.json-logging/json.keys_under_root: "true"co.elastic.logs.json-logging/json.add_error_key: "true"co.elastic.logs.json-logging/json.message_key: "message"
6. 处理器 processors
6.1. add_kubernetes_metadata
add_kubernetes_metadata 处理器根据事件源自哪个kubernetes pod,用相关元数据对每个事件进行注释。在启动时,它检测一个 in_cluster
环境并缓存与Kubernetes相关的元数据。只有在检测到有效配置时,才会对事件进行注释。如果无法检测到有效的Kubernetes配置,则不会使用与Kubernete相关的元数据对事件进行注释。
每个事件都注释有:
- Pod Name
- Pod UID
- Namespace
- Labels
也就是,对 Kubernetes 的每个日志事件,处理日志数据的时候,都会在处理后的日志数据中添加上面列出的信息。
此外,节点和命名空间元数据被添加到 pod 元数据中。
add_kubernetes_metadata处理器有两个基本构建块:
- Indexers
- Matchers
索引器(Indexers)使用pod元数据为每个pod创建唯一的标识符。这些标识符有助于将观察到的pod的元数据与实际事件相关联。例如,ip_port
索引器可以获取一个 Kubernetes pod,并根据其所有 pod_ip:container_port
的组合,为其创建标识符。
匹配器(Matchers)使用事件中的信息,来构造与索引器创建的标识符匹配的查找键。例如,当字段匹配器将["metricset.host"
]作为查找字段时,它将使用字段 metricset_host
的值构造查找关键字。当这些查找键中的一个与其中一个标识符匹配时,事件会丰富已标识的pod的元数据。
当 add_kubernetes_medata
与 Filebeat 一起使用时,它使用容器索引器和 logs_path
。因此,在 log.file.path
中路径包含对容器ID的引用的事件会被该容器的pod的元数据丰富。
可以通过禁用配置中的默认索引器和匹配器来禁用此行为:
processors:- add_kubernetes_metadata:default_indexers.enabled: falsedefault_matchers.enabled: false
当filebeat在Kubernetes中作为pod运行时,下面的配置将启用处理器。
processors:- add_kubernetes_metadata:#labels.dedot: true#annotations.dedot: true
下面的配置允许 Filebeat 上的处理器作为在Kubernetes节点上运行一个进程(也就是支持运行在 Kubernetes 集群之外,但必须在 Kubernetes 节点上)。
processors:- add_kubernetes_metadata:host: <hostname># If kube_config is not set, KUBECONFIG environment variable will be checked# and if not present it will fall back to InClusterkube_config: $Filebeat Reference [8.14]/.kube/config#labels.dedot: true#annotations.dedot: true
下面的配置禁用了默认的索引器和匹配器,并启用了用户感兴趣的索引器。
processors:- add_kubernetes_metadata:host: <hostname># If kube_config is not set, KUBECONFIG environment variable will be checked# and if not present it will fall back to InClusterkube_config: ~/.kube/configdefault_indexers.enabled: falsedefault_matchers.enabled: falseindexers:- ip_port:matchers:- fields:lookup_fields: ["metricset.host"]#labels.dedot: true#annotations.dedot: true
add_kubernetes_metadata
处理器具有以下配置设置:
host
(可选)指定要将filebeat定位到的节点,以防无法准确检测到,例如在主机网络模式下运行filebeat时。
scope
(可选)指定处理器应该在节点级别还是在整个集群级别具有可见性。可能的值为node和cluster。默认情况下,作用域为 node。
namespace
(可选)选择要从中收集元数据的命名空间。如果未设置,处理器将从所有命名空间收集元数据。默认情况下未设置。
add_resource_metadata
(可选)为将要添加到事件中的额外元数据,指定筛选器和配置,以便优化这些元数据,比如添加哪些,删除哪些。
配置参数:
node
ornamespace
: 为来自 node 和 namespace 的额外元数据指定标签和注释过滤器。默认情况下,包括所有标签,而不包括注释。要更改默认行为,可以定义include_labels
,exclude_labels
和include_annotations
。当存储需要特殊处理以避免存储输出过载的标签和注释时,这些设置非常有用。注意:这些设置不支持通配符。通过设置enabled: false
,可以单独禁用node
或namespace
元数据的丰富。deployment
: 如果资源是pod,并且是从 deployment 创建的,那么默认情况下会添加 deployment 名称,可以通过设置deployment: false
来禁用此功能。cronjob
: 如果资源是 Pod,并且是从 cronjob 创建的,那么默认情况下会添加 cronjob 名称,可以通过设置cronjob: false
来禁用此功能。
示例:
add_resource_metadata:namespace:include_labels: ["namespacelabel1"]#labels.dedot: true#annotations.dedot: truenode:include_labels: ["nodelabel2"]include_annotations: ["nodeannotation1"]#labels.dedot: true#annotations.dedot: truedeployment: falsecronjob: false
kube_config
(可选)使用给定的配置文件作为Kubernetes客户端的配置。它默认为 KUBECONFIG 环境变量的值(如果提供)。
kube_client_options
(可选)可以为Kubernetes客户端配置其他选项。目前支持客户端QPS和burst,如果不设置,将使用Kubernetes客户端的默认QPS和burst。示例:
kube_client_options:qps: 5burst: 10
cleanup_timeout
(Optional) Specify the time of inactivity before stopping the running configuration for a container. This is 60s by default.
(可选)指定停止容器的运行配置之前的非活动时间。默认情况下为60秒。
sync_period
(可选)指定列出历史资源的超时时间。
default_indexers.enabled
(可选)当您想要指定自己的pod索引器时,启用或禁用默认pod索引器。
default_matchers.enabled
(可选)当您想要指定自己的pod匹配器时,启用或禁用默认pod匹配器。
labels.dedot
(可选)默认为 true
。如果设置为 true
,那么 labels 中的 .
将替换为 _
。
annotations.dedot
(可选)默认为 true
。如果设置为 true
,那么 annotations 中的 .
将替换为 _
。
7. Indexers and matchers (索引器和匹配器)
7.1. Indexers 索引器
索引器使用pod元数据为每个pod创建唯一的标识符。
可用的索引器:
-
container
使用容器的ID标识 Pod 元数据。 -
ip_port
Identifies the pod metadata using combinations of its IP and its exposed ports.
使用 IP 和 公开的 ports 的结合标识 Pod 元数据。
When using this indexer metadata is identified using the IP of the pods, and the combination if ip:port for each one of the ports exposed by its containers.
使用此索引器时,元数据是使用pod的IP以及容器暴露的每个端口的组合来标识的ip:port
。 -
pod_name
Identifies the pod metadata using its namespace and its name as namespace/pod_name.
使用它的命名空间和名称(namespace/pod_name)标识 Pod 元数据。 -
pod_uid
Identifies the pod metadata using the UID of the pod.
使用 Pod 的 UID 表示 Pod 元数据。
7.2. Matchers
匹配器用于构造查找键,这个会与索引创建的标识符进行匹配。
field_format
使用字符串格式创建的键,查找pod元数据,该字符串格式可以包括事件字段。
这个匹配器有一个选项格式来定义字符串格式。此字符串格式可以包含事件中任何字段的占位符。
例如,以下配置使用 ip_port
索引器通过 Pod IP 及其公开端口的组合来识别 Pod 元数据,并使用事件中的目标 IP 和端口作为匹配密钥:
processors:
- add_kubernetes_metadata:...default_indexers.enabled: falsedefault_matchers.enabled: falseindexers:- ip_port:matchers:- field_format:format: '%{[destination.ip]}:%{[destination.port]}'
fields
使用某些特定字段的值作为关键字来查找pod元数据。定义多个字段时,将使用事件中包含的第一个字段。
此匹配器具有一个选项 lookup_fields
,用于定义其值将用于查找。
例如,以下配置使用 ip_port
索引器来识别 Pod,并定义一个匹配器,该匹配器使用目标 IP 或服务器 IP 进行查找,这是它在事件中找到的第一个匹配器:
processors:
- add_kubernetes_metadata:...default_indexers.enabled: falsedefault_matchers.enabled: falseindexers:- ip_port:matchers:- fields:lookup_fields: ['destination.ip', 'server.ip']
logs_path
使用从 log.file.path
字段中存储的日志路径中提取的标识符查找pod元数据。
此匹配器具有以下配置设置:
- logs_path
(可选)容器日志的基本路径。如果未指定,则使用运行Filebeat的平台的默认日志路径:
Linux:/var/lib/docker/containers/
Windows:C:\\ProgramData\\Docker\\containers
- resource_type
有效的资源类型:- pod: 以基于pod UID进行查找。当
resource_type
设置为pod
时,还必须设置logs_path
,在这种情况下支持路径:- /var/lib/kubelet/pods/ 用于读取挂载到 pod 卷中的日志,这些日志最终位于
/var/lib/kubelet/pods/<pod UID>/volumes/<volume-name>/..
下。要使用/var/lib/kubelet/pods/
作为log_path
,必须将/var/lib/kobelet/pods
filebeat pods。 - /var/log/pods/ 注意:当使用
resource_type: 'pod'
时,Pod 元数据将只使用Pod 元数据: pod id,namespace 填充。
- /var/lib/kubelet/pods/ 用于读取挂载到 pod 卷中的日志,这些日志最终位于
- container: 要根据容器ID进行查找,必须将
logs_path
设置为/var/log/containers/
。它默认为container
。
- pod: 以基于pod UID进行查找。当
要能够使用 logs_path
匹配器 filebeat,输入路径必须是 logs_path
配置设置中定义的目录的子目录。
当从默认的docker日志路径(Linux上的 /var/lib/docker/containers/<containerID>/…
)收集日志时,默认配置能够使用容器ID查找元数据。
例如,当从 var/lib/kubelet/pods/<pod UID>/...
收集日志时,以下配置将使用pod UID
processors:
- add_kubernetes_metadata:...default_indexers.enabled: falsedefault_matchers.enabled: falseindexers:- pod_uid:matchers:- logs_path:logs_path: '/var/lib/kubelet/pods'resource_type: 'pod'