

# 将日志发送到 CloudWatch Logs
<a name="Container-Insights-EKS-logs"></a>

要将日志从您的容器发送到 Amazon CloudWatch Logs，您可以使用 Fluent Bit。有关更多信息，请参阅 [Fluent Bit](https://fluentbit.io/)。

**注意**  
自 2025 年 2 月 10 日起，AWS 已不再支持使用 FluentD 作为 CloudWatch Logs 的日志转发器。我们建议您使用 Fluent Bit，这是一种轻量级的资源高效型替代方案。现有的 FluenTD 部署将继续正常运行。将您的日志记录管道迁移到 Fluent Bit，以确保继续获得支持和实现最佳性能。  
Container Insights 以前还支持使用 FluentD 从容器发送日志。FluenTD 已被弃用，现在不支持 Container Insights。改为使用 Fluent Bit。

**Topics**
+ [将 Fluent Bit 设置为 DaemonSet 以将日志发送到 CloudWatch Logs](Container-Insights-setup-logs-FluentBit.md)
+ [（可选）设置 Amazon EKS 控制面板日志记录](Container-Insights-setup-control-plane-logging.md)
+ [（可选）为大型集群启用 Use\$1Kubelet 功能](ContainerInsights-use-kubelet.md)

# 将 Fluent Bit 设置为 DaemonSet 以将日志发送到 CloudWatch Logs
<a name="Container-Insights-setup-logs-FluentBit"></a>

以下部分帮助您部署 Fluent Bit 以将日志从容器发送到 CloudWatch Logs。

**Topics**
+ [设置 Fluent Bit](#Container-Insights-FluentBit-setup)
+ [多行日志支持](#ContainerInsights-fluentbit-multiline)
+ [（可选）从 Fluent Bit 减少日志卷](#ContainerInsights-fluentbit-volume)
+ [问题排查](#Container-Insights-FluentBit-troubleshoot)
+ [控制面板](#Container-Insights-FluentBit-dashboard)

## 设置 Fluent Bit
<a name="Container-Insights-FluentBit-setup"></a>

要设置 Fluent Bit 以从容器中收集日志，您可以按照 [Amazon EKS 和 Kubernetes 上的 Container Insights 的快速入门设置](Container-Insights-setup-EKS-quickstart.md) 中的步骤操作，也可以按照本节中的步骤操作。

无论使用哪种方法，附加到集群节点的 IAM 角色必须具有足够的权限。有关运行 Amazon EKS 集群所需权限的更多信息，请参阅 *Amazon EKS 用户指南*中的 [Amazon EKS IAM 策略、角色和权限](https://docs.aws.amazon.com/eks/latest/userguide/IAM_policies.html)。

在以下步骤中，您将 Fluent Bit 设置为 daemonSet 以将日志发送到 CloudWatch Logs。在完成该步骤时，Fluent Bit 将创建以下日志组（如果尚不存在）。

**重要**  
如果您已经在 Container Insights 中配置了 FluentD 并且 FluentD DaemonSet 没有按预期运行（如果您使用 `containerd` 运行时系统可能会发生这种情况），则必须在安装 Fluent Bit 之前将其卸载，以防止 Fluent Bit 处理 FluentD 错误日志消息。否则，您必须在成功安装 Fluent Bit 后立即卸载 FluentD。在安装 Fluent Bit 后卸载 Fluentd 可确保在此迁移过程中日志记录的连续性。将日志发送到 CloudWatch Logs 只需要 Fluent Bit 或 FluentD 中的其中一个。


| 日志组名称 | 日志源 | 
| --- | --- | 
|  `/aws/containerinsights/Cluster_Name/application`  |  `/var/log/containers` 中的所有日志文件  | 
|  `/aws/containerinsights/Cluster_Name/host`  |  `/var/log/dmesg`、`/var/log/secure` 和 `/var/log/messages` 中的日志  | 
|  `/aws/containerinsights/Cluster_Name/dataplane`  |  `kubelet.service`、`kubeproxy.service` 和 `docker.service` 的 `/var/log/journal` 中的日志。  | 

**安装 Fluent Bit 以将日志从容器发送到 CloudWatch Logs**

1. 如果您还没有名为 `amazon-cloudwatch` 的命名空间，请通过输入以下命令创建一个：

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
   ```

1. 运行以下命令以创建一个名为 `cluster-info` 的 ConfigMap，该 ConfigMap 以集群名称和要向其发送日志的区域命名。将 *cluster-name* 和 *cluster-region* 分别替换为您的集群的名称和区域。

   ```
   ClusterName=cluster-name
   RegionName=cluster-region
   FluentBitHttpPort='2020'
   FluentBitReadFromHead='Off'
   [[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
   [[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
   kubectl create configmap fluent-bit-cluster-info \
   --from-literal=cluster.name=${ClusterName} \
   --from-literal=http.server=${FluentBitHttpServer} \
   --from-literal=http.port=${FluentBitHttpPort} \
   --from-literal=read.head=${FluentBitReadFromHead} \
   --from-literal=read.tail=${FluentBitReadFromTail} \
   --from-literal=logs.region=${RegionName} -n amazon-cloudwatch
   ```

   在此命令中，默认情况下，用于监控插件指标的 `FluentBitHttpServer` 处于启用状态。要将其关闭，请将命令中的第三行更改为命令中的 `FluentBitHttpPort=''`（空字符串）。

   同样，默认情况下，Fluent Bit 从尾部读取日志文件，并在部署后仅捕获新日志。如果您想要相反的设置，请设置 `FluentBitReadFromHead='On'`，它将收集文件系统中的所有日志。

1. 运行以下任一命令，将 Fluent Bit daemonset 下载并部署到集群中。
   + 如果需要针对 Linux 计算机的 Fluent Bit 优化配置，则请运行此命令。

     ```
     kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
     ```
   + 如果需要针对 Windows 计算机的 Fluent Bit 优化配置，则请运行此命令。

     ```
     kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit-windows.yaml
     ```
   + 如果使用 Linux 计算机且需要更类似于 Fluentd 的 Fluent Bit 配置，则请运行此命令。

     ```
     kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit-compatible.yaml
     ```
**重要**  
默认情况下，Fluent Bit 守护程序集配置会将日志级别设置为 INFO，这可能会导致 CloudWatch Logs 摄取成本增加。要减少日志摄取量和成本，您可以将日志级别更改为 ERROR。  
有关如何减少日志量的更多信息，请参阅 [（可选）从 Fluent Bit 减少日志卷](#ContainerInsights-fluentbit-volume)。

1. 运行以下命令以验证部署。每个节点应具有一个名为 **fluent-bit-\$1** 的 pod。

   ```
   kubectl get pods -n amazon-cloudwatch
   ```

上述步骤在集群中创建了以下资源：
+ `amazon-cloudwatch` 命名空间中名为 `Fluent-Bit` 的服务账户。该服务账户用于运行 Fluent Bit daemonSet。有关更多信息，请参阅《Kubernetes 参考》中的 [管理服务账户](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/)。
+ `amazon-cloudwatch` 命名空间中名为 `Fluent-Bit-role` 的集群角色。该集群角色为 `Fluent-Bit` 服务账户授予有关 pod 日志的 `get`、`list` 和 `watch` 权限。有关更多信息，请参阅《Kubernetes 参考》中的 [API 概述](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#api-overview/)。
+ `amazon-cloudwatch` 命名空间中的名为 `Fluent-Bit-config` 的 ConfigMap。该 ConfigMap 包含由 Fluent Bit 使用的配置。有关更多信息，请参阅《Kubernetes 任务》文档中的 [配置 Pod 以使用 ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/)。

如果要验证 Fluent Bit 设置，请按照下列步骤操作。

**验证 Fluent Bit 设置**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择 **Log groups（日志组）**。

1. 确保您位于部署 Fluent Bit 的区域中。

1. 检查区域中的日志组列表。您将看到以下内容：
   + `/aws/containerinsights/Cluster_Name/application`
   + `/aws/containerinsights/Cluster_Name/host`
   + `/aws/containerinsights/Cluster_Name/dataplane`

1. 导航到其中一个日志组，并检查日志流的 **Last Event Time（上次事件时间）**。如果相对于您部署 Fluent Bit 的时间，它是最近的，则会验证设置。

   创建 `/dataplane` 日志组时，可能会稍有延迟。这是正常的，因为只有在 Fluent Bit 开始为该日志组发送日志时才会创建这些日志组。

## 多行日志支持
<a name="ContainerInsights-fluentbit-multiline"></a>

有关如何将 Fluent Bit 用于多行日志的信息，请参阅 Fluent Bit 文档的以下部分：
+ [多行解析](https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/multiline-parsing)
+ [多行和容器（v1.8）](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-and-containers-v1.8)
+ [多行核心（v1.8）](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-core-v1.8)
+ [始终在尾部输入中使用多行](https://github.com/aws/aws-for-fluent-bit/blob/mainline/troubleshooting/debugging.md#always-use-multiline-the-tail-input)

## （可选）从 Fluent Bit 减少日志卷
<a name="ContainerInsights-fluentbit-volume"></a>

默认情况下，我们将 Fluent Bit 应用程序日志和 Kubernetes 元数据发送到 CloudWatch。如果您要减少发送到 CloudWatch 的数据量，可以停止将这些数据源中的一个或两个发送到 CloudWatch。如果您已按照本页上的步骤设置 Fluent Bit，则请通过之前运行的 kubectl `apply` 命令下载 Kubernetes 清单 YAML 文件，并根据您的更改对其进行修改，然后可以将其重新应用到集群。或者，如果您使用的是 Amazon CloudWatch 可观测性 EKS 加载项或 Helm 图表，则请参阅 [（可选）其他配置](install-CloudWatch-Observability-EKS-addon.md#install-CloudWatch-Observability-EKS-addon-configuration)，了解有关使用加载项的高级配置或 Helm 图表管理 Fluent Bit 配置的信息。

要停止 Fluent Bit 应用程序日志，请从 `Fluent Bit configuration` 文件中删除以下部分。

```
[INPUT]
        Name                tail
        Tag                 application.*
        Path                /var/log/containers/fluent-bit*
        Parser              docker
        DB                  /fluent-bit/state/flb_log.db
        Mem_Buf_Limit       5MB
        Skip_Long_Lines     On
        Refresh_Interval    10
```

要取消将 Kubernetes 元数据附加到发送到 CloudWatch 的日志事件，请在 Fluent Bit 配置的 `application-log.conf` 部分中添加以下筛选条件。将 *<Metadata\$11>* 和类似字段替换为实际的元数据标识符。

```
application-log.conf: |
    [FILTER]
        Name                nest
        Match               application.*
        Operation           lift
        Nested_under        kubernetes
        Add_prefix          Kube.

    [FILTER]
        Name                modify
        Match               application.*
        Remove              Kube.<Metadata_1>
        Remove              Kube.<Metadata_2>
        Remove              Kube.<Metadata_3>
    
    [FILTER]
        Name                nest
        Match               application.*
        Operation           nest
        Wildcard            Kube.*
        Nested_under        kubernetes
        Remove_prefix       Kube.
```

## 问题排查
<a name="Container-Insights-FluentBit-troubleshoot"></a>

如果您没有看到这些日志组并且查看的是正确区域，请检查 Fluent Bit daemonSet pod 日志以查找错误。

运行以下命令，并确保状态为 `Running`。

```
kubectl get pods -n amazon-cloudwatch
```

如果日志具有与 IAM 权限相关的错误，请检查附加到集群节点的 IAM 角色。有关运行 Amazon EKS 集群所需权限的更多信息，请参阅 *Amazon EKS 用户指南*中的 [Amazon EKS IAM 策略、角色和权限](https://docs.aws.amazon.com/eks/latest/userguide/IAM_policies.html)。

如果 pod 状态为 `CreateContainerConfigError`，请运行以下命令以获取确切的错误。

```
kubectl describe pod pod_name -n amazon-cloudwatch
```

## 控制面板
<a name="Container-Insights-FluentBit-dashboard"></a>

您可以创建一个控制面板来监控每个正在运行的插件的指标。您可以查看输入和输出字节以及记录处理率以及输出错误和重试/失败率的数据。要查看这些指标，您需要为 Amazon EKS 和 Kubernetes 集群安装带有 Prometheus 指标集合的 CloudWatch 代理。有关如何设置控制面板的更多信息，请参阅 [在 Amazon EKS 和 Kubernetes 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理在 Amazon EKS 和 Kubernetes 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理](ContainerInsights-Prometheus-Setup.md)。

**注意**  
在设置此控制面板之前，您必须为 Prometheus 指标设置 Container Insights。有关更多信息，请参阅 [Container Insights Prometheus 指标监控](ContainerInsights-Prometheus.md)。

**为 Fluent Bit Prometheus 指标创建控制面板**

1. 创建环境变量，替换以下行中右侧的值以匹配您的部署。

   ```
   DASHBOARD_NAME=your_cw_dashboard_name
   REGION_NAME=your_metric_region_such_as_us-west-1
   CLUSTER_NAME=your_kubernetes_cluster_name
   ```

1. 通过运行以下命令来创建控制面板。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_cloudwatch_dashboards/fluent-bit/cw_dashboard_fluent_bit.json \
   | sed "s/{{YOUR_AWS_REGION}}/${REGION_NAME}/g" \
   | sed "s/{{YOUR_CLUSTER_NAME}}/${CLUSTER_NAME}/g" \
   | xargs -0 aws cloudwatch put-dashboard --dashboard-name ${DASHBOARD_NAME} --dashboard-body
   ```

# （可选）设置 Amazon EKS 控制面板日志记录
<a name="Container-Insights-setup-control-plane-logging"></a>

如果使用的是 Amazon EKS，您可以选择启用 Amazon EKS 控制面板日志记录，以直接从 Amazon EKS 控制面板中向 CloudWatch Logs 提供审计和诊断日志。有关更多信息，请参阅 [Amazon EKS 控制面板日志记录](https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html)。

# （可选）为大型集群启用 Use\$1Kubelet 功能
<a name="ContainerInsights-use-kubelet"></a>

默认情况下，在 FluentBit Kubernetes 插件中禁用 Use\$1Kubelet 功能。启用此功能可以减少 API 服务器的流量，并缓解 API 服务器成为瓶颈的问题。我们建议您为大型集群启用此功能。

要启用 Use\$1Kubelet，请先将节点和节点/代理权限添加到 clusterRole config 中。

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluent-bit-role
rules:
  - nonResourceURLs:
      - /metrics
    verbs:
      - get
  - apiGroups: [""]
    resources:
      - namespaces
      - pods
      - pods/logs
      - nodes
      - nodes/proxy
    verbs: ["get", "list", "watch"]
```

在 DaemonSet 配置中，此功能需要主机网络访问权限。适用于 `amazon/aws-for-fluent-bit` 的镜像版本应为 2.12.0 或更高版本，或者 fluent bit 镜像版本应为 1.7.2 或更高版本。

```
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: amazon-cloudwatch
  labels:
    k8s-app: fluent-bit
    version: v1
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    matchLabels:
      k8s-app: fluent-bit
  template:
    metadata:
      labels:
        k8s-app: fluent-bit
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: fluent-bit
        image: amazon/aws-for-fluent-bit:2.19.0
        imagePullPolicy: Always
        env:
            - name: AWS_REGION
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: logs.region
            - name: CLUSTER_NAME
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: cluster.name
            - name: HTTP_SERVER
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: http.server
            - name: HTTP_PORT
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: http.port
            - name: READ_FROM_HEAD
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: read.head
            - name: READ_FROM_TAIL
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: read.tail
            - name: HOST_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: HOSTNAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name      
            - name: CI_VERSION
              value: "k8s/1.3.8"
        resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 500m
              memory: 100Mi
        volumeMounts:
        # Please don't change below read-only permissions
        - name: fluentbitstate
          mountPath: /var/fluent-bit/state
        - name: varlog
          mountPath: /var/log
          readOnly: true
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: fluent-bit-config
          mountPath: /fluent-bit/etc/
        - name: runlogjournal
          mountPath: /run/log/journal
          readOnly: true
        - name: dmesg
          mountPath: /var/log/dmesg
          readOnly: true
      terminationGracePeriodSeconds: 10
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: fluentbitstate
        hostPath:
          path: /var/fluent-bit/state
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: fluent-bit-config
        configMap:
          name: fluent-bit-config
      - name: runlogjournal
        hostPath:
          path: /run/log/journal
      - name: dmesg
        hostPath:
          path: /var/log/dmesg
      serviceAccountName: fluent-bit
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      - operator: "Exists"
        effect: "NoExecute"
      - operator: "Exists"
        effect: "NoSchedule"
```

Kubernetes 插件配置应该类似于以下内容：

```
[FILTER]
        Name                kubernetes
        Match               application.*
        Kube_URL            https://kubernetes.default.svc:443
        Kube_Tag_Prefix     application.var.log.containers.
        Merge_Log           On
        Merge_Log_Key       log_processed
        K8S-Logging.Parser  On
        K8S-Logging.Exclude Off
        Labels              Off
        Annotations         Off
        Use_Kubelet         On
        Kubelet_Port        10250 
        Buffer_Size         0
```