工程

用 Elastic 的方式使用 Filebeat 和 Metricbeat 监测 Kubernetes

上一篇博文 中,我演示了如何将 Prometheus 和 Fluentd 与 Elastic Stack 结合使用来监测 Kubernetes。如果您已经在组织中使用这些基于开源的监测工具,那么这是一个不错的选择。但是,如果您刚刚接触 Kubernetes 监测,或者想要充分利用 Elastic 可观测性 的功能,有一种更简单、更全面的方法。在这篇博文中,我们将探索如何用 Elastic 的方式监测 Kubernetes:使用 Filebeat 和 Metricbeat。

使用 Filebeat 和 Metricbeat

众所周知,Beats 是一个免费、开放的数据传输平台。使用 Beats,您可以将数据从数百台或数千台机器传输到 Logstash 或 Elasticsearch。

Filebeat 被称为轻量级日志采集器,它也支持容器化架构。Filebeat 可以部署在 Docker、Kubernetes 和云环境中,用于收集所有日志流,以及提取容器、Pod、节点、虚拟环境和主机等元数据,并自动将这些元数据与相应的日志事件关联起来。Metricbeat 是一个轻量级的指标采集器,和 Filebeat 一样,它也支持容器化环境。在 Kubernetes 环境中,容器作为 Pod,动态地部署在可用的工作节点上。这里的“动态”是关键,Filebeat 和 Metricbeat 有一个很方便的功能,叫做“自动发现”。当您在容器中运行应用程序时,它们就成为了用于监测系统的移动目标。Filebeat 和 Metricbeat 的 Kubernetes 自动发现提供程序会监测 Kubernetes 节点、Pod 和服务的启动、更新和停止。当 Filebeat 或 Metricbeat 检测到这些事件时,它们会为每个事件提供适当的元数据。此外,根据已启动的 Kubernetes Pod 的注释,它们会将适当的设置应用于目标日志和指标。我们先前关于 Beats 推出基于提示的 Docker 和 Kubernetes 自动发现 的博文中详细介绍了基于提示的自动发现。

监测架构

与上一篇博文中介绍的一样,我们将在 Kubernetes 集群上部署一个简单的多容器应用程序 Cloud-Voting-App,并监测包含该应用程序的 Kubernetes 环境。这一次,我将阐释以下过程:使用 Filebeat 收集日志,使用 Metricbeat 收集指标,将日志和指标直接采集到 Elasticsearch 中,并使用 Kibana 进行监测。我还将介绍如何使用 Elastic APM 获取 Prometheus 定制指标。总体架构如下图所示。此外,您可以在我的 GitHub 存储库 中获取本教程的代码,请参考该代码,了解完整的过程。

enter image description here

我们来分步查看详细的过程!

将 Filebeat 作为 DaemonSet 进行部署

每个 Kubernetes 节点只能部署一个 Filebeat 实例。DaemonSet 的清单已在 elastic/filebeat-kubernetes.yaml 文件中定义好,但我们可以看看相关的设置。

首先,使用 Kubernetes 自动发现提供程序配置应用程序 Pod 注释设置以处理日志。您可以看到,自动发现设置是在 filebeat.autodiscover 部分中定义的。我启用了提示,并为容器日志设置了默认路径。有关为 Filebeat 配置自动发现的更多信息,请参考 Filebeat 文档

...
    # 要启用基于提示的自动发现,请移除 `filebeat.inputs` 配置并取消注释:
    filebeat.autodiscover:
      providers:
        - type: kubernetes
          node: ${NODE_NAME}
          hints.enabled: true
          hints.default_config:
            type: container
            paths:
              - /cn/var/log/containers/*${data.kubernetes.container.id}.log
...

除此之外,您要做的基本上就是为 Elasticsearch 集群添加 URL 和凭据。

...
     containers:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.13.0
        args: [
          "-c", "/cn/etc/filebeat.yml",
          "-e",
        ]
        env:
        - name:ELASTICSEARCH_HOST
          value: elasticsearch
        - name:ELASTICSEARCH_PORT
          value:"9200"
        - name:ELASTICSEARCH_USERNAME
          value: elastic
        - name:ELASTICSEARCH_PASSWORD
          value: changeme
        - name:ELASTIC_CLOUD_ID
          value:
        - name:ELASTIC_CLOUD_AUTH
          value:
...

部署 kube-state-metrics

kube-state-metrics 是 Kubernetes 的一个附加组件,用于监测 Kubernetes 中存储的对象。kube-state-metrics 专注于识别部署到 Kubernetes 集群的 Kubernetes 对象的状态。例如,在给定的时间点,集群中部署了多少个 Pod,集群中可分配的 CPU 核心有哪些,失败的作业有多少,等等。默认情况下,kube-state-metrics 不会部署到 Kubernetes 集群,因此您需要自行部署。examples/standard 下有一个示例 kube-state-metrics 清单供您参考。有关 kube-state-metrics 的更多信息,请参考这个 GitHub 存储库

将 Metricbeat 作为 DaemonSet 进行部署

与 Filebeat 一样,每个 Kubernetes 节点只能部署一个 Metricbeat 实例。DaemonSet 的清单已在 elastic/metricbeat-kubernetes.yaml 文件中定义好,但它比 Filebeat 要复杂一些。我们看一下关键设置。

自动发现的设置是在 metricbeat.autodiscover 部分中定义的。第一个 - type: kubernetes 设置是针对整个 Kubernetes 集群的。这里,我们使用 Metricbeat 的 Kubernetes 模块为整个 Kubernetes 集群配置指标。第一个 - module: kubernetes 配置设置了我们从上面提到的 kube-state-metrics 中获得的指标。第二个 - module: kubernetes 配置用于监测 Kubernetes API 服务器 (kube-apiserver),该服务器是 Kubernetes 控制平面的核心,该控制平面公开了 Kubernetes API。有关 Metricbeat 的 Kubernetes 模块的更多信息,请参考 Metricbeat 文档

metricbeat.autodiscover:
  providers:
    - type: kubernetes
      scope: cluster
      node: ${NODE_NAME}
      unique: true
      templates:
        - config:
            - module: kubernetes
              hosts: ["kube-state-metrics:8080"]
              period:10s
              add_metadata: true
              metricsets:
                - state_node
                - state_deployment
                - state_daemonset
                - state_replicaset
                - state_pod
                - state_container
                - state_cronjob
                - state_resourcequota
                - state_statefulset
                - state_service
            - module: kubernetes
              metricsets:
                - apiserver
              hosts: ["https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}"]
              bearer_token_file: /cn/var/run/secrets/kubernetes.io/serviceaccount/token
              ssl.certificate_authorities:
                - /cn/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
              period:30s

此外,还定义了一些提示,以利用 Kubernetes 自动发现提供程序,使用应用程序 Pod 注释设置来启用指标的处理。有关为 Metricbeat 配置自动发现的更多信息,请参考 Metricbeat 文档

    # 要启用基于提示的自动发现,请取消注释:
    - type: kubernetes
      node: ${NODE_NAME}
      hints.enabled: true

下面的 ConfigMap 设置针对 node/system/pod/container/volume,它们是 Metricbeat 的 Kubernetes 模块的默认 Metricset。这些指标是从每个节点的 kubelet 终端拉取的。

kubernetes.yml: |-
  - module: kubernetes
    metricsets:
      - node
      - system
      - pod
      - container
      - volume
    period:10s
    host: ${NODE_NAME}
    hosts: ["https://${NODE_NAME}:10250"]
    bearer_token_file: /cn/var/run/secrets/kubernetes.io/serviceaccount/token
    ssl.verification_mode: "none"

最后,与 Filebeat 一样,您要做的就是为 Elasticsearch 集群添加 URL 和凭据。

部署应用程序

上一篇博文 所述,我们将部署 Cloud-Voting-App。应用程序接口已经使用 Python/Flask 构建完成。数据组件使用 Redis。请记住,应用程序已装载 Prometheus Python 客户端 测量工具,以公开 Prometheus 定制指标。尽管这次没有 Prometheus,我们如何收集 Prometheus 定制指标?从 7.12 版本开始,我们 可以使用 Elastic APM 代理获取定制 Prometheus 指标

首先,应用程序导入 ElasticAPM,并将环境变量用于 Elastic APM 代理设置。SERVICE_NAME 是用于识别应用程序的任意字符串,ENVIRONMENT 是用于识别应用程序环境的任意字符串,SECRET_TOKENSERVER_URL 是用于与 APM 服务器通信的字符串。最后的 PROMETHEUS_METRICS 是一个参数,用于指示是否从 prometheus_client 获取指标。

from elasticapm.contrib.flask import ElasticAPM
...
app = Flask(__name__)
...
# Elastic APM 配置
app.config['ELASTIC_APM'] = {
# 设置所需的服务名称。允许使用的字符:
# a-z、A-Z、0-9、-、_ 和空格
'SERVICE_NAME': os.environ['SERVICE_NAME'],
#
# APM 服务器需要令牌时使用
'SECRET_TOKEN': os.environ['SECRET_TOKEN'],
#
# 设置定制 APM 服务器 URL(默认:http://localhost:8200)
'SERVER_URL': os.environ['SERVER_URL'],
#
# 设置环境
'ENVIRONMENT': os.environ['ENVIRONMENT'],
#
# 设置 prometheus_metrics
'PROMETHEUS_METRICS': os.environ['PROMETHEUS_METRICS'],
}
apm = ElasticAPM(app)

下面是将 Cloud-Voting-App 部署到 Kubernetes 集群的清单。相应的文件位于 elastic/cloud-vote-all-in-one-redis-aks.yaml 中。首先,关于用户接口 cloud-vote-front,上述 APM 代理所需的变量被设置为容器规范中的环境变量。这里没有指定特定于 Pod 的注释,因此使用默认设置获取日志和指标。

apiVersion: apps/v1
kind:Deployment
metadata:
  name: cloud-vote-front
spec:
  replicas:1
  selector:
    matchLabels:
      app: cloud-vote-front
  strategy:
    rollingUpdate:
      maxSurge:1
      maxUnavailable:1
  minReadySeconds:5
  template:
    metadata:
      labels:
        app: cloud-vote-front
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: cloud-vote-front
        image: your image name
        ports:
        - containerPort:80
        resources:
          requests:
            cpu:250m
          limits:
            cpu:500m
        env:
        - name:REDIS
          value: "cloud-vote-back"
        - name:SERVICE_NAME
          value: "cloud-voting"
        - name:SECRET_TOKEN
          value:"APM Server secret token"
        - name:SERVER_URL
          value:"APM Server URL"
        - name:ENVIRONMENT
          value:"Production"
        - name:PROMETHEUS_METRICS
          value:"True"

另外,后端 cloud-vote-redis 使用 Pod annotations 来启用 Filebeat Redis 模块用于日志,启用 Metricbeat Redis 模块用于指标,同时应用任何必要的设置。而 cloute-vote-front 使用 Beats 的默认设置来收集日志和指标,cloud-vote-back 使用 Beats 的 Redis 模块来收集日志和指标。此外,通过配置如何在应用程序清单而不是 Beats 清单中收集日志和指标,您可以使开发团队和可观测性平台团队之间的责任分离开来。

apiVersion: apps/v1
kind:Deployment
metadata:
  name: cloud-vote-back
spec:
  replicas:1
  selector:
    matchLabels:
      app: cloud-vote-back
  template:
    metadata:
      labels:
        app: cloud-vote-back
      annotations:
        co.elastic.logs/enabled: "true"
        co.elastic.logs/module: redis
        co.elastic.logs/fileset.stdout: log
        co.elastic.metrics/enabled: "true"
        co.elastic.metrics/module: redis
        co.elastic.metrics/hosts: "${data.host}:6379"
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: cloud-vote-back
        image: redis
        ports:
        - containerPort:6379
          name: redis

访问 Kibana

现在我们已经部署了所有必需的组件。接下来,使用 Cloud-Voting-App 投几次票,然后访问 Kibana。

可观测性概述

首先,当您在 Kibana 中打开 Elastic 可观测性 时,无需执行任何操作,就可以看到来自 Filebeat 的日志输入的日志速率和来自 Metricbeat 的指标输入的摘要。之所以会有这一结果,是因为 Filebeat 和 Metricbeat 默认以 ECS 格式 采集数据。

enter image description here

日志

Filebeat 采集的日志存储在 filebeat-* 索引中。您可以使用 Kibana 上的 Logs 应用 对 Elasticsearch 中收集到的所有日志进行搜索、筛选和跟踪。您还可以突出显示特定的字符串;例如,我们在下面的示例中突出显示了 cloud-vote-front

enter image description here

指标

Metricbeat 采集的指标存储在 metricbeat-* 索引中。Kibana 中的 Metrics 应用 提供了一种简单易懂且直观的方式来查看 Elasticsearch 中收集的指标。使用如下所示的 Kubernetes Pods 视图映射 Kubernetes 节点和 Pod,并显示每个资源的使用情况。

enter image description here

您还可以单击特定的 Pod 以跳转到其他应用,例如 Pod 日志或 APM 跟踪,同时保留上下文。请注意,屏幕上显示 View details for kubernetes.pod.uid a47d81b1-02d7-481a-91d4-1db9fe82d7a7

enter image description here

然后,您可以通过单击 Kubernetes Pod logs 跳转到这个 Pod 的日志。您有没有注意到 Logs 应用中的搜索栏已经填充了 kubernetes.pod.uid: a47d81b1-02d7-481a-91d4-1db9fe82d7a7?通过以这种方式保留上下文,Kibana 可以在应用之间无缝切换,即时返回相关结果。

enter image description here

那么 Prometheus 定制指标发生了什么呢?Prometheus Python 客户端保留的定制指标通过 Elastic APM 代理写入名为 apm-* 的索引。如果您使用 Kibana Discover 查看的话,可以看到它是在 prometheus.metrics.cloud_votes 字段中收集的。POST 请求中的变量存储为 labels.vote。有关使用 Elastic APM Python 代理收集 Prometheus 定制指标的更多信息,请参考 APM 文档

enter image description here

如下所示,您可以使用 Kibana Lens 轻松地可视化 apm-* 索引。

enter image description here

预定义的仪表板

对于使用 Redis 的 cloud-vote-back Pod,我们已经为 Filebeat 和 Metricbeat 启用了 Redis 模块。这也会预先创建相关的开箱即用型仪表板。您可以立即可视化 Redis 日志和指标,无需进行额外的设置。

enter image description here enter image description here

此外,正是由于有 Metricbeat 的 Kubernetes 模块,Kubernetes 仪表板也可随时使用。

enter image description here

总结

在这篇博文中,我们介绍了一种更具 Elastic 风格的方法:使用 Filebeat 和 Metricbeat 来填充 Elastic Stack,并使用日志和指标来监测 Kubernetes。我们还了解了如何使用 Elastic APM 代理获得 Prometheus 定制指标。通过注册 Elastic Cloud 的免费试用版,或者 下载 Elastic Stack 并自行托管,您可以立即开始监测您的 Kubernetes 环境。Elastic 可观测性让监测更有效果且有效率。它还可以与 Elastic Machine Learning 和 Kibana 告警集成,实现高度自动化、可操作、全面的可观测性。如果您遇到任何困难或问题,请跳转至我们的论坛,我们随时为您提供真诚帮助。

在后续博文中,我们会推出更多使用 Elastic 监测 Kubernetes 的方法,敬请期待。