本文提供一套生产级的日志采集方案,用于将部署在容器服务 Kubernetes 版 ACK中的应用日志,通过OpenTelemetry Collector进行采集,经由云消息队列 Kafka版进行缓冲,最终持久化到阿里云Elasticsearch(ES)实例中。此方案以声明式YAML配置为核心,旨在实现高效、可靠且可自动化的日志管理。
业务场景说明
在微服务架构下,应用的日志数据量通常非常庞大。如果日志采集组件直接将数据写入ES,当日志流量洪峰或后端ES集群出现性能抖动、不可用时,极易导致日志采集链路中断,甚至引发数据丢失。
本方案通过在采集端与存储端之间引入Kafka作为消息队列,实现两者的解耦。Kafka作为高性能缓冲层,能够平滑处理突发日志流量,增强整个日志系统的稳定性和数据可靠性。即使下游ES暂时不可用,日志数据也会暂存在Kafka中,待恢复后继续消费,从而避免数据丢失。
方案架构
本方案采用两级OpenTelemetry Collector的部署模式:Sidecar采集器和中心化采集器。

工作流程与核心逻辑:
-
Sidecar OTel Collector:作为Sidecar容器与业务应用Pod一同部署。它通过共享卷(
emptyDir)读取应用容器写入的日志文件。采集到的日志数据被发送到指定的Kafka Topic。 -
云消息队列 Kafka 版:作为日志数据的缓冲队列。它接收来自所有Sidecar采集器的日志,为后端消费提供一个统一、稳定的数据源。引入Kafka可以提升架构的稳定性,有效应对日志洪峰。
-
中心化 OTel Collector:作为一个独立的Deployment部署在ACK集群中。它作为Kafka的消费组,从Topic中拉取日志数据,经过处理后,批量写入目标ES集群。
-
阿里云ES:作为日志数据的最终存储和检索系统。
架构决策:为何引入Kafka?
-
应对日志流量的突发性增长:避免后端ES因瞬时写入压力过大而性能下降或拒绝请求。
-
系统解耦:将日志采集端(应用Pod)与存储端(ES)解耦。任何一方的故障或维护都不会直接影响另一方,提升了系统的整体可用性。
-
数据缓冲与可靠性:当ES不可用时,日志数据被暂存在Kafka中,避免了数据丢失。待ES恢复后,中心化Collector会自动追赶消费,确保数据的最终一致性。
实施步骤
1. 环境准备
请确保以下环境和配置已准备就绪:
-
准备 ACK、 ES以及Kafka实例
-
一个可用的容器服务 ACK 集群。
-
一个阿里云 ES 实例。建议开启自动创建索引功能,以便服务能自动根据上报数据创建索引。
进入ES实例的基本信息页面,单击,单击修改配置,选择允许自动创建索引。
-
在Kaffka实例中创建Topic和Group资源。
-
-
确保网络连通性
-
确认 ACK 集群与 ES 实例之间的网络是连通的。如果两者不在同一个专有网络 VPC (Virtual Private Cloud) 内,必须先打通网络。推荐使用 VPC对等连接实现网络互通。
-
-
准备容器镜像
本方案使用 Elastic Agent 的官方镜像。为确保部署的稳定性和可访问性,建议将所需镜像预先拉取并推送到您自己的阿里云容器镜像服务 ACR (Alibaba Cloud Container Registry) 仓库中。
# 拉取官方镜像 docker pull elastic/elastic-agent:9.1.5方案经过测试,
elastic/elastic-agent:9.x版本与8.17版本的 ES 兼容。
2. 在ACK中配置OTel Collector
在ACK中创建两个ConfigMap作为OTel配置文件的引用,分别用于将日志数据输出到Kafka(名为otel2kafka-config)以及用来消费Kafka数据并输出到ES(名为otel-kafka2es-config)。
-
登录ACK控制台,单击。
-
创建配置项:
-
创建名称otel2kafka-config的配置项,具体名称为otel.yml,值为您的otel配置文件内容,用于将日志数据输出到Kafka。
otel.yml示例值,请根据实际配置进行修改,详细otel配置请参见openTelemetryReceivers。
receivers: # 配置文件日志接收器 filelog: include: [/path/to/logs/*.log] # 日志文件路径 exclude: [] # 排除文件列表 start_at: end # 从文件结尾开始读取 multiline: line_start_pattern: ^xxxx # 改为您日志的实际行开头pattern正则 exporters: kafka/logs: brokers: - broker1:9092 - broker2:9092 - broker3:9092 logs: topic: otel-kafka # 您在kafka中创建的用来收集日志的topic producer: compression: zstd # 开启zstd压缩 compression_params: level: 3 # 压缩等级3 service: pipelines: logs: receivers: [filelog] exporters: [kafka/logs] -
创建名称为otel-kafka2es-config的配置项,具体名称为otel.yml,值为您的otel配置文件内容,用来消费Kafka数据并输出到ES。
otel.yml示例值,请根据实际配置进行修改:
receivers: kafka: brokers: - broker1:9092 - broker2:9092 - broker3:9092 logs: topic: otel-kafka # 您在kafka中创建的用来收集日志的topic group_id: gid_otel_collector # 您在kafka中创建的用来收集日志的group_id exporters: elasticsearch/logs: endpoints: ["http://es-cn-xxxxxxpxi00xxxxxx.elasticsearch.aliyuncs.com:9200"] # ES 集群地址 user: "elastic" password: "your_password" tls: insecure_skip_verify: false # 生产环境应设为 true retry: enabled: true initial_interval: 5s max_interval: 30s service: pipelines: logs: receivers: [kafka] exporters: [elasticsearch/logs]
-
-
创建完成后,返回配置项列表。
3. 部署OTel Collector服务
部署OTel Collector服务,用来消费Kafka数据并输出到ES实例。
-
登录容器服务管理控制台,在左侧导航栏选择集群列表。在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。在无状态页面,单击使用镜像创建。
-
在应用基本信息配置向导页面,设置应用的基本信息。然后单击下一步,进入容器配置向导页面。
-
配置容器
在容器配置区域,完成容器的镜像名、端口、环境变量以及数据卷配置。其余设置均为可选设置,保持默认即可。
-
镜像名称:选择在环境准备环节提前准备好的elastic/elastic-agent:9.1.5镜像。
-
环境变量:添加
ELASTIC_AGENT_OTEL,值为true启用 OpenTelemetry 采集模式。 -
数据卷:
-
类型:选择 配置项
-
名称:
kafka2es-config -
挂载源:
otel-kafka2es-configConfigMap -
挂载路径:
/usr/share/elastic-agent/otel.yml(必须严格匹配官方镜像路径) -
子路径:
otel.yml(必须指定,否则会覆盖整个/usr/share/elastic-agent目录)
-
-
-
然后单击下一步,进入高级配置向导页面,保持默认配置,单击创建。
4. 部署应用与 Sidecar 容器
在现有Deployment 或 StatefulSet 的 Pod 模板中添加日志采集 Sidecar 容器的定义,可使需要日志采集的业务 Pod 在创建时自动包含该 Sidecar 容器。以下以 Deployment 为例说明,StatefulSet 的配置方式相同。
-
在Deployment列表中,单击目标 Deployment 名称,进入详情页。
-
单击编辑。
-
在编辑页面,找到数据卷区域,单击增加本地存储为业务容器添加共享日志卷。
重要此处的数据卷作为业务容器与 Sidecar 的共享存储,确保日志文件可被 Sidecar 读取,容器路径必须与业务容器实际日志路径严格一致,否则 Sidecar 无法采集数据。
-
在编辑页面,单击添加容器添加日志采集 Sidecar 容器。
-
镜像名称:选择在环境准备环节提前准备好的elastic/elastic-agent:9.1.5镜像。
-
环境变量:添加
ELASTIC_AGENT_OTEL,值为true启用 OpenTelemetry 采集模式。
-
-
配置 Sidecar 容器的卷挂载,添加两个挂载项:
-
挂载 1:共享日志卷
-
卷名称:选择
app-log(与业务容器共享的卷)。 -
容器路径:
/path/to/logs(与业务容器挂载路径完全一致)。
-
-
挂载 2:OTel 配置文件
-
卷类型:选择
ConfigMap。 -
卷名称:
otel-config(需提前创建的 ConfigMap 名称)。 -
挂载路径:
/usr/share/elastic-agent/otel.yml(必须严格匹配官方镜像路径)。 -
子路径:
otel.yml(关键:仅挂载单个文件,避免覆盖目录)。
-
-
-
确认所有配置无误后,单击更新提交变更。
Kubernetes将自动滚动重启 Pod,新 Pod 会包含业务容器和 Sidecar 容器。
5. 验证方案
-
检查Pod状态:确认中心化OTel Collector和注入了Sidecar的应用Pod都正常运行。
-
查看采集器日志,确认没有错误信息。
-
检查Kafka Topic:确认Topic中有新的日志数据流入。
-
查询Elasticsearch:在Kibana中查询对应的索引,验证新的应用日志是否已成功写入。