背景现象解决过程总结(很重要)背景趁热记录下,给未来的自己
本地部署了两套 k8s 环境:开发和预生产。为了方便开发同学调试,需要将 k8s 的业务日志通过 EFK 框架输出到 WEB 端查看。
部署架构:
elastic search 和 kibana 是部署在 k8s 集群外,filebeat 以 demonset 的方式部署在 k8s 的 node 节点上。现象同一份 filebeat-k8s.yml 文件,在开发集群上可以成功部署且在 Kibana 上能采集到对应的日志。但是在预生产集群上部署成功后,无法在 Kibana 上看到日志。
解决过程首先,对比了 filebeat 在开发和预生产 node 节点上的日志,发现前者含有 [input.harvester] 和 Collection to backoff established 日志,而后者没有。这说明,后者没有采集到数据,所以没有向 elastic search 发送数据。
定位到了具体问题,那么接下来要解决的是,为什么预生产 node 节点上的 filebeat 无法采集 docker 日志呢?
到这里,我突然想起来,预生产和开发集群最大的区别在于: docker 安装目录不同。
开发集群的 docker 安装在默认位置: /var/lib/docker; 预生产的 docker 安装在了 /home/ops/docker 。这么做的目的是,将 docker 从较小的系统盘移到了较大的数据盘上,以便放更多的日志。没想到给自己埋下了一个大坑。。。
为了验证猜测,进入预生产的 filebeat 容器, 查看 /var/log/container 目录下的内容,发现全是红色的,表示挂载失败:
用 ls -la 命令查看了下,发现这些文件软链接于 /var/log/pods
于是,又进入 /var/log/pods,ls -la 发现,该目录下的log文件又软链接于 /home/ops/docker 目录
而 /home/ops/docker 目录在容器中并不存在!至此,找到了根本原因。那么可以修改 filebeat-k8s.yml 里 DeamonSet 资源的 volume 和 volumeMounts 如下:
volumeMounts:- name: varlibdockercontainers # 容器内的目录 mountPath: /home/ops/docker/containers readOnly: true volumes:- name: varlibdockercontainers # 宿主机上的目录 hostPath: path: /home/ops/docker/containers
k8s里 docker 的日志链路关系:
默认docker安装目录:/var/log/container/*.log --> /var/log/pods/*/*.log -> /var/lib/docker/containers/*/*.log
预生产docker安装目录:/var/log/container/*.log --> /var/log/pods/*/*.log -> /home/ops/docker/containers/*/*.log
Done