K8S应用日志收集及可视化展示
背景介绍
目前公司的微服务是跑在IDC自建的K8S中,各个微服务的日志与前期开发沟通,约定日志输出规范,INFO和ERROR级别日志分开(当然每个公司的需求都不一样),但跑在K8S集群中的日志,如何收集及展示呢?提高研发效能,基于此,进行了K8S应用日志调研及部署。
K8S的日志收集难点
k8s的日志相比于传统的基于物理机/虚拟机部署的场景有哪些不同点呢?
日志形式变得更加复杂:不仅有物理机/虚拟机上的系统日志,还有容器的标准输出日志,容器内的应用日志、容器事件日志、k8s事件等等日志都需要采集。
环境的动态变化:在k8s中,机器的宕机、上下线,Pod销毁/重建、扩缩容等等都是常态,这种情况的日志时瞬时的(例如Pod生命周期结束后,该Pod中的日志就没有了),这就要求日志采集能够使用这种环境动态的变化,也即是:日志需要实时采集到。
业务架构变化:现在也有好多公司在k8s中进行了落地架构,在微服务体系架构中,服务的开发变得更复杂,服务之间的依赖关系及服务底层之间的调用关系更加复杂,若出现异常情况,对于排障情况,更加复杂。
日志种类变化多样:当k8s真正落地到生产环境,且中大规模使用时,里面的日志种类是非常多的;就譬如一个用户从app发起一个请求,大致需要经过CDN、Ingress、Mesh、Pod、调用链日志(traceId)、App访问日志、App错误日志、中间件日志、审计日志、网络日志、系统组件日志、内核日志等。
日志规模:若业务量不是很大,业界都是都是自建开源的日志系统(我们也是自建的),这种方式没有打到一定的日志规模,都不会出现什么问题。若打到一定规模,自建的开源日志系统就出出现各种问题;例如 ES整个集群Hang、查询延迟、日志系统可用性等。当然了,公司有钱,直接上阿里云日志服务,省心省力、有时有问题,还有阿里云背锅(哈哈)或者基于开源的日志进行自研。不排查问题时,系统系统地位体现不到,尤其是出现关键问题,就知道日志系统的重要性;
基于以上几点,那日志系统需要哪些功能呢?
全方位的日志采集;支持web、移动端、IoT、物理机、虚拟机各种数据源采集
日志实时
数据清洗
日志展现和搜索
实时分析:可以快速分析问题的根因;离线分析:通过连线分析提供一定是数据价值给运营或安全部门。
机器学习,通过对大量的历史日志数据进行离线训练,并将训练后的结果加载到线上实时的方法库中。就好比是历史技术文档,出现类似问题,就能找到处理方法
K8S的日志采集方案
官方给出了3种方案
Using a node logging agent
Using a sidecar container with the logging agent
此方案,官方给出的是使用Fluentd插件,我们是使用Filebeat插件,原因如下:
Kubernetes官方提供了EFK的日志收集解决方案,但是这种方案并不适合所有的业务场景,它本身就有一些局限性,例如:
a. 所有日志都必须是out前台输出,真实业务场景中无法保证所有日志都在前台输出
b. 只能有一个日志输出文件,而真实业务场景中往往有多个日志输出文件
c. Fluentd并不是常用的日志收集工具,我们更习惯用logstash,现使用filebeat替代
因Logstash是基于JDK的,在没有产生日志的情况单纯启动Logstash就大概要消耗500M内存,在每个Pod中都启动一个日志收集组件的情况下,使用logstash有点浪费系统资源;单独启动Filebeat容器大约会消耗12M内存,比起logstash相当轻量级
Exposing logs directly from the applicatio
可以参见kubernetes.io的官方介绍:https://kubernetes.io/docs/concepts/cluster-administration/logging/
以上各采集方式对比:
这里我们是使用方案二:Sidecar方式
整体情况介绍:
确保k8s集群能正常运行
确保es和kibana能正常运行且可访问,这里安装略,可参见官网
我这里使用filebeat版本为:7.8.1,将其镜像下载好后,然后推入到自己的私仓中,不然出现下载很慢很慢
确保有一个能跑通的jar应用,我这里集成了Jenkins 的CI/CD,通过触发job,自动将jar包生成镜像,并上传到我们的私仓中,然后进行deployment、创建Service、进行NodePort映射,通过nginx绑定nodeport(因我们应用不多,没有使用Ingress),结合内网DNS访问。关于Jenkins 与K8S集成CI/CD这里不做过介绍,因为每个公司的CI/CD都是不一样的。
cat deploy.yaml
--- apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config namespace: dev labels: k8s-app: filebeat data: filebeat.yml: |- filebeat.inputs: - type: log enabled: true paths: - /logs/* multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}' multiline.negate: true multiline.match: after multiline.timeout: 10s # 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: container # paths: # - /var/log/containers/*${data.kubernetes.container.id}.log processors: #- add_cloud_metadata: - add_host_metadata: cloud.id: ${ELASTIC_CLOUD_ID} cloud.auth: ${ELASTIC_CLOUD_AUTH}
output.elasticsearch: hosts: ['192.168.1.101:9200'] #username: ${ELASTICSEARCH_USERNAME} #password: ${ELASTICSEARCH_PASSWORD} index: "k8s-dev-%{+YYYY}" setup.template.name: "k8s-dev" setup.template.pattern: "k8s-dev-*" setup.ilm.enabled: false
--- apiVersion: apps/v1 kind: Deployment metadata: name: cd-web namespace: dev spec: selector: matchLabels: app: cd-web replicas: 2 template: metadata: labels: app: cd-web spec: imagePullSecrets: - name: cd-registry containers: - image: harbor.ttsingops.com/beats/filebeat:7.8.1 name: cd-web-filebeat args: [ "-c", "/etc/filebeat.yml", "-e", ] env: - name: ELASTICSEARCH_HOST value: "192.168.1.101" - name: ELASTICSEARCH_PORT value: "9200" - name: ELASTICSEARCH_USERNAME value: - name: ELASTICSEARCH_PASSWORD value: - name: ELASTIC_CLOUD_ID value: - name: ELASTIC_CLOUD_AUTH value: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName securityContext: runAsUser: 0 volumeMounts: - name: filebeat-config readOnly: true subPath: filebeat.yml mountPath: /etc/filebeat.yml - name: applogs mountPath: /logs - image: harbor.ttsingops.com/cd-web/cd-web:297 name : cd-web-container imagePullPolicy: Always ports: - containerPort: 9090 volumeMounts: - name: applogs mountPath: /data/logs/cd-web/ volumes: - name: applogs emptyDir: {} - name: filebeat-config configMap: defaultMode: 0600 name: filebeat-config --- #Service apiVersion: v1 kind: Service metadata: name: cd-web namespace: dev spec: type: NodePort ports: - port: 9090 protocol: TCP targetPort: 9090 nodePort: 39090 selector: app: cd-web |
查看Dashboard的filebeat容器的日志信息:
说明配置已采集到定义的日志文件了
最后通过Kibana来查询日志信息
最后访问api的Rest接口:
至此,k8s的应用日志收集完成,并成功的通过Kibana来展示,同时api接口也访问正常。
- K8S使用filebeat统一收集应用日志
- K8S使用filebeat统一收集应用日志
- k8s应用内部日志收集
- 基于dropwizard/metrics ,kafka,zabbix构建应用统计数据收集展示系统
- 如何为应用创建收集崩溃日志文本
- k8s日志收集配置
- 关于K8s集群器日志收集的总结
- 【如何R实现聚类算法及3D可视化展示】:kmeans聚类方法在用户价值细分上的应用
- Flume日志收集分层架构应用实践
- 大数据可视化之Nginx服务器日志分析及可视化展示(Nginx+flume+HDFS+Spark+Highcharts)
- 基于Elasticsearch+Fluentd+Kibana的日志收集分析系统搭建与应用
- 在Kubernetes上搭建日志收集、分析、展示平台ELK(Logstash+Elasticsearch+Kibana)
- 关于K8s集群器日志收集的总结
- 分布式mongodb搭建-使用mongodb收集应用日志
- Linux――ELK(Elasticsearch + Logstash + Kibana)企业日志分析之linux系统history收集展示
- 日志收集系统Flume及其应用
- 基于dropwizard/metrics ,kafka,zabbix构建应用统计数据收集展示系统
- Flume日志收集分层架构应用实践
- ELK收集nginx日志并用高德地图展示出IP
- 技术积累应用-可视化编程平台应用方式-数据展示控制