针对K8s日志采集存在的采集目标多、弹性伸缩难、运维成本大、侵入性高、采集性能低等问题,阿里云日志服务和容器服务团队设计了阿里云K8s日志解决方案。
用户一分钟内即可完成整个集群部署,并实现集群节点日志、容器日志、容器标准输出等所有数据源的一站式采集。而且,在后续集群动态伸缩的时候,用户也不需要对日志组件做任何二次调整。
9.1 日志服务介绍
阿里云的日志服务是针对日志类数据的一站式服务。日志采集代理Logtail运行在上百万机器上,为数以万计的应用提供服务。阿里云日志服务有如下特点:
- 可靠:经历了“金融级别”的考验,不丢失一条日志。
- 稳定:客户端性能强劲,资源占用率低,在上百万台机器上运行。
- 高吞吐:PB级规模,参数配置灵活,“秒级”出结果。
- 无维负担: 零负担,零代价,零预留成本。
- 生态丰富:完美支撑Hadoop、Spark、Flink等开源产品与阿里云自研技术。
-
迭代快:是阿里共用的一套产品,可第一时间提供新功能。新技术。
从功能角度来看,日志服务主要包括日志采集、离线计算、可视分析以及实时计算等。如下图所示。
9.2 采集方案介绍
9.2.1 方案简介
阿里云K8s日志采集方案如下图所示。K8s的每个节点都会运行一个Logtail容器,该容器可采集宿主机以及该宿主机上容器的日志,包括标准输出和日志文件。
Logtail以集群Daemonset的方式编排,这保证了每个节点都有一个Logtail容器在运行。
同时,此方案使用了自定义标识机器组,支持集群动态缩容和扩容。另外,采集配置支持通过标签以及环境变量过滤指定容器。
K8s内部会注册自定义资源CRD AliyunLogConfig,并部署ALibaba Log Controller控制器。所以,此方案支持用户通过CRD方式或日志服务控制台两种方式对采集配置进行管理。
9.2.2 运行流程
以CRD的配置方式为例,可以把日子方案的工作流程简单总结为6个步骤,如下图所示。
- (1)用户使用kubectl或其他工具应用aliyunlogconfigs CRD配置。
- (2)alibaba-log-controller监听到配置更新。
- (3)alibaba-log-controller根据CRD内容以及服务端状态,自动向日志服务提交创建Logstore、创建配置以及创建应用机器组的请求。
- (4)以DaemonSet模式运行的Logtail会定期请求配置服务器,获取新的或已更新的配置并进行热加载。
- (5)Logtail根据配置信息采集各个容器(Pod)上的标准输出或日志文件。
- (6)最终Logtail将处理、聚合好的数据发送给日志服务。
9.2.3 配置方式
日志采集配置默认支持控制台配置方式,同时针对K8s微服务开发模式,提供了CRD的配置方式,用户可以直接使用命令行对配置进行处理或将其集成到其他编排服务中。两种配置方式的特点如下表所示。
如果刚开始使用日志服务,建议使用控制台的配置方式,此种方式所见即所得,易于上手。
若后续需要将日志采集与服务或组件发布集成,建议使用CRD的配置方式,可以直接将采集配置和服务配置放在同一个Yaml文件中部署和管理。
若后续需要将日志采集于服务或组件发布集成,建议使用CRD的配置方式,可以直接将采集配置和服务配置放到同一个Yaml文件中部署和管理。
9.3 核心技术介绍
9.3.1 背景
不同于其他开源日志采集Agent,日志服务Logtail从设计之初就已经考虑到配置管理的难题。因此Logtail从第一个版本开始就支持中心化的配置管理,支持在日志服务台或者SDK中对所有采集配置进行统一管理,大大降低了日志采集的管理负担。
但在K8s集群环境下,业务应用、服务、组件的持续集成和自动发布已经成为常态,使用控制台或SDK操作采集配置的方式很难与各类CI、编排框架集成,导致业务应用发布后用户只能通过控制台以手动配置的方式部署与之对应的日志采集配置。因此日志服务专门为K8s进行了扩展,用以支持原始的配置管理。
9.3.2 实现方式
如下图所示,日志服务为K8s新增了一个CRD扩展,名为AliyunLogConfig。同时开发了alibaba-controller用于监听AlilyunLogConfig事件。
当用户创建、删除、修改AliyunLogConfig资源时,alibaba-log-controller会监听到资源变化,并在日志服务上创建、删除、修改相应的采集配置,以此实现K8s内部AliyunLogConfig与日志服务中采集配置的关联关系。
9.3.3 allibaba-log-controller内部实现
alibaba-log-controller主要由6个模块组成,各个模块的功能以及依赖关系如下图所示。
EventListener:负责监听AliyunLogConfig的CRD 资源。这个EventListener是广义上的Listener,主要功能有:
- 初始化时会罗列所有的AliyunLogConfig资源。
- 注册AliyunLogConfig监听变化的事件。
- 定期再扫描全部AliyunLogConfig资源,防止事件出现遗漏或处理失效。
- 将事件打包,交由EventHandler处理。
EventHandler:负责处理对应的创建、删除、修改事件,作为Controller的核心模块,主要功能如下: - 首先检查ConfigMapManager中对应的Checkpoint,如该事件已经被处理(版本号相同且状态为200),则直接跳过。
- 为防止历史时间干扰处理结果,从服务端拉去最新的资源状态,检查是否为同一版本,若版本不一致,则使用服务端版本替换。
- 对事件进行一定的预处理,使之符合LogSDK的基本格式需求。
- 调用LogSDKWrapper,创建日志服务Logstore,创建、删除、修改对应的配置。
- 根据上述处理结果,更新对应的AliyunLogConfig资源的状态。
ConfigMapManager:依赖于K8s的ConfigMap机制实现Controller的Checkpoint管理,包括: - 维护Checkpoint到ConfigMap的映射关系。
- 提供基础的Checkpoint增删改查接口。
LogSDKWrapper:基于阿里云LOG golang sdk的二次封装,功能包括: - 初始化创建日志服务资源,包括Project、MachineGroup、OperationLogstore等。
- 将CRD资源转换为对应的日志服务资源操作、CRD与日志服务资源为一对多关系。
- 包装SDK接口,自动处理网络异常、服务器异常、权限异常。
- 负责权限管理,包括自动获取role,更新STS Token。
ScheduledSyner:后台的定期同步模块,防止进程或节点失效期间配置改动而遗漏事件,保证配置管理的最终一致性: - 定期刷新所有的Checkpoint和AliyunLogConfig。
- 检查Checkpoint和AliyunLogConfig资源的映射关系,如果Checkpoint中出现不存在的配置,则删除对应的资源。
- Monitor:alibaba-log-controller除了将本地运行日志输出到stdout外,还会将日志直接采集到日志服务中,便于远程排查问题。采集日志种类如下:
- K8s内部异常日志
- alibaba-log-controller运行日志
- alibaba-log-controller内部异常数据(自动聚合)
9.4 总结
总体来说,阿里云K8s日志解决方案做到了以下三点:
首先打造了极致的不熟体验,用户只要一条命令、一个参数即可完成整个K8s集群的日志解决方案部署。
其次是支持更多配置方式,除原生控制台、SDK配置方式外,还支持通过CRD方式进行配置。
最后是与K8s无缝集成,采集配置支持yaml方式部署,兼容K8s各种集成方式。