如何将Kubernetes日志发送到AWS CloudWatch?

21

AWS CloudWatch日志在Docker中

docker中设置AWS CloudWatch日志驱动程序需要使用log-driver=awslogslog-opt参数,例如 -

#!/bin/bash

docker run \
    --log-driver=awslogs \
    --log-opt awslogs-region=eu-central-1 \
    --log-opt awslogs-group=whatever-group \
    --log-opt awslogs-stream=whatever-stream \
    --log-opt awslogs-create-group=true \
    wernight/funbox \
        fortune

我的问题

如何将log-driverlog-opt参数发送到Pod/Deployment中的Docker容器?

我的问题背景

我想在Kubernetes集群中使用AWS CloudWatch日志,其中每个Pod包含几个Docker容器。每个部署将有一个单独的Log Group,每个容器将有一个单独的stream。我找不到通过Kubernetes create/apply向Docker容器发送日志参数的方法。

我尝试过什么


尝试使用CloudWatch容器洞察力(https://aws.amazon.com/about-aws/whats-new/2019/05/cloudwatch-container-insights-for-eks-and-kubernetes-preview/)。它具有用于应用程序日志、数据平面日志(kubelet和容器运行时)以及主机日志的fluentd yaml。 - Marco
4个回答

18

据我了解,Kubernetes 更偏向于使用集群级别的日志记录而非 Docker 日志驱动程序。

我们可以使用 fluentd 来收集、转换并推送容器日志到 CloudWatch Logs。

您只需要创建一个带有 ConfigMap 和 Secret 的 fluentd DaemonSet。文件可以在 Github 上找到。它已经在 Kubernetes v1.7.5 上进行了测试。

以下是一些说明。

输入

通过 DaemonSet,fluentd 从主机文件夹 /var/lib/docker/containers 中收集每个容器的日志。

过滤

fluent-plugin-kubernetes_metadata_filter 插件从 Kubernetes API 服务器加载 Pod 的元数据。

日志记录将会像这样。

{
    "log": "INFO: 2017/10/02 06:44:13.214543 Discovered remote MAC 62:a1:3d:f6:eb:65 at 62:a1:3d:f6:eb:65(kube-235)\n",
    "stream": "stderr",
    "docker": {
        "container_id": "5b15e87886a7ca5f7ebc73a15aa9091c9c0f880ee2974515749e16710367462c"
    },
    "kubernetes": {
        "container_name": "weave",
        "namespace_name": "kube-system",
        "pod_name": "weave-net-4n4kc",
        "pod_id": "ac4bdfc1-9dc0-11e7-8b62-005056b549b6",
        "labels": {
            "controller-revision-hash": "2720543195",
            "name": "weave-net",
            "pod-template-generation": "1"
        },
        "host": "kube-234",
        "master_url": "https://10.96.0.1:443/api"
    }
}

使用Fluentd的record_transformer过滤插件创建一些标记。

{
    "log": "...",
    "stream": "stderr",
    "docker": {
        ...
    },
    "kubernetes": {
        ...
    },
    "pod_name": "weave-net-4n4kc",
    "container_name": "weave"
}

输出

fluent-plugin-cloudwatch-logs插件将信息发送到AWS CloudWatch日志服务。

通过log_group_name_keylog_stream_name_key配置,可将日志分组和流名称设置为记录中的任意字段。

<match kubernetes.**>
  @type cloudwatch_logs
  log_group_name_key pod_name
  log_stream_name_key container_name
  auto_create_stream true
  put_log_events_retry_limit 20
</match>

1
这个解决方案会保持容器隔离吗?它们能够读取彼此的日志吗? - Adam Matan
1
是的,它们彼此是隔离的。由于卷映射的原因,只有 fluentd 容器可以读取所有容器的日志(在其主机上)。 - silverfox
2
目前我正在努力理解这个问题。目前使用kops,将docker logDriver设置为awslogs,并且所有日志都正确地发送到CloudWatch,但是在一个日志组中。我正在尝试找到一种方法,将它们分成每个应用程序的单独日志组。我应该关闭docker级别的日志记录,改为按照您上面描述的使用fluentd进行分类吗? - Olly W
@olly-w,你能分享一下如何将Docker logDriver设置为记录到CloudWatch吗?我试图找出如何做,但我读到docker run用于日志后端的标志不受k8s和kops支持。 - cryanbhu
3
您需要编辑 kops 集群,例如 kops edit cluster,然后设置如下内容:docker: logDriver: awslogs logOpt:
  • awslogs-region=eu-west-1
  • awslogs-group=integration
  • tag={{.Name}}
- Olly W

4

4
根据Kubernetes,Kubernetes没有原生的日志存储解决方案,但您可以将许多现有的日志记录解决方案集成到您的Kubernetes集群和kubernate 集群级日志架构中。Kubernetes不指定日志记录代理,但是Kubernetes发布包内包含两个可选的日志记录代理:适用于Google Cloud Platform的Stackdriver Logging和Elasticsearch。您可以在专门的文档中找到更多信息和说明。这两者都使用在节点上作为代理的自定义配置的fluentd。Fluentd映像还可将Kubernetes日志发送到CloudWatch,因此您可以使用它来部署

3
Sliverfox有一个很好的答案。您不必构建自己的镜像。也可以直接使用fluentd官方的docker镜像,fluent/fluentd-kubernetes-daemonset:cloudwatch。 代码位于 fluentd-kubernetes-daemonset github
您可以使用configmap替换默认的fluent.conf。就像在ds.yaml中所示,并在configmap.yaml中编写自己的fluent.conf。有关完整的yaml文件,请参见我们编写的示例 ds.yaml configmap.yaml
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: varlibdockercontainers
      mountPath: /var/lib/docker/containers
      readOnly: true
    - name: config-volume
      mountPath: /fluentd/etc/
  volumes:
  - name: varlog
    hostPath:
      path: /var/log
  - name: varlibdockercontainers
    hostPath:
      path: /var/lib/docker/containers
  - name: config-volume
    configMap:
      name: fluentd-cw-config

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接