《Kubernetes业务日志收集与监控探析.docx》由会员分享,可在线阅读,更多相关《Kubernetes业务日志收集与监控探析.docx(15页珍藏版)》请在课桌文档上搜索。
1、随着容器技术以及容器编排技术的成熟,越来越多的中小型企业也在将服务迁移到KUbenIeteS中,更智能,更便捷的管理服务,降低运维成本,而在迁移过程中,业务日志的收集以及业务服务的监控,集群状态的监控就变得很重要了。本问主要讲述在将服务迁移到Kubernetes中是如何收集业务日志以及监控集群、业务状态的。集群业务日志收集我司规模不大、运维人员较少,所以在业务迁移到Kubernetes中整体的日志收集流程并没有大改,只做出了部分调整。由于前期日志目录以及日志名称规范很好,所以调整起来也很方便。在业务迁移KUbenIeteS之前日志收集流程如下图图1旧E1.K架构旧的日志收集架构其实存在一些问题
2、:当1.ogstash挂了之后就存在丢失日志问题,之前跨大版本升级1.ogstash失败就丢失了一段时间日志。当1.ogStaSh后的消费程序挂了其一,例如ES挂了,会导致日志写文件和写InfluxDB都有问题并且由于Filebeat会不断推送日志给1.ogStaSh从而导致日志丢失。以上两个问题都说明组件之间耦合严重,所以在迁移Kubernetes时我们对架构做了一些调整,调整后的日志收集架构如下图2。图2新E1.K架构在Filebeat和1.ogstash之间增加Kafka用于临时缓存日志,并用于解耦日志消费者。启动多个1.ogStaSh实例分别处理写文件、连接ES、写InfIUXDB从而
3、解耦日志消费程序耦合。因为业务迁移要求快、时间短,没有时间将日志都打在容器StdOUt输出,所以采用将容器日志映射到宿主机上,再通过FiIebeat收集,实现KUbenleteS中业务日志收集。这里给出1、3点变化的配置变更:第1点带来的配置变化对比如下图3。变更股争-1.ogstashoutputoutput.IogstasK:9The1.09stashhostshosts:(,IP三5e44,j变更后:Kafkaoutputoutput.kafka:hosts:(MIP:9e92M)topic:*M!fields.topic*key:5044SJ三input(Skafka(bootstrp
4、.srvers=HIP:9092Mtopics三(xotgroup-ld三IogstashofilterJSonsource三FcsgeJJg二墨,皂/1#幽量延WflwQD些模处电星母tt取不到日志内容,没书之加注一行无法将慢敷却8式图3接入Kaflca后配置变更重点分享下第3点变化:最开始公司内部新增一个服务都需要将该服务的所有日志类型的收集规则直接写入filebeat.yml文件,然后使用Ansible下发到所有业务机上重启并Filebeat。这样导致filebeat.yml文件越来越长、难以维护并且一个配置不正确会导致Filebeat起不来,造成日志无法及时收集。后来我们将每个业务日志
5、收集规则拆分成一个个小yaml文件存放在etcf11ebeatinputs.d中,业务Filebeat收集规则则由一个自动生成配置脚本从Kubernetes集群获取业务namespace和服务日志路径来自动生成业务Filebeat配置再通过Ansible将配置下发到指定目录。第3点配置变化对比如下图4中3部分。图4FiIebeat收集变化通过以上几点修改我们快速的完成了业务日志在Kubernetes集群中的收集工作,并且提高了日志系统的稳定性,为以后常规化升级日志系统带来了便利。当然我们的系统也有不足之处,现在我们的Filebeat还是使用Systemd启动,每新增一个Node,都需要安装一次
6、FiIebea3并且需要让自动脚本检索到这个节点给节点下发配置,后期我们打算使用KubernetesDaemonSet模式来部署Filebeat并且当有新服务加入自动更新Filebeat配置、使用Kubernetes的方法来完成FiIebeat安装、配置更新。集群状态监控以及业务状态监控我们在集群状态监控以及业务状态监控方面,采用的是PrometheusOperator的一揽子开源工具解决方案。先介绍下各个组件作用:PrometheusOperator:PrometheUS是主动去拉取监控数据的,在KUbemeteS里Pod因为调度原因导致IP不断变化,人工不可能去维持,自动发现又是基于DNS
7、的,但是新增还是有点麻烦。PrometheusOperator的本职就是一组用户自定义的CRD资源以及Controller的实现,PrometheusOperator这个controller有RBAC权限、负责监听这些自定义资源的变化,并且根据这些资源的定义自动化的完成如PrometheusServer自身以及配置的自动化管理工作。Kube-state-metrics:能够采集绝大多数KUbenleteS内置资源相关数据,例如Pod、Deploy.SerViCe等。同时它也提供自己的数据,主要是资源采集个数和采集发生的异常次数统计。例如我调度了多少个RePliCas?现在可用的有几个?多少个P
8、od是running/stopped/terminated状态?Pod重启了多少次?等等这些状态值都可以通过添加Prometheusrule来产生报警,及时通知运维和开发人员。Prometheus:用于收集集群组件Metric和集群中各类资源状态Metric以及自定义实现的监控Metric数据。AlertManager:处理由PrOmetheUS服务器等客户端发来的警报。它负责删除重复数据、分组,并将警报通过路由发送到正确的接收器,比如电子邮件、Webhook等。在Kubernetes中部署业务前,监控系统和日志收集系统都需要提前安装好,因为业务分地区等原因我司内部存在多套集群环境,每套集群部
9、署地区都不一致,所以在部署监控服务时,我们采取的方案是在每个集群中都创建一套完整的监控系统,因为我们的业务不属于PV很大的业务且集群规模较小,所以每个集群一套监控系统是比较合理的。监控系统中的各组件服务存放在个单独的namespace中,直接采用YAM1.方式安装,没有使用helm安装。集群监控架构图如下图5。图5Kubernetes集群监控架构从图中可以看出我们主要收集了三个方面监控数据:集群组件:我们收集了API、ControllerSchedulerKubeletsCoreDNS五个组件的Metrics,由于我司集群采用二进制方式安装的,所以部分组件Metric(ControllerSc
10、heduler)数据的获取需要自己配置EndPOintS并配合SerViCe和ServiceMonitor完成Metric的收集。下面给出Controller的EndpointsServiceServiceMonitor配置如下图6。apiVersion:vlkind:Endpointsmetadata:labels:k8s-app:kube-controller-nanagername:kube-controller-managernanespace:kube-systemsubsets:-addresses:- ip:IPl- ip:IP2- ip:IP3ports:- name:http
11、-metricsport:10252protocol:TCP,SerViCe配置.apiVersion:vlkind:Servicemetadata:nanespace:kube-systePrometheusAIertmanager、kube-state-metrics的部署,网上教程也很多,大家自己搭建碰到问题自己解决也是很有乐趣的,也可以查看我的GitHUb仓库,参考安装。这里重点说下Prometheus存储,由于Prometheus部署在Kubernetes集群中而Pod是随时消亡的,所以直接本地存储是不合适的,当然也可以使用PV来存储,不过现在有很多很好也很完善的Prometheus
12、远程存储方案可供选择,建议使用远程存储方案。我司采用InfIUXDB作为Prometheus远程存储方案,单机InfklXDB性能已经很强基本满足日常需求,但由于他的集群方案是不开源的,存在单点故障问题。所以大家可以选择其他远程存储解决方案避免这个问题。Prometheus连接InfIUXDB配置如下图7。#在PrOfnetheUS的StatefUlSet.yaml中配置:apiVersion:baseimage:quay.io/prometheus/prometheus#baseimage:-UrI:http:IP:8086/api/vlpro11l/read?db=库名&u=用户名&p=密
13、码readRecent:trueremoteWrite:#furl:http:1P:8086/api/vl/pro11write?db=库名&u=用户名&p=密码ServiceAccountNaine:prometheus-k8sServiceMonitorflamespaceSelectors冏ServiceMonitorSelector:ruleselector:match1.abels:prometheus:k8srole:alert-rulesresources:requests:memory:400Mialerting:alertmanagers:-name:aIertmanager
14、-mainnamespace:monitoringIport:Web图7Prometheus远程读写关于报警方面。我司内部为了统一各类报警资源与报警信息格式,由架构部开发了一个报警API程序,其他部门如需使用只要将报警内容转换成特定Json格式发送给报警API即可将报警信息推送到个人的电话、邮箱、短信、企业微信中。所以在Alertmanager中我们采用了Webhook模式发出Json格式报警数据到指定API,建议有能力的同学采用该模式自行处理报警数据,而不要使用默认配置方法发送邮件或者微信,默认的报警格式不太美观。数据展示方面当然用的Grafana了,Grafana展示效果图如下图8与图9,
15、我的图形配置也是基于Grafana官方模版中其他同学的模版,大家可以到官方网站中去下载适合自己的模版。图8Kubernetes组件展示图9Pod性能展示总结一下,对于中小型的企业采用开源的PrometheusOperator一揽子工具来快速的构建Kubernetes监控系统再合适不过了,这套系统基本可以搞定在Kubernetes中监控业务状态和组件状态,当然这套系统也有一些不足之处:Event监控/收集:在Kubemetes中Pod的部署过程会产生一些事件,这些事件会记录Pod的生命周期以及调度情况。并且event在集群中不是永久保存的。如果你需要知道集群中Pod的调度情况,以及收集event
16、作为审计或其他作用,并且当集群中业务越来越多,不太可能实时去集群中查看event,那么event的监控/收集就很重要了。最近在了解阿里的event收集工具kube-eventer,看上去还不错,有兴趣的同学可以一起讨论下如何搭建。某些情况下Prometheus产生报警信息过多、过于频繁:虽然我们已经调整了部分Prometheusrule规则中并且修改了rule中报警产生频率,但是实际应用中我们偶尔会碰到例如一个节点故障时产生大量报警信息的问题。这些报警信息虽然有用,但是信息太多反而干扰了问题排查。JVM监控关于JVM监控,我司由于后端服务都是JaVa编写的,我相信国内多数公司的后端都是Java
17、。众所周知JaVa程序是运行在JVM虚拟机之上的,随着业务规模的增大,JVM监控旧显得越来越重要。开始我司并没有JVM监控,开发同学被运行上到业务机器上到处JVM相关信息,但后来由于公司开发人员越来越多,规范和要求也越来越多。一个可以集中查看JVM监控展示是必须的。于是开始搭建JVM监控服务,选型时通过对比了PinpointsJMXExporterSkywalking三种方案,虽然Pinpoint和Skywalking还支持链路追踪等功能,但由于公司内部已经有了ZiPkin并且PinPOint和Skywalking服务部署比较麻烦,于是选择了JMXEXPOrter方案。这个方法对业务代码无任何
18、入侵且部署简单,在宿主机部署业务的JMX监控架构如下图100图10旧JVM监控简单介绍图中架构:现在由于微服务的流行,后端存在很多服务并且新增后端服务很快,在prometheus.yml直接配置服务IP+JVM端口不是明智之选。所以我们选择用Consul来做自动注册服务功能并通过每台业务机器上的Python脚本将部署在该台机器上的所有服务JVM端口地址发送给Consul,Prometheus从Consul中获取服务JVMMetrics地址从而获取服务JVM数据。在没有Kubernetes集群之前PrOmetheUS使用Docker启动,远程存储采用CIickHouse但是由于ClickHous
19、e连接Promehteus需要使用prom2click做数据转换,多一个组件多一份维护成本且这个组件功能不全,所以在Kubernetes集群中Prometheus远程存储已经改成InfIUXDB。JMXEXPOrteI注入服务启动也很方便,这里只需将JMXExporter的jar包以及配置文件放在程序的启动命令中并且指定端口即可获取到JVM相关MetriC数据。服务启动命令如下:java-javaagent:/datci/jmx_prometheusJavaagent-0.11.0.jar=57O34:/data/jmx_exporter/jmx_exporter.yml-jar-D1.OG-
20、D1R=/日志路径/服务名/-Xmx512m-Xms256m服务名.jarPrometheus中配置Consul如下图11,当Prometheus收集到业务JVMMetrics数据后就可以在Grafana中做聚合展示、报警等功能。-job-name:,consul1consul_sd_configs:-server:,IPj8501,#ConSUI的地址services:relabel_configs:-SoUrCe.labels:_meta_consul_serviceregex:(.*)target-label:servicereplacement:$1action:replace一SOU
21、rCe.labels:_meta_consul_serviceregex:(.*)target_label:servicesreplacement:$1action:replace图11PrometheusConsul当服务迁移到KUberneteS集群中,我们变更了JMXEXPorte的部署方式JMXExporter通过ini(Container方式共享jar包和配置给业务容器,方便jmx_exporterjar包升级和配置变更。这里就不具体展示配置YAM1.,而JVM采集我们抛弃了之前用COnSUI做自动注册的方法而采用SerViCeMonitOI配合SerViCe来获取JVMMetriC
22、S数据,配置YAM1.如下图12,Grafana展示如下图13。#BMserviceapiVersion:vlkind:Servicemetadata:name:alabels:app:aspec:type:NodePortports:-name:httpport:80targetPort:80nodePort:3-name:jmxport:JtargetPort:XnodePort:X*QT配Ibrtapp:a#JVMServiceMonitroapiVersion:labels:app:a-jvmname:a-jvmspec:endpoints:-interval:lsport:jmxsc
23、heme:httppath:/metrics,namespaceSelector:matchNames:-defaultselector:match1.abels:app:a图12JVMYAM1.图13JVMGrafana在Kubernetes中我们的JVM监控也碰到了一些问题,例如之前在业务机器直接部署程序,主机IP固定不变,当JVM挂了之后程序自动重启,我们可以在Grafana中看到程序挂掉那一刻的JVM状态,并且一台机器上的业务图像是连续的,而在集群中由于PodIP和Pod名称都在变化这样就导致一个服务POd挂了之后,在Grafana上查找之前消亡的POd比较麻烦,而且图形在时间线上也不
24、连续。之前有想过用StatfulSet模式来固定名称,最后觉得这有悖无状态原则就没有采纳,F个问题还有待解决。为何采用JMXEXPOrter来监控JVM,而不是ACtUatOr/Prometheus?A:公司最开始只考虑了链路追踪,用的是ZiPkin,后来要求上JVM监控时,要求是完全不能有代码侵入,所以考虑了JMXEXPorter。还有你说的这个工具我不是很了解,后期可以了解下。如何做到业务监控的报警,如某个接口响应时间增多,或调用频率多?A:我司的做法是程序自身记录接口响应时间,暴露成MetriC数据之后通过PrOmetheUS收集,配置对应的rule规则,超过设定的响应时间就推送报警消息
25、给Alertmanager再发送给运维人员。kube-state在集群规模大的时候容易00M,怎么解决?A:我们的集群节点还很少,到现在还未碰到kube-state-metricOOM的问题,既然你的集群规模大,由于kube-state收集的数据很多,那多给点内存总是没错的。内部应用http调用是怎么调的?直接使用service域名?还是有内网ingresscontroller?还是其他方案?A:我们用的是Eureka来做服务注册与发现,但是我更希望公司能用Kubernetes的servic,Eureka调用是有一丢丢问题的。Kubernetes日志系统做多租户模型有没有什么方案的建议?你的多
26、租户是区分nanespace的话,可以考虑将namespace加入到日志路径中或kafkatopic中,这样就能区分了。有没有考虑过监控跨集群,跨机房数据汇聚问题?之前我们用过PrOmetheUS联邦方式,但是由于我们的业务跨了国家在网络上有很多限制,就放弃了这种方法了。如果你的业务都在国内或者一个云服务商或者网络条件允许的话,可以搞一搞。附参考资料:KUbemeteS日志收集路径关于容器日志DOCkeI的日志分为两类,一类是DOCker引擎日志;另一类是容器日志。引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。本文主要介绍容器日志,容器日志可以理解是运行在容器内部的应用输出的日
27、志,默认情况下,dockeMogs显示当前运行的容器的日志信息,内容包含SToUT(标准输出)和STDERR(标准错误输出)。日志都会以json-file的格式存储于varlibdockerCOntainerS/-json.log,不过这种方式并不适合放到生产环境中。默认方式下容器日志并不会限制日志文件的大小,容器会一直写日志,导致磁盘爆满,影响系统应用。(dockerlog-driver支持log文件的rotate)DockerDaemon收集容器的标准输出,当日志量过大时会导致DockerDaemon成为日志收集的瓶颈,日志的收集速度受限。日志文件量过大时,利用dockerlogs-f查看
28、时会直接将DockerDaemon阻塞住,造成dockerps等命令也不响应。如果您正在学习SpringBoot,推荐一个连载多年还在继续更新的免费教程;DOCker提供了IoggingdriVerS配置,用户可以根据自己的需求去配置不同的log-driver,可参考官网COnfigUrelOggingdriVerS。但是上述配置的日志收集也是通过DOCkerDaemOn收集,收集日志的速度依然是瓶颈。log-driver日志收集速度syslog14.9MB/sjson-file37.9MB/s能不能找到不通过DockerDaemon收集日志直接将日志内容重定向到文件并自动rotate的工具呢
29、?答案是肯定的采用S62基底镜像。S6-log将CMD的标准输出重定向到/./default/CUITen3而不是发送到DockerDaemon,这样就避免了DOCkerDaemOn收集日志的性能瓶颈。本文就是采用S6基底镜像构建应用镜像形成统一日志收集方案。关于Kubernetes日志Kubernetes日志收集方案分成三个级别:应用(Pod)级别Pod级别的日志,默认是输出到标准输出和标志输入,实际上跟DoCker容器的一致。使用kubectllogspod-name-nnamespace查看。节点级别Node级别的日志,通过配置容器的log-driver来进行管理,这种需要配合Iogro
30、tare来进行,日志超过最大限制,自动进行rotate操作。集群级别集群级别的日志收集,有三种。节点代理方式,在NOde级别进行日志收集。一般使用DaemonSet部署在每个NOde中。这种方式优点是耗费资源少,因为只需部署在节点,且对应用无侵入。缺点是只适合容器内应用日志必须都是标准输出。使用sidecarCOntainer作为容器日志代理,也就是在Pod中跟随应用容器起一个日志处理容器,有两种形式:一种是直接将应用容器的日志收集并输出到标准输出(叫做Streamingsidecarcontainer),但需要注意的是,这时候,宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另
31、一份则是sidecar的stdout和StdeiT对应的JSON文件。这对磁盘是很大的浪费,所以说,除非万不得已或者应用容器完全不可能被修改。另一种是每一个Pod中都起一个日志收集agent(比如1.ogstash或Fluebtd)也就是相当于把方案一里的loggingagent放在了Pod里。但是这种方案资源消耗(CPU,内存)较大,并且日志不会输出到标准输出,kubectllogs会看不到日志内容。应用容器中直接将日志推到存储后端,这种方式就比较简单了,直接在应用里面将日志内容发送到日志收集服务后端。日志架构通过上文对Kubernetes日志收集方案的介绍,要想设计一个统一的日志收集系统,
32、可以采用节点代理方式收集每个节点上容器的日志,日志的整体架构如图所示:解释如下:所有应用容器都是基于S6基底镜像的,容器应用日志都会重定向到宿主机的某个目录文件下比如datalogsnamespaceappnamePOdnamelogxxxx.Ioglog-agent内部包含Filebeat,1.ogrotate凄工具,其中Filebeat是作为日志文件收集的agent通过Filebeat将收集的日志发送到KafkaKafka在讲日志发送的ES日志存储Zkibana检索层1.ogstash作为中间工具主要用来在ES中创建index和消费Kafka的消息如果您正在学习SpringBoot,推荐一
33、个连载多年还在继续更新的免费教程整个流程很好理解,但是需要解决的是:用户部署的新应用,如何动态更新Filebeat配置如何保证每个日志文件都被正常的rotate如果需要更多的功能则需要二次开发Filebeat,使Filebeat支持更多的自定义配置付诸实践解决上述问题,就需要开发一个log-agent应用以DaemonSet形式运行在KUberneteS集群的每个节点上,应用内部包含Filebeat,1.OgrOtate和需要开发的功能组件。第一个问题,如何动态更新Filebeat配置,可以利用工具包监听日志目录变化Create、delete事件,利用模板渲染的方法更新Filebeat配置文件。第二个问题,利用工具包创建CrOnJob,定期rotate日志文件,注意应用日志文件所属用户,如果不是root用户所属,可以在配置中设置切换用户。varlogxxxxxxxxx.logsuwww-datawww-dataMissingokNotifemptysizeIGCopytruncate第三个问题,关于二次开发f11ebeat总结本文只是对Kubernetes日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。