K8S采集专题-稳定性:iLogtail容器重启数据可靠性探讨

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 容器场景下iLogtail容器的稳定性对于日志采集的可靠性尤为重要,特别是对于容器重启的情况需要通过特定的配置确保采集状态可恢复。本文简要讲解了iLogtail的状态持久化原理和容器场景状态持久化方案,并详细描述了在K8S和Docker环境下如何配置iLogtail参数和容器参数来解决这种情况下的数据采集的稳定性问题。

2022年10月26日更新

阿里云ACK上的iLogtail组件已经更新,新版组件集成了iLogtail状态持久化配置,本文所提到的手动配置方法可以在ACK上一键升级搞定。步骤如下:

  1. 通过ACK控制台左侧导航,找到组件管理 -> logtail-ds。看到当前版本旁边有个小红点,说明有新版本可升级。

  1. 点击升级,弹出的提示框会显示最新版本。v1.0.34.1及以上版本均自带持久化参数。

需要注意的是,如果以前使用本文方法已经配置了持久化参数的同学需要注意,如果被挂载点主机路径不是/etc/kube-system-logtail-ds/checkpoint则请使用提示的“手动升级”方法进行升级,否则已配置参数会被覆盖,导致升级过程中的数据重复采集。对于此类参数被覆盖的问题后续会进一步对logtail-ds组件进行升级,以组件配置的方式提供组件自定义能力,并保持版本间升级时参数得到传承。

背景

在容器场景下,使用iLogtail DaemonSet方式对采集容器内的日志是最为常见的日志采集方案。这种方式指在每一个K8S节点上部署一个iLogtail采集Agent容器实现对该节点上所属的容器进行日志采集。由于节点上的容器都依赖一个iLogtail容器进行采集,iLogtail容器的可靠性就显得尤为重要。随着业务发展或者环境变化总有一些情况需要iLogtail容器重启:

  1. 容器资源配置过小或节点资源不足导致iLogtail容器被杀死或驱逐
  2. 需要使用新功能,对iLogtail版本进行升级
  3. 需要调整iLogtail配置参数

在默认的参数配置下,iLogtail容器并没有对Logtail的运行状态进行很好的持久化,因此在iLogtail重启后,因采集进度丢失必然导致节点上容器日志重复采集、采集丢失的情况发生。为了保证在正常重启的情况下数据采集不丢不重,异常重启的情况下数据不丢,本文讲详细介绍在容器场景下iLogtail应该如何配置才能做到重启时数据无异常。

状态持久化原理

保存哪些状态

要做到在iLogtail重启时数据无异常,要求iLogtail在重启前后的关键状态是一致的。这里我们首先了解一下iLogtail有哪些关键状态:

  1. 当前iLogtail的采集配置。iLogtail需要采集哪些文件的配置,重启后依赖本地配置恢复采集文件读取进度与采集配置的关系。
  2. 当前容器路径与实际采集路径的映射表。DaemonSet方式容器日志采集的原理是通过挂载宿主机的根目录来采集容器内存文件在宿主机上的对应路径,因此在容器场景下采集配置加上这份映射表才是完整的配置。
  3. 当前所有文件的读取进度。这一点最容易理解,重启前文件读到哪了,那么重启后文件从哪开始读。
  4. 没有来得及发送的缓存数据。理想情况下,iLogtail在退出前现将缓存中的数据发完然后退出,但实际情况是由于网络等原因iLogtail可能无法在较短时间内将缓存的数据发完。为了至少能够在网络异常的情况下退出并做到数据不丢失,iLogtail需要将这些缓存数据持久化到磁盘上。
  5. 插件状态。比如容器标准输出采集插件要记录自己当前采集的标准输出对应的文件名以及偏移量。

什么时候保存

然后,我们来了解一下这些状态记录的时机:

  1. iLogtail的采集配置:拉取到远程的采集配置后在本地生效时。
  2. 容器路径与实际采集路径的映射表:发现容器新增、删除时。
  3. 文件的读取进度:定期,这段时间的长短由参数check_point_dump_interval决定,默认为900秒。iLogtail在退出时也会保存文件的读取进度。
  4. 发送缓存数据:iLogtail退出时。
  5. 插件状态:插件自定义定期以及退出时。

如何恢复

这部分最后,介绍一下重启后状态恢复的过程:

  1. 读取本地保存的iLogtail的采集配置
  2. 读取容器路径与实际采集路径的映射表。
  3. 加载发送缓存数据并启动发送线程。
  4. 恢复插件状态。
  5. 扫描配置的采集路径并通过文件的读取进度重建文件读取器,启动文件读取线程,开始文件采集。

状态持久化参数

参数

类型

说明

示例

user_config_file_path

String

Logtail配置文件的保存路径,默认为进程binary所在目录,文件名为user_log_config.json。

"user_config_file_path" : user_log_config.json

docker_file_cache_path

String

该文件记录了容器文件到宿主机文件的路径映射,默认值:/usr/local/ilogtail/docker_path_config.json。

"docker_file_cache_path": /usr/local/ilogtail/docker_path_config.json

check_point_filename

String

Logtail的checkpoint文件的保存路径, 默认值:/tmp/logtail_check_point。

"check_point_filename" : /tmp/logtail_check_point

check_point_dump_interval

int

Logtail更新Checkpoint文件的周期,默认值:900,单位:秒。即默认情况下每15分钟更新一次Checkpoint文件。

仅支持Logtail 1.0.19及以上版本。

"check_point_dump_interval" : 900

buffer_file_path

String

缓存文件存放目录。 默认值为空,即缓存文件存放于logtail安装目录/usr/local/ilogtail下。

当您设置此参数后,需手动将原目录下名为logtail_buffer_file_*的文件移动到此目录,以保证Logtail可以读取到该缓存文件并在发送后进行删除。

"buffer_file_path" : ""

logtail_sys_conf_dir

String

Logtail系统配置目录。默认值/etc/ilogtail/。存储用户标识机器组用户自定义标识、插件Checkpoint文件等。

"logtail_sys_conf_dir": "/etc/ilogtail/"


容器场景下的状态持久化方案

在主机场景下,这些采集参数的默认值已经可以很好地保证iLogtail进程重启前后的关键状态不丢失,但在容器场景下,容器的存储生命周期默认与容器相同,保存在/usr/local/ilogtail、/tmp和/etc/ilogtail目录下的数据在容器重启后将丢失,因此需要一个方案将iLogtail的状态保存到持久化数据卷上。由于/usr/local/ilogtail/目录与iLogtail镜像中iLogtail安装目录冲突、/tmp是系统临时目录,均不适合挂载持久化数据卷,因此容器场景下的需要调整保存状态的文件路径。

这里我们选择将状态文件都保存到/etc/ilogtail/checkpoint下,保证iLogtail容器正常重启前后数据不丢不重。选择这个目录是由于插件状态文件没有直接的参数可以修改其保存位置,只能继续保留在/etc/ilogtail/checkpoint中,而为了简化部署其他文件在确保不冲突的情况下直接复用该目录。同时修改checkpoint的保存频率,在异常情况下保证数据异常控制在1分钟以内。

  1. 通过容器编排程序将主机的上的目录挂载到容器/etc/ilogtail/checkpoint中,实现容器存储的持久化。
  2. 通过修改ilogtail的状态持久化参数,将状态文件写入到/etc/ilogtail/checkpoint中。
  3. 通过修改ilogtail的状态持久化参数,调整checkpoint频率为60秒。

K8S环境配置

K8S环境下使用hostPath实现主机磁盘挂载。这里以Aliyun ACK中已经部署的iLogtail DaemonSet为例介绍配置过程。(K8S环境下iLogtail的部署请参考:安装iLogtail组件

  1. 在集群管理页面,通过“工作负载”>“守护进程集”>“命名空间:kube-system”找到“logtail-ds”。
  2. 点击“查看Yaml”进行编辑,containers声明中只有logtail一个容器,在原有的env后面追加以下环境变量
            - name: user_config_file_path
              value: '/etc/ilogtail/checkpoint/user_log_config.json'            - name: docker_file_cache_path
              value: '/etc/ilogtail/checkpoint/docker_path_config.json'            - name: check_point_filename
              value: '/etc/ilogtail/checkpoint/logtail_check_point'            - name: check_point_dump_interval
              value: '60'            - name: buffer_file_path
              value: '/etc/ilogtail/checkpoint'
  1. 在原有的volumeMounts后面追加挂载
            - mountPath: /etc/ilogtail/checkpoint
              name: state
  1. 在原有的volumes后追加数据卷声明
        - hostPath:            path: /lib/var/kube-system-logtail-ds/checkpoint
            type: DirectoryOrCreate
          name: state
  1. 最终的yaml应该符合如下的结构。点击“更新”生效配置。
apiVersion: apps/v1
kind: DaemonSet
metadata:  name: logtail-ds
  namespace: kube-system
spec:  template:    spec:      containers:        - env:            - name: user_config_file_path
              value: '/etc/ilogtail/checkpoint/user_log_config.json'            - name: docker_file_cache_path
              value: '/etc/ilogtail/checkpoint/docker_path_config.json'            - name: check_point_filename
              value: '/etc/ilogtail/checkpoint/logtail_check_point'            - name: check_point_dump_interval
              value: '60'            - name: buffer_file_path
              value: '/etc/ilogtail/checkpoint'          name: logtail
          volumeMounts:            - mountPath: /etc/ilogtail/checkpoint
              name: state
      volumes:        - hostPath:            path: /lib/var/kube-system-logtail-ds/checkpoint
            type: DirectoryOrCreate
          name: state

Docker环境配置

Docker环境下直接使用bind mounts的功能实现主机磁盘挂载。(Docker环境下iLogtail的部署请参考:采集标准Docker容器日志

  1. 在命令行参数中增加挂载
-v /lib/var/docker_ilogtail/checkpoint:/etc/ilogtail/checkpoint
  1. 在命令行参数中增加环境变量
-euser_config_file_path=/etc/ilogtail/checkpoint/user_log_config.json
-edocker_file_cache_path=/etc/ilogtail/checkpoint/docker_path_config.json
-echeck_point_filename=/etc/ilogtail/checkpoint/logtail_check_point
-echeck_point_dump_interval=60-ebuffer_file_path=/etc/ilogtail/checkpoint
  1. 最终命令应该符合如下结构
docker run -d--name docker_ilogtail -v /:/logtail_host:ro -v /var/run:/var/run -v /lib/var/docker_ilogtail/checkpoint:/etc/ilogtail/checkpoint -eALIYUN_LOGTAIL_CONFIG=/etc/ilogtail/conf/${your_region_name}/ilogtail_config.json -eALIYUN_LOGTAIL_USER_ID=${your_aliyun_user_id}-eALIYUN_LOGTAIL_USER_DEFINED_ID=${your_machine_group_user_defined_id}-euser_config_file_path=/etc/ilogtail/checkpoint/user_log_config.json -edocker_file_cache_path=/etc/ilogtail/checkpoint/docker_path_config.json -echeck_point_filename=/etc/ilogtail/checkpoint/logtail_check_point -echeck_point_dump_interval=60-ebuffer_file_path=/etc/ilogtail/checkpoint registry.${your_region_name}.aliyuncs.com/log-service/logtail

配置前后效果对比

假设我们已经配置好了采集配置,采集容器中的/root/log/1.log文件。采集容器日志的配置可参考:通过DaemonSet-控制台方式采集容器文本日志

我们在被采集的容器中上创建一个文件并输入一些测试数据

~/log # echo 1 > 1.log; echo 2 >> 1.log; echo 3 >> 1.log

在日志服务控制台观察日志已经采集

接着我们重启logtail-ds。

等待新Pod拉起后,在被采集的容器中追加一条日志触发采集。

~/log # echo 4 >> 1.log

通过控制台查询可知,由于iLogtail状态丢失,日志重复采集了。

然后我们使用上述配置更新logtail-ds的声明,Pod会自动重启。

在业务容器中再次输入以下命令,触发的logtail-ds进行日志采集。

~/log # echo 1 > 1.log; echo 2 >> 1.log; echo 3 >> 1.log

可以到控制台确认数据采集是否成功,这里不再截图。

进入logtail-ds容器,检查/var/lib/ilogtail目录,确认状态是否保存成功。

# ls /var/lib/ilogtail/docker_path_config.json  logtail_check_point  user_log_config.json

可以看到关键的状态文件已经保存到配置的目录下了。

接着我们再次重启logtail-ds。

等待新Pod拉起后,在被采集的容器中追加一条日志触发采集。

~/log # echo 4 >> 1.log

通过控制台查询可知,iLogtail状态持久化生效,采集到的数据完全正常。

总结

追求数据采集准确是每一个从业人员的目标,K8S和Docker容器在给予开发者便利的同时也对日志采集的稳定性提出了新的的挑战。采集容器重启是容器场景下必然会遇到的一种可能导致数据采集异常的场景,本文简要讲解了iLogtail的状态持久化原理和容器场景状态持久化方案,并详细描述了在K8S和Docker环境下如何配置iLogtail参数和容器参数来解决这种场景下的数据采集的稳定性问题。

有些读者可能会疑惑,既然这样进行配置那么好,为什么在阿里云自己的ACK上安装iLogtail日志采集组件没有默认进行这样的配置呢?这是一个很好的建议,在后续的iLogtail组件升级中,我们将会把这种设置变成默认参数,给大家更稳定的日志采集体验。(2022年10月26日更新:组件已完成升级)

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
9天前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
12天前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
142 77
|
10天前
|
人工智能 运维 监控
阿里云ACK容器服务生产级可观测体系建设实践
本文整理自2024云栖大会冯诗淳(花名:行疾)的演讲,介绍了阿里云容器服务团队在生产级可观测体系建设方面的实践。冯诗淳详细阐述了容器化架构带来的挑战及解决方案,强调了可观测性对于构建稳健运维体系的重要性。文中提到,阿里云作为亚洲唯一蝉联全球领导者的容器管理平台,其可观测能力在多项关键评测中表现优异,支持AI、容器网络、存储等多个场景的高级容器可观测能力。此外,还介绍了阿里云容器服务在多云管理、成本优化等方面的最新进展,以及即将推出的ACK AI助手2.0,旨在通过智能引擎和专家诊断经验,简化异常数据查找,缩短故障响应时间。
阿里云ACK容器服务生产级可观测体系建设实践
|
10天前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
阿里云容器服务ACK提供强大的产品能力,支持弹性、调度、可观测、成本治理和安全合规。针对拥有IDC或三方资源的企业,ACK One分布式云容器平台能够有效解决资源管理、多云多集群管理及边缘计算等挑战,实现云上云下统一管理,提升业务效率与稳定性。
|
20天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
54 7
|
22天前
|
运维 Kubernetes Docker
深入理解容器化技术:Docker与Kubernetes的协同工作
深入理解容器化技术:Docker与Kubernetes的协同工作
43 1
|
22天前
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
40 1
|
24天前
|
Kubernetes Cloud Native API
深入理解Kubernetes——容器编排的王者之道
深入理解Kubernetes——容器编排的王者之道
36 1
|
1月前
|
Kubernetes Cloud Native 持续交付
深入理解Kubernetes:容器编排的基石
深入理解Kubernetes:容器编排的基石
|
26天前
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。

相关产品

  • 容器服务Kubernetes版
  • 下一篇
    DataWorks