在使用filebeat采集部署在使用騰訊云TKE容器集群上的日志時(shí),會(huì)把default、kube-system等默認(rèn)的命名空間下的日志都采集上來(lái),但是這些命名空間下的日志一般都不是我們需要的,怎么過(guò)濾掉對(duì)這些命名空間下的容器運(yùn)行日志?比較直觀(guān)的想法是在filebeat的yml配置中定義好processors,使用drop_event processor對(duì)采集上來(lái)的不需要的日志進(jìn)行丟棄,這種方法雖然能夠?qū)崿F(xiàn)日志的過(guò)濾,但是filebeat還是會(huì)對(duì)不需要采集的容器日志進(jìn)行監(jiān)聽(tīng)和采集,一定程度上降低了filebeat的效率,所以有沒(méi)有好的方法能夠從源頭就不采集不需要的日志呢?
1. 使用filebeat 7.x版本采集容器日志
對(duì)于容器日志的采集,filebeat有專(zhuān)門(mén)的inupt類(lèi)型:docker和container兩種,早期的6.x版本的filebeat只有docker input類(lèi)型,對(duì)于使用docker作為運(yùn)行時(shí)組件的kubernetes集群,比較友好;在7.2版本的filebeat又重新開(kāi)發(fā)了container類(lèi)型的input類(lèi)型,無(wú)論是docker組件還是containerd組件,都可以比較好的支持。因此從7.2版本開(kāi)始,docker input就被廢棄了,官方推薦使用container input。
在使用filebeat 7.x版本采集容器日志時(shí),推薦采用container input,并且使用autodiscover實(shí)現(xiàn)容器的自動(dòng)發(fā)現(xiàn),也就是在有新的容器運(yùn)行時(shí),filebeat會(huì)自動(dòng)去采集新建的容器日志,而不需要再去修改filebeat.yml來(lái)實(shí)現(xiàn)對(duì)新部署的容器日志的采集。而正式使用autodiscover功能,使得限定采集源成為了可能,因?yàn)樵赼utodiscover模式下,filebeat在啟動(dòng)時(shí)就會(huì)去調(diào)用kubernetes API來(lái)獲取當(dāng)前集群下所有的namespace、pod、container等元數(shù)據(jù)的信息,然后根據(jù)這些元數(shù)據(jù)再去指定的目錄采集對(duì)應(yīng)的日志。
下面給出一個(gè)可用的限定采集源的filebeat.yml:
filebeat.autodiscover:
providers:
- type: kubernetes
hints.enabled: true
templates:
- condition:
and:
- or:
- equals:
kubernetes.namespace: testa
- equals:
kubernetes.namespace: testb
- equals:
kubernetes.container.name: nginx
kubernetes.labels:
k8s-app: nginx
config:
- type: container
paths:
- /var/log/containers/${data.kubernetes.pod.name}_${data.kubernetes.namespace}_${data.kubernetes.container.name}-*.log
output.elasticsearch:
hosts: ['x.x.x.x:9200']
username: "xxx"
password: "xxx"
上述配置中,用于限定采集源的就是condition模塊下的部分,用于限定只采集testa 或者 testb命名空間下的nginx容器的日志??梢愿鶕?jù)kubernetes元數(shù)據(jù)來(lái)限定采集源,可用的元數(shù)據(jù)有以下這些:
host
port (if exposed)
kubernetes.labels
kubernetes.annotations
kubernetes.container.id
kubernetes.container.image
kubernetes.container.name
kubernetes.namespace
kubernetes.node.name
kubernetes.pod.name
kubernetes.pod.uid
kubernetes.node.name
kubernetes.node.uid
kubernetes.namespace
kubernetes.service.name
kubernetes.service.uid
kubernetes.annotations
上述配置中,condition可以根據(jù)需求定義更復(fù)雜的限定條件,可以參考Conditions進(jìn)行填寫(xiě)。
另外需要注意的是,上述配置中的config模塊下的paths路徑,需要也通過(guò)占位符對(duì)日志文件的名稱(chēng)進(jìn)行匹配,否則就會(huì)出現(xiàn)采集上來(lái)的日志內(nèi)容與kubernetes元數(shù)據(jù)不一致的問(wèn)題。比如/var/log/containers目錄下有各個(gè)pod的日志,日志文件名的命名規(guī)則為{pod_name}_{namespace}_{container_name}-{container_id}.log
nginx-6c5ff7b97b-6t5k4_default_nginx-eeecb30c81564668b1858c186099ab525431b435ed1b8fa3b25704cbbbca6a2d.log
那么 paths就需要通過(guò)$符進(jìn)行規(guī)則匹配:
${data.kubernetes.pod.name}_${data.kubernetes.namespace}_${data.kubernetes.container.name}-*.log
2. 使用filebeat 6.x版本采集容器日志
6.x版本的filebeat,只有docker input, 對(duì)于docker運(yùn)行時(shí)組件比較友好,而對(duì)于containerd運(yùn)行時(shí)組件,不太友好,沒(méi)有較好的方式限定采集源,只能全量采集所有容器的日志。
2.1 采集docker組件部署的kubernetes集群中的容器日志:
filebeat.autodiscover:
providers:
- type: kubernetes
templates:
- condition:
and:
- equals:
kubernetes.labels:
k8s-app: nginx
config:
- type: docker
combine_partial: true
containers:
ids:
- ${data.kubernetes.container.id}
output.elasticsearch:
hosts: ['http://x.x.x.x:9200']
username: "xxxx"
password: "xxx"
其中的condition條件用于限定只采集標(biāo)簽為k8s-app: nginx的容器的日志。
2.2 采集containerd組件部署的kubernetes集群中的容器日志:
filebeat.autodiscover:
providers:
- type: kubernetes
hints.enabled: true
templates:
- condition:
and:
- equals:
kubernetes.labels:
k8s-app: nginx
config:
- type: docker
combine_partial: true
symlinks: true
containers:
path: "/var/log/containers"
ids:
- ""
output.elasticsearch:
hosts: ['http://x.x.x.x:9200']
username: "xxx"
password: "xxxx"
上述配置與2.1中配置的區(qū)別是,需要顯式的指定container.path為/var/log/containers, 因?yàn)閏ontainerd組件下,容器日志在該目錄下,并且為軟鏈接,需要指定symlinks: true,否則就無(wú)法采集。另外,container.ids需要指定為空字符串,不必限定容器的id的匹配規(guī)則,該配置項(xiàng)對(duì)docker組件部署的容器有效,因?yàn)閐ocker組件下,容器日志默認(rèn)在/var/lib/docker/containers目錄下,且日志文件名采用容器id命名。
上述配置的問(wèn)題就是condition條件不會(huì)生效,會(huì)全量采集所有的命名空間下的容器日志,目前沒(méi)有找到較好的解決辦法來(lái)限定采集源,但是可以通過(guò)定義drop_event processor來(lái)丟棄掉不需要采集的日志。實(shí)際使用中,還是建議直接使用7.2及以上版本的filebeat來(lái)采集使用containerd組件部署的kubernetes集群中的容器日志。