如何将AWS CloudWatch日志发送至K8s集群中的Loki?
方案:将AWS API Gateway CloudWatch日志归集至K8s Loki
工具选择建议
优先用Fluent Bit:资源占用低(内存通常几十MB)、性能适配K8s环境,AWS官方镜像已内置CloudWatch插件,部署成本低。如果需要复杂日志处理(多步骤过滤、自定义解析),再考虑用Fluentd(资源占用更高,需自定义镜像安装插件)。
方案一:Fluent Bit实现流程
1. 权限准备
通过**IRSA(IAM Roles for Service Accounts)**给Fluent Bit的K8s服务账号赋予CloudWatch日志读取权限,避免硬编码密钥:
- 创建IAM角色,关联权限政策:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:GetLogEvents" ], "Resource": "arn:aws:logs:<你的AWS区域>:<账号ID>:log-group:/aws/api-gateway/<你的API名称>:*" } ] }
- 给K8s ServiceAccount添加IRSA注解,关联上述IAM角色:
apiVersion: v1 kind: ServiceAccount metadata: name: fluent-bit-cloudwatch namespace: logging annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<账号ID>:role/<你的IAM角色名>
2. 输入插件选择:cloudwatch
Fluent Bit官方内置的CloudWatch输入插件,直接支持拉取CloudWatch日志流,无需额外中间件。
3. K8s部署配置
ConfigMap(核心配置)
apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config namespace: logging data: fluent-bit.conf: | [SERVICE] Flush 1 Log_Level info Daemon off Parsers_File parsers.conf # CloudWatch输入配置 [INPUT] Name cloudwatch Region <你的AWS区域> Log_Group_Name /aws/api-gateway/<你的API名称> Log_Stream_Prefix API-Gateway-Execution-Logs_ # API Gateway日志流固定前缀 Poll_Interval 10 Tag api-gateway.* # 给日志添加自定义标识,方便Loki过滤 [FILTER] Name modify Match api-gateway.* Add cluster_name <你的K8s集群名> Add service api-gateway # 输出到Loki [OUTPUT] Name loki Match api-gateway.* Host loki.logging.svc.cluster.local # Loki集群内服务地址 Port 3100 Labels job=api-gateway-cloudwatch,cluster=${cluster_name},service=${service} Label_Keys log_stream BatchWait 1 BatchSize 10240
Deployment(运行Fluent Bit)
apiVersion: apps/v1 kind: Deployment metadata: name: fluent-bit-cloudwatch namespace: logging labels: app: fluent-bit-cloudwatch spec: replicas: 1 selector: matchLabels: app: fluent-bit-cloudwatch template: metadata: labels: app: fluent-bit-cloudwatch spec: serviceAccountName: fluent-bit-cloudwatch containers: - name: fluent-bit image: amazon/aws-for-fluent-bit:latest # AWS官方镜像,内置CloudWatch插件 volumeMounts: - name: config-volume mountPath: /fluent-bit/etc/ volumes: - name: config-volume configMap: name: fluent-bit-config
方案二:Fluentd实现流程
1. 权限准备
同Fluent Bit,用IRSA给ServiceAccount绑定CloudWatch读取权限。
2. 输入插件选择:fluent-plugin-cloudwatch-logs
需自定义Fluentd镜像,安装该插件和Loki输出插件:
FROM fluent/fluentd:v1.16-debian-1 USER root RUN gem install fluent-plugin-cloudwatch-logs fluent-plugin-loki USER fluent
3. K8s部署配置
ConfigMap(核心配置)
apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config namespace: logging data: fluentd.conf: | # CloudWatch输入 <source> @type cloudwatch_logs aws_region <你的AWS区域> log_group_name /aws/api-gateway/<你的API名称> log_stream_prefix API-Gateway-Execution-Logs_ tag api-gateway.* <interval> @type time interval 10s </interval> </source> # 添加自定义标识 <filter api-gateway.*> @type record_transformer <record> cluster_name "<你的K8s集群名>" service "api-gateway" </record> </filter> # 输出到Loki <match api-gateway.*> @type loki url http://loki.logging.svc.cluster.local:3100 <label> job "api-gateway-cloudwatch" cluster ${record["cluster_name"]} service ${record["service"]} log_stream ${tag_suffix[2]} </label> flush_interval 10s </match>
Deployment(运行Fluentd)
apiVersion: apps/v1 kind: Deployment metadata: name: fluentd-cloudwatch namespace: logging labels: app: fluentd-cloudwatch spec: replicas: 1 selector: matchLabels: app: fluentd-cloudwatch template: metadata: labels: app: fluentd-cloudwatch spec: serviceAccountName: fluentd-cloudwatch containers: - name: fluentd image: <你的自定义Fluentd镜像地址> resources: requests: memory: 256Mi cpu: 200m limits: memory: 512Mi cpu: 500m volumeMounts: - name: config-volume mountPath: /fluentd/etc/ volumes: - name: config-volume configMap: name: fluentd-config
验证方法
- 查看Fluent Bit/Fluentd的Pod日志,确认无权限错误、连接错误
- 登录Grafana(或Loki UI),用标签
job=api-gateway-cloudwatch查询,验证是否能看到API Gateway的日志
内容的提问来源于stack exchange,提问作者Domenico
相关产品推荐
相关产品推荐

