我正在使用另一种方法,即在日志管道中传输的日志数量方面效率较低。
与您的做法类似,我使用守护程序集在我的节点上部署了一个 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
守护进程规范:
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 帮助,请在 cmets 中询问):
logstash.yml 文件非常基础:
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
只是表示我挂载管道配置文件的目录的挂载点,如下:
10-beats.conf:
声明 filebeat 的输入(端口 5044 必须使用名为“logstash”的服务公开)
input {
beats {
port => 5044
ssl => false
}
}
49-filter-logs.conf:
这个过滤器基本上会丢弃来自没有“elk”标签的 pod 的日志。对于确实具有“elk”标签的 pod,它会保留来自 pod 的“elk”标签中命名的容器的日志。例如,如果一个 Pod 有两个容器,分别称为“nginx”和“python”,放置一个值为“nginx”的标签“elk”只会保留来自 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中的新日志。您只需在 pod 模板中添加标签即可。
- 默认情况下,所有日志文件都会被删除,只要您没有明确放置标签。
这种方法的缺点
- 来自所有 pod 的所有日志都来自 filebeat 和 logstash,并且仅在 logstash 中被丢弃。这对 logstash 来说是很多工作,并且可能会消耗资源,具体取决于集群中的 pod 数量。
我确信有更好的方法来解决这个问题,但我认为这个解决方案非常方便,至少对于我的用例而言。