系列文章:Kubernetes日志采集最佳实践
前言
上一期主要介绍Kubernetes日志输出的一些注意事项,日志输出最终的目的还是做统一的采集和分析。在Kubernetes中,日志采集和普通虚拟机的方式有很大不同,相对实现难度和部署代价也略大,但若使用恰当则比传统方式自动化程度更高、运维代价更低。
Kubernetes日志采集难点
在Kubernetes中,日志采集相比传统虚拟机、物理机方式要复杂很多,最根本的原因是Kubernetes把底层异常屏蔽,提供更加细粒度的资源调度,向上提供稳定、动态的环境。因此日志采集面对的是更加丰富、动态的环境,需要考虑的点也更加的多。
例如:
- 对于运行时间很短的Job类应用,从启动到停止只有几秒的时间,如何保证日志采集的实时性能够跟上而且数据不丢?
- K8s一般推荐使用大规格节点,每个节点可以运行10-100+的容器,如何在资源消耗尽可能低的情况下采集100+的容器?
- 在K8s中,应用都以yaml的方式部署,而日志采集还是以手工的配置文件形式为主,如何能够让日志采集以K8s的方式进行部署?
Kubernetes | 传统方式 | |
---|---|---|
日志种类 | 文件、stdout、宿主机文件、journal | 文件、journal |
日志源 | 业务容器、系统组件、宿主机 | 业务、宿主机 |
采集方式 | Agent(Sidecar、DaemonSet)、直写(DockerEngine、业务) | Agent、直写 |
单机应用数 | 10-100 | 1-10 |
应用动态性 | 高 | 低 |
节点动态性 | 高 | 低 |
采集部署方式 | 手动、Yaml | 手动、自定义 |
采集方式:主动 or 被动
日志的采集方式分为被动采集和主动推送两种,在K8s中,被动采集一般分为Sidecar和DaemonSet两种方式,主动推送有DockerEngine推送和业务直写两种方式。
- DockerEngine本身具有LogDriver功能,可通过配置不同的LogDriver将容器的stdout通过DockerEngine写入到远端存储,以此达到日志采集的目的。这种方式的可定制化、灵活性、资源隔离性都很低,一般不建议在生产环境中使用。
- 业务直写是在应用中集成日志采集的SDK,通过SDK直接将日志发送到服务端。这种方式省去了落盘采集的逻辑,也不需要额外部署Agent,对于系统的资源消耗最低,但由于业务和日志SDK强绑定,整体灵活性很低,一般只有日志量极大的场景中使用。
- DaemonSet方式在每个node节点上只运行一个日志agent,采集这个节点上所有的日志。DaemonSet相对资源占用要小很多,但扩展性、租户隔离性受限,比较适用于功能单一或业务不是很多的集群。
- Sidecar方式为每个POD单独部署日志agent,这个agent只负责一个业务应用的日志采集。Sidecar相对资源占用较多,但灵活性以及多租户隔离性较强,建议大型的K8S集群或作为PAAS平台为多个业务方服务的集群使用该方式。
总结下来:DockerEngine直写一般不推荐;业务直写推荐在日志量极大的场景中使用;DaemonSet一般在中小型集群中使用;Sidecar推荐在超大型的集群中使用。详细的各种采集方式对比如下:
DockerEngine | 业务直写 | DaemonSet方式 | Sidecar方式 | |
---|---|---|---|---|
采集日志类型 | 标准输出 | 业务日志 | 标准输出+部分文件 | 文件 |
部署运维 | 低,原生支持 | 低,只需维护好配置文件即可 | 一般,需维护DaemonSet | 较高,每个需要采集日志的POD都需要部署sidecar容器 |
日志分类存储 | 无法实现 | 业务独立配置 | 一般,可通过容器/路径等映射 | 每个POD可单独配置,灵活性高 |
多租户隔离 | 弱 | 弱,日志直写会和业务逻辑竞争资源 | 一般,只能通过配置间隔离 | 强,通过容器进行隔离,可单独分配资源 |
支持集群规模 | 本地存储无限制,若使用syslog、fluentd会有单点限制 | 无限制 | 取决于配置数 | 无限制 |
资源占用 | 低,docker | |||
engine提供 | 整体最低,省去采集开销 | 较低,每个节点运行一个容器 | 较高,每个POD运行一个容器 | |
查询便捷性 | 低,只能grep原始日志 | 高,可根据业务特点进行定制 | 较高,可进行自定义的查询、统计 | 高,可根据业务特点进行定制 |
可定制性 | 低 | 高,可自由扩展 | 低 | 高,每个POD单独配置 |
耦合度 | 高,与DockerEngine强绑定,修改需要重启DockerEngine | 高,采集模块修改/升级需要重新发布业务 | 低,Agent可独立升级 | 一般,默认采集Agent升级对应Sidecar业务也会重启(有一些扩展包可以支持Sidecar热升级) |
适用场景 | 测试、POC等非生产场景 | 对性能要求极高的场景 | 日志分类明确、功能较单一的集群 | 大型、混合型、PAAS型集群 |
日志输出:Stdout or 文件
和虚拟机/物理机不同,K8s的容器提供标准输出和文件两种方式。在容器中,标准输出将日志直接输出到stdout或stderr,而DockerEngine接管stdout和stderr文件描述符,将日志接收后按照DockerEngine配置的LogDriver规则进行处理;日志打印到文件的方式和虚拟机/物理机基本类似,只是日志可以使用不同的存储方式,例如默认存储、EmptyDir、HostVolume、NFS等。
虽然使用Stdout打印日志是Docker官方推荐的方式,但大家需要注意这个推荐是基于容器只作为简单应用的场景,实际的业务场景中我们还是建议大家尽可能使用文件的方式,主要的原因有以下几点:
- Stdout性能问题,从应用输出stdout到服务端,中间会经过好几个流程(例如普遍使用的JSON LogDriver):应用stdout -> DockerEngine -> LogDriver -> 序列化成JSON -> 保存到文件 -> Agent采集文件 -> 解析JSON -> 上传服务端。整个流程相比文件的额外开销要多很多,在压测时,每秒10万行日志输出就会额外占用DockerEngine 1个CPU核。
- Stdout不支持分类,即所有的输出都混在一个流中,无法像文件一样分类输出,通常一个应用中有AccessLog、ErrorLog、InterfaceLog(调用外部接口的日志)、TraceLog等,而这些日志的格式、用途不一,如果混在同一个流中将很难采集和分析。
- Stdout只支持容器的主程序输出,如果是daemon/fork方式运行的程序将无法使用stdout。
- 文件的Dump方式支持各种策略,例如同步/异步写入、缓存大小、文件轮转策略、压缩策略、清除策略等,相对更加灵活。
因此我们建议线上应用使用文件的方式输出日志,Stdout只在功能单一的应用或一些K8s系统/运维组件中使用。
CICD集成:Logging Operator
Kubernetes提供了标准化的业务部署方式,可以通过yaml(K8s API)来声明路由规则、暴露服务、挂载存储、运行业务、定义缩扩容规则等,所以Kubernetes很容易和CICD系统集成。而日志采集也是运维监控过程中的重要部分,业务上线后的所有日志都要进行实时的收集。
原始的方式是在发布之后手动去部署日志采集的逻辑,这种方式需要手工干预,违背CICD自动化的宗旨;为了实现自动化,有人开始基于日志采集的API/SDK包装一个自动部署的服务,在发布后通过CICD的webhook触发调用,但这种方式的开发代价很高。
在Kubernetes中,日志最标准的集成方式是以一个新资源注册到Kubernetes系统中,以Operator(CRD)的方式来进行管理和维护。在这种方式下,CICD系统不需要额外的开发,只需在部署到Kubernetes系统时附加上日志相关的配置即可实现。
Kubernetes日志采集方案
早在Kubernetes出现之前,我们就开始为容器环境开发日志采集方案,随着K8s的逐渐稳定,我们开始将很多业务迁移到K8s平台上,因此也基于之前的基础专门开发了一套K8s上的日志采集方案。主要具备的功能有:
- 支持各类数据的实时采集,包括容器文件、容器Stdout、宿主机文件、Journal、Event等;
- 支持多种采集部署方式,包括DaemonSet、Sidecar、DockerEngine LogDriver等;
- 支持对日志数据进行富化,包括附加Namespace、Pod、Container、Image、Node等信息;
- 稳定、高可靠,基于阿里自研的Logtail采集Agent实现,目前全网已有几百万的部署实例;
- 基于CRD进行扩展,可使用Kubernetes部署发布的方式来部署日志采集规则,与CICD完美集成。
安装日志采集组件
目前这套采集方案已经对外开放,我们提供了一个Helm安装包,其中包括Logtail的DaemonSet、AliyunlogConfig的CRD声明以及CRD Controller,安装之后就能直接使用DaemonSet采集以及CRD配置了。安装方式如下:
- 阿里云Kubernetes集群在开通的时候可以勾选安装,这样在集群创建的时候会自动安装上述组件。如果开通的时候没有安装,则可以手动安装。
- 如果是自建的Kubernetes,无论是在阿里云上自建还是在其他云或者是线下,也可以使用这样采集方案,具体安装方式参考[自建Kubernetes安装]()。
安装好上述组件之后,Logtail和对应的Controller就会运行在集群中,但默认这些组件并不会采集任何日志,需要配置日志采集规则来采集指定Pod的各类日志。
采集规则配置:环境变量 or CRD
除了在日志服务控制台上手动配置之外,对于Kubernetes还额外支持两种配置方式:环境变量和CRD。
环境变量是自swarm时代一直使用的配置方式,只需要在想要采集的容器环境变量上声明需要采集的数据地址即可,Logtail会自动将这些数据采集到服务端。这种方式部署简单,学习成本低,很容易上手;但能够支持的配置规则很少,很多高级配置(例如解析方式、过滤方式、黑白名单等)都不支持,而且这种声明的方式不支持修改/删除,每次修改其实都是创建1个新的采集配置,历史的采集配置需要手动清理,否则会造成资源浪费。
CRD配置方式是非常符合Kubernetes官方推荐的标准扩展方式,让采集配置以K8s资源的方式进行管理,通过向Kubernetes部署AliyunLogConfig这个特殊的CRD资源来声明需要采集的数据。例如下面的示例就是部署一个容器标准输出的采集,其中定义需要Stdout和Stderr都采集,并且排除环境变量中包含COLLEXT_STDOUT_FLAG:false的容器。
基于CRD的配置方式以Kubernetes标准扩展资源的方式进行管理,支持配置的增删改查完整语义,而且支持各种高级配置,是我们极其推荐的采集配置方式。
采集规则推荐的配置方式
实际应用场景中,一般都是使用DaemonSet或DaemonSet与Sidecar混用方式,DaemonSet的优势是资源利用率高,但有一个问题是DaemonSet的所有Logtail都共享全局配置,而单一的Logtail有配置支撑的上限,因此无法支撑应用数比较多的集群。
上述是我们给出的推荐配置方式,核心的思想是:
- 一个配置尽可能多的采集同类数据,减少配置数,降低DaemonSet压力;
- 核心的应用采集要给予充分的资源,可以使用Sidecar方式;
- 配置方式尽可能使用CRD方式;
- Sidecar由于每个Logtail是单独的配置,所以没有配置数的限制,这种比较适合于超大型的集群使用。
实践1-中小型集群
绝大部分Kubernetes集群都属于中小型的,对于中小型没有明确的定义,一般应用数在500以内,节点规模1000以内,没有职能明确的Kubernetes平台运维。这种场景应用数不会特别多,DaemonSet可以支撑所有的采集配置:
实践2-大型集群
对于一些用作PAAS平台的大型/超大型集群,一般业务在1000以上,节点规模也在1000以上,有专门的Kubernetes平台运维人员。这种场景下应用数没有限制,DaemonSet无法支持,因此必须使用Sidecar方式,整体规划如下:
- Kubernetes平台本身的系统组件日志、内核日志相对种类固定,这部分日志使用DaemonSet采集,主要为平台的运维人员提供服务;
- 各个业务的日志使用Sidecar方式采集,每个业务可以独立设置Sidecar的采集目的地址,为业务的DevOps人员提供足够的灵活性。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring Cloud Alibaba v2.2.0 发布
升级核心依赖 Spring Cloud Hoxton.RELEASE Seata 1.0.0 Sentinel 1.7.1 Apache Dubbo 2.7.4.1 更新日志 新增 NacosConfigHealthIndicator ,服务状态Actuator 优化 NacosWatch,重构线程池 优化 NacosServiceRegistry 服务注册异常抛出 Seata 支持 Feign 新的负载均衡器 FeignBlockingLoadBalancerClient 使用Spring Boot 2.2.1新特性 @Configuration(proxyBeanMethods=false) 减少无用代理开销 Nacos支持ReactiveDiscoveryClient Sentinel 使用SentinelWebInterceptor 代替 CommonFilter Nacos 相关配置增加默认的服务地址 localhost:8848 Sentinel 迁移为spring-cloud-circuitbreaker-sentinel 优化RocketMQBinderConfigur...
- 下一篇
【产品解读】阿里云 Elasticsearch 在日志场景中实现“低成本高性能”
本文字数:1435预计阅读:3~5分钟 您将了解:1、数据写入导致的高并发集群打爆问题,如何解决?2、TB、PB级数据如何降低存储成本?3、原生Elasticsearch在时序查询上的瓶颈如何突破?4、峰谷差异大,如何避免闲置成本? 【全链路云上Elastic Stack 全景图】100%兼容开源,9大独有能力 ----> 直播回顾 | 请点击观看 :阿里云Elasticsearch日志增强版介绍 寻根问源 日志场景面临的问题 日志场景是Elasticsearch使用中较为常见的场景,而大量日志数据让企业在追求经济效应与性能效应的同时,对产品本身提出了更为苛刻的要求。 1、高并发写入问题:Elasticsearch在日志数据写入过程中,会同时对主副分片同步写入,还会去写开销较大的trancelog,从而造成Elasticsearch在
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8编译安装MySQL8.0.19
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境