如何在 Amazon EKS 中将容器日志流式传输到 CloudWatch?

上次更新日期:2022 年 5 月 13 日

我想将 Amazon Elastic Kubernetes Service(Amazon EKS)中运行的容器日志流式传输到像 CloudWatch Logs 这样的日志记录系统。我该如何操作?

简短描述

您可以使用 Fluent BitFluentd 将容器中的日志发送到您的 CloudWatch 日志。Fluent Bit 是 Container Insights 的默认日志解决方案,因此最佳实践是使用 Fluent Bit 而非 Fluentd。Amazon 在 Amazon Elastic Container Registry(Amazon ECR)上提供了 Fluent Bit 容器映像。有关更多信息,请参阅 Amazon ECR 上的 cloudwatch-agent

当您将 Fluent Bit 设置为 DaemonSet 以向 CloudWatch 发送日志时,则 FluentBit 会创建以下日志组(如尚不存在):

日志组名称 日志来源
/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 中的日志

解决方法

先决条件

在执行这些步骤之前,请查看先决条件:

  • 您的 EKS 集群正在运行,节点处于“就绪”状态,kubectl 命令已安装且正在运行。
  • AWS Identity and Access Management(IAM)的 CloudWatchAgentServerPolicy 已经到位,允许您的 Amazon EKS Worker 节点将指标和日志发送到 CloudWatch。您可以通过将策略附加到 Worker 节点的 IAM 角色来实现此目的。或者,为集群的服务账户使用 IAM 角色,并将策略附加到此角色。有关更多信息,请参阅服务账户的 IAM 角色
  • 您正在运行支持 Kubernetes 1.18 或更高版本的集群。这是 Container Insights for EKS Fargate 的要求。您还定义了一个 Fargate 配置文件以在 Fargate 上调度 pod。
  • EKS pod 执行角色已经到位,允许在 Fargate 基础设施上运行的组件代表您调用 AWS API。例如,从 Amazon ECR 中提取容器映像。

流式传输在 EKS EC2 集群中运行的容器日志

要将容器日志流式传输到 CloudWatch Logs,请按照以下步骤安装 AWS for Fluent Bit:

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

2.    运行此命令可创建名为 fluent-bit-cluster-info 的ConfigMap,包括集群名称和要向其发送日志的区域。将 my-cluster-name 和 my-cluster-region 替换为您的集群名称和区域。

ClusterName=<my-cluster-name>
RegionName=<my-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

3.    将 Fluent Bit 优化配置 DaemonSet 部署到该集群:

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

4.    可选:修补 aws-for-fluent-bit DaemonSet 以使用 Amazon Elastic Container Registry 上的 AWS for Fluent Bit 映像:

kubectl patch ds fluent-bit -n amazon-cloudwatch -p \
'{"spec":{"template":{"spec":{"containers":[{"name":"fluent-bit","image":"public.ecr.aws/aws-observability/aws-for-fluent-bit:latest"}]}}}}'

5.    对于服务账户的 IAM 角色,请创建 OIDC 提供商以及一个 IAM 角色和策略。然后,将 IAM 角色关联到 cloudwatch-agent 和 fluent-bit 服务账户。将 ACCOUNT_IDIAM_ROLE_NAME 替换为 AWS 账户 ID 和用于服务账户的 IAM 角色。

kubectl annotate serviceaccounts fluent-bit -n cloudwatch-agent "eks.amazonaws.com/role-arn=arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME"

有关更多自定义设置,请参阅将 Fluent Bit 设置为DaemonSet 以将日志发送到 CloudWatch Logs

排查 Fluent Bit 部署的问题

1.    运行此命令,然后检查输出底部的事件:

kubectl describe pod pod-name -n amazon-cloudwatch

2.    运行此命令以检查日志:

kubectl logs pod-name -n amazon-cloudwatch

删除 Fluent Bit 部署

要删除 Fluent Bit 部署,请运行以下命令:

kubectl delete configmap fluent-bit-cluster-info -n amazon-cloudwatch 

kubectl delete -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

流式传输在 EKS Fargate 集群中运行的容器日志

Fargate 上的 Amazon EKS 有一个基于 Fluent Bit 的内置日志路由器。这意味着您没有明确地将 Fluent Bit 容器作为 Sidecar 运行。Amazon 则会为您运行。有关更多详细信息,请参阅 Fargate 日志记录

按照以下步骤将容器日志流式传输到 CloudWatch 日志:

1.    创建一个名为 aws-observability 的专用 Kubernetes 命名空间:

cat <<EOF > aws-observability-namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
  name: aws-observability
  labels:
    aws-observability: enabled
EOF

kubectl apply -f aws-observability-namespace.yaml

2.    使用 Fluent Conf 数据值创建一个 ConfigMap,以便将容器日志发送到 CloudWatch 日志:

cat <<EOF > aws-logging-cloudwatch-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: aws-logging
  namespace: aws-observability
data:
  output.conf: |
    [OUTPUT]
        Name cloudwatch_logs
        Match   *
        region region-code
        log_group_name fluent-bit-cloudwatch
        log_stream_prefix from-fluent-bit-
        auto_create_group true
        log_key log

  parsers.conf: |
    [PARSER]
        Name crio
        Format Regex
        Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L%z
  
  filters.conf: |
     [FILTER]
        Name parser
        Match *
        Key_name log
        Parser crio
EOF

kubectl apply -f aws-logging-cloudwatch-configmap.yaml

3.    使用 CloudWatch IAM 策略创建 IAM 策略,然后将其附加到为您的 Fargate 配置文件指定的 pod 执行角色。

  • 将 CloudWatch IAM 策略下载到您的电脑。您也可以在 GitHub 上查看该策略
curl -o permissions.json https://raw.githubusercontent.com/aws-samples/amazon-eks-fluent-logging-examples/mainline/examples/fargate/cloudwatchlogs/permissions.json
  • 从您下载的策略文件创建 IAM 策略。
aws iam create-policy —policy-name eks-fargate-logging-policy —policy-document file://permissions.json
  • 将 IAM 策略附加到为您的 Fargate 配置文件指定的 pod 执行角色。然后,将“111122223333”替换为您的 账户 ID。
aws iam attach-role-policy \
--policy-arn arn:aws:iam::111122223333:policy/eks-fargate-logging-policy \
--role-name your-pod-execution-role

有关对在 EKS Fargate 上运行的 AWS Fluent Bit 进行故障排除的更多信息,请参阅故障排除页面。

为 EKS Fargate pod 禁用流式传输日志功能

要为您的 EKS Fargate pod 禁用流式传输日志,请运行以下命令:

kubectl delete namespace aws-observability

删除 aws-observability 命名空间后,请删除 pod 并进行重新部署。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?