自动发现

编辑

当您在容器上运行应用程序时,它们会成为监控系统的动态目标。自动发现允许您跟踪它们并随着更改的发生而调整设置。通过定义配置模板,自动发现子系统可以在服务开始运行时对其进行监控。

您可以在 heartbeat.yml 配置文件的 heartbeat.autodiscover 部分中定义自动发现设置。要启用自动发现,请指定提供程序列表。

提供程序

编辑

自动发现提供程序通过监视系统上的事件并将这些事件转换为具有通用格式的内部自动发现事件来工作。配置提供程序时,您可以选择使用自动发现事件中的字段来设置条件,满足这些条件时,将启动特定配置。

启动时,Heartbeat 将扫描现有容器并为其启动正确的配置。然后,它将监视新的启动/停止事件。这确保您无需担心状态,而只需定义所需的配置。

Docker
编辑

Docker 自动发现提供程序监视 Docker 容器的启动和停止。

它具有以下设置:

host
(可选) Docker 套接字(UNIX 或 TCP 套接字)。默认情况下,它使用 unix:///var/run/docker.sock
ssl
(可选) 连接到 Docker 套接字时使用的 SSL 配置。
cleanup_timeout
(可选) 指定在停止容器的运行配置之前的非活动时间,默认为禁用。
labels.dedot
(可选) 默认值为 false。如果设置为 true,则将标签中的点替换为 _

这些是在配置模板中可用的字段。docker.* 字段将在每个发出的事件中可用。event

  • host
  • port
  • docker.container.id
  • docker.container.image
  • docker.container.name
  • docker.container.labels

例如

{
  "host": "10.4.15.9",
  "port": 6379,
  "docker": {
    "container": {
      "id": "382184ecdb385cfd5d1f1a65f78911054c8511ae009635300ac28b4fc357ce51"
      "name": "redis",
      "image": "redis:3.2.11",
      "labels": {
        "io.kubernetes.pod.namespace": "default"
        ...
      }
    }
  }
}

您可以定义一组配置模板,当条件与事件匹配时应用这些模板。模板定义要匹配自动发现事件的条件,以及发生此条件时要启动的配置列表。

条件匹配来自提供程序的事件。提供程序对条件使用与处理器相同的格式。

配置模板可以包含来自自动发现事件的变量。它们可以在 data 命名空间下访问。例如,使用示例事件,“${data.port}” 解析为 6379

Heartbeat 支持模块模板

heartbeat.autodiscover:
  providers:
    - type: docker
      templates:
        - condition:
            contains:
              docker.container.image: redis
          config:
            - type: tcp
              hosts: ["${data.host}:${data.port}"]
              schedule: "@every 1s"
              timeout: 1s

此配置为所有名称中包含 redis 的镜像运行的容器启动 redis 监控器。

Kubernetes
编辑

Kubernetes 自动发现提供程序监视 Kubernetes 节点、Pod 和服务的启动、更新和停止。

kubernetes 自动发现提供程序具有以下配置设置:

node
(可选) 指定要将 heartbeat 范围限定到的节点,在主机网络模式下运行 heartbeat 时,如果无法准确检测到节点,则需要指定此节点。
namespace
(可选) 选择要从中收集资源事件的命名空间。如果未设置,则提供程序将从所有命名空间中收集它们。默认为未设置。命名空间配置仅适用于具有命名空间范围的 Kubernetes 资源,并且如果 unique 字段设置为 false
cleanup_timeout
(可选) 指定在停止容器的运行配置之前的非活动时间,默认为禁用。
kube_config
(可选) 使用给定的配置文件作为 Kubernetes 客户端的配置。如果未设置 kube_config,则将检查 KUBECONFIG 环境变量,如果不存在,则将回退到 InCluster。
kube_client_options
(可选) 可以为 Kubernetes 客户端配置其他选项。目前支持客户端 QPS 和突发,如果未设置,将使用 Kubernetes 客户端的默认 QPS 和突发。示例
      kube_client_options:
        qps: 5
        burst: 10
resource
(可选) 选择要对其进行发现的资源。目前支持的 Kubernetes 资源包括 podservicenode。如果未配置,resource 默认为 pod
scope
(可选) 指定需要在哪个级别进行自动发现。scope 可以取 nodecluster 作为值。node 范围允许发现指定节点中的资源。cluster 范围允许集群范围的发现。只有 podnode 资源可以在节点范围内发现。
add_resource_metadata

(可选) 指定将添加到事件的额外元数据的过滤器和配置。配置参数

  • nodenamespace:指定来自节点和命名空间的额外元数据的标签和注释过滤器。默认情况下,所有标签都包含在内,而注释则不包含。要更改默认行为,可以定义 include_labelsexclude_labelsinclude_annotations。这些设置在存储需要特殊处理以避免过载存储输出的标签和注释时很有用。注意:这些设置不支持通配符。nodenamespace 元数据的丰富可以单独通过设置 enabled: false 来禁用。
  • deployment:如果资源是 pod 并且它是从 deployment 创建的,则默认情况下不会添加部署名称,可以通过设置 deployment: true 来启用。
  • cronjob:如果资源是 pod 并且它是从 cronjob 创建的,则默认情况下不会添加 cronjob 名称,可以通过设置 cronjob: true 来启用。

    示例

      add_resource_metadata:
        namespace:
          include_labels: ["namespacelabel1"]
        node:
          include_labels: ["nodelabel2"]
          include_annotations: ["nodeannotation1"]
        # deployment: false
        # cronjob: false
unique
(可选) 默认为 false。将自动发现提供程序标记为唯一会导致提供程序仅在获得领导者租约时启用提供的模板。此设置只能与 cluster 范围组合使用。启用 unique 时,将不考虑 resourceadd_resource_metadata 设置。
leader_lease
(可选) 默认为 heartbeat-cluster-leader。这将是锁租约的名称。可以使用 kubectl describe lease beats-cluster-leader 监控租约的状态。引用相同领导者租约的不同 Beats 将成为持有租约的竞争者,每次只有一个将被选为领导者。
leader_leaseduration
(可选) 非领导者候选者强制获取租约领导权之前的等待时间。默认为 15s
leader_renewdeadline
(可选) 领导者在放弃之前重试刷新其领导地位的持续时间。默认为 10s
leader_retryperiod
(可选) 运行以获取租约的 metricbeat 实例应在操作尝试之间等待的持续时间。默认为 2s

配置模板可以包含来自自动发现事件的变量。这些变量可以在 data 命名空间下访问,例如,要访问 Pod IP:${data.kubernetes.pod.ip}

这些是在配置模板中可用的字段。kubernetes.* 字段将在每个发出的事件中可用

通用字段
编辑
  • host
Pod 特定字段
编辑
类型 描述

port

string

Pod 端口。如果 Pod 公开了多个端口,则应使用 ports.<port-name> 代替

kubernetes.namespace

string

Pod 运行的命名空间

kubernetes.namespace_uuid

string

Pod 运行的命名空间的 UUID

kubernetes.namespace_annotations.*

object

Pod 运行的命名空间的注释。注释应使用非点分隔格式,例如 kubernetes.namespace_annotations.app.kubernetes.io/name

kubernetes.pod.name

string

Pod 的名称

kubernetes.pod.uid

string

Pod 的 UID

kubernetes.pod.ip

string

Pod 的 IP

kubernetes.labels.*

object

Pod 标签的对象。标签应使用非点分隔格式,例如 kubernetes.labels.app.kubernetes.io/name

kubernetes.annotations.*

object

Pod 注释的对象。注释应使用非点分隔格式,例如 kubernetes.annotations.test.io/test

kubernetes.container.name

string

容器的名称

kubernetes.container.runtime

string

容器的运行时

kubernetes.container.id

string

容器的 ID

kubernetes.container.image

string

容器的镜像

kubernetes.node.name

string

节点的名称

kubernetes.node.uid

string

节点的 UID

kubernetes.node.hostname

string

节点的主机名

节点特定字段
编辑
类型 描述

kubernetes.labels.*

object

节点标签的对象

kubernetes.annotations.*

object

节点注释的对象

kubernetes.node.name

string

节点的名称

kubernetes.node.uid

string

节点的 UID

kubernetes.node.hostname

string

节点的主机名

服务特定字段
编辑
类型 描述

port

string

服务端口

kubernetes.namespace

string

服务的命名空间

kubernetes.namespace_uuid

string

服务的命名空间的 UUID

kubernetes.namespace_annotations.*

object

服务的命名空间的注释。注释应使用非点分隔格式,例如 kubernetes.namespace_annotations.app.kubernetes.io/name

kubernetes.labels.*

object

服务标签的对象

kubernetes.annotations.*

object

服务注释的对象

kubernetes.service.name

string

服务的名称

kubernetes.service.uid

string

服务的 UID

如果 include_annotations 配置添加到提供程序配置中,则配置中存在的注释列表将添加到事件中。

如果 include_labels 配置添加到提供程序配置中,则配置中存在的标签列表将添加到事件中。

如果 exclude_labels 配置添加到提供程序配置中,则配置中存在的标签列表将从事件中排除。

如果在提供程序配置中将 labels.dedot 配置设置为 true,则标签中的 . 将替换为 _。默认值为 true

如果在提供程序配置中将 annotations.dedot 配置设置为 true,则注释中的 . 将替换为 _。默认值为 true

从 8.6 版本开始,在配置模板中使用的 kubernetes.labels.* 将不再进行点分隔符去除,无论 labels.dedot 的值如何。此配置参数仅影响添加到最终 Elasticsearch 文档中的字段。例如,对于标签为 app.kubernetes.io/name=ingress-nginx 的 Pod,匹配条件应为 condition.equals: kubernetes.labels.app.kubernetes.io/name: "ingress-nginx"。如果 labels.dedot 设置为 true(默认值),则标签将以 kubernetes.labels.app_kubernetes_io/name 的形式存储在 Elasticsearch 中。Kubernetes 注解也适用相同的规则。

例如

{
  "host": "172.17.0.21",
  "port": 9090,
  "kubernetes": {
    "container": {
      "id": "bb3a50625c01b16a88aa224779c39262a9ad14264c3034669a50cd9a90af1527",
      "image": "prom/prometheus",
      "name": "prometheus"
    },
    "labels": {
      "project": "prometheus",
      ...
    },
    "namespace": "default",
    "node": {
      "name": "minikube"
    },
    "pod": {
      "name": "prometheus-2657348378-k1pnh"
    }
  },
}

Heartbeat 支持模块模板

heartbeat.autodiscover:
  providers:
    - type: kubernetes
      include_annotations: ["prometheus.io.scrape"]
      templates:
        - condition:
            contains:
              kubernetes.annotations.prometheus.io/scrape: "true"
          config:
            - type: http
              hosts: ["${data.host}:${data.port}"]
              schedule: "@every 1s"
              timeout: 1s

此配置为所有使用 prometheus.io/scrape=true 注解的 Pod 的容器启动一个 http 模块。

Amazon ELB(已弃用)
编辑

注意:此提供程序现已弃用,将在未来的版本中移除。

Amazon ELB 自动发现提供程序会发现 ELB 及其监听器。当您不想直接连接到服务,而是连接到位于服务池前面的 ELB 时,这非常有用。

此提供程序将为每个 ELB 监听器生成一个配置块。因此,如果您有一个 ELB 同时公开 80 和 443 端口,它将生成两个配置,每个端口一个。请记住,Beat 将对配置进行去重。因此,如果生成的配置相同,则实际上只有一个会运行。

此提供程序将使用标准的 AWS 环境变量和共享凭证文件加载 AWS 凭证,更多信息请参见 AWS 访问密钥管理最佳实践。如果您不想使用这些凭证,可以显式设置 access_key_idsecret_access_key 变量。

这些是在配置模板中可用的字段。aws.elb.* 字段将在每个发出的事件中可用。

  • host
  • port
  • cloud.availability_zone
  • cloud.provider
  • cloud.region
  • aws.elb.listener_arn
  • aws.elb.load_balancer_arn
  • aws.elb.protocol
  • aws.elb.type
  • aws.elb.scheme
  • aws.elb.availability_zones
  • aws.elb.created
  • aws.elb.state.code
  • aws.elb.state.reason
  • aws.elb.ip_address_type
  • aws.elb.security_groups
  • aws.elb.vpc_id
  • aws.elb.ssl_policy

Heartbeat 支持模块模板

heartbeat.autodiscover:
  providers:
  - type: aws_elb
    period: 1m
    regions: ["us-east-1", "us-east-2"]
    access_key_id: my-access-key
    secret_access_key: my-secret-access-key
    templates:
    - condition:
        equals.port: 8080
      config:
      - type: tcp
        hosts: ["${data.host}:${data.port}"]
        schedule: "@every 5s"
        timeout: 1s

此配置为所有声明了端口的 ELB 启动一个 tcp 监控器。

此自动发现提供程序采用我们的标准 AWS 凭证选项

AWS 凭证配置

编辑

要配置 AWS 凭证,可以将凭证放入 Heartbeat 配置中,或使用共享凭证文件,如下例所示。

配置参数

编辑
  • access_key_id:访问密钥的第一部分。
  • secret_access_key:访问密钥的第二部分。
  • session_token:使用临时安全凭证时需要。
  • credential_profile_name:共享凭证文件中的配置文件名。
  • shared_credential_file:共享凭证文件的目录。
  • role_arn:要承担的 AWS IAM 角色。
  • external_id:在承担另一个帐户中的角色时使用的外部 ID,请参阅 AWS 文档中关于外部 ID 用法的说明
  • proxy_url:用于连接到 AWS Web 服务的代理的 URL。语法为 http(s)://<IP/Hostname>:<port>
  • fips_enabled:启用此选项指示 Heartbeat 使用服务的 FIPS 端点。Heartbeat 使用的所有服务都与 FIPS 兼容,除了 tagging,但只有某些区域与 FIPS 兼容。请参阅 https://aws.amazon.com/compliance/fips/ 或相应的服务页面 https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html,了解 FIPS 端点和区域的完整列表。
  • ssl:这指定了 SSL/TLS 配置。如果缺少 ssl 部分,则 HTTPS 连接将使用主机的 CA。更多信息请参阅 SSL
  • default_region:如果没有设置其他区域,则查询的默认区域。大多数 AWS 服务提供可用于发出请求的区域端点。某些服务(例如 IAM)不支持区域。如果未通过任何其他方式(环境变量、凭证或实例配置文件)提供区域,则将使用此处设置的值。
  • assume_role.duration:请求的承担角色会话的持续时间。未设置时默认为 15 分钟。AWS 允许的最大会话持续时间为 1 小时到 12 小时,具体取决于您的最大会话持续时间策略。
  • assume_role.expiry_window:expiry_window 允许在会话过期之前刷新会话。这有助于防止过期的令牌导致请求因 ExpiredTokenException 而失败。

支持的格式

编辑

本节中的示例指的是 Metricbeat,但无论使用哪个 Beat,用于通过 AWS 进行身份验证的凭证选项都是相同的。

  • 使用 access_key_idsecret_access_key 和/或 session_token

用户可以将凭证放入 Metricbeat 模块配置中,也可以使用环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 和/或 AWS_SESSION_TOKEN

如果在 Docker 上运行,则应将这些环境变量作为 Docker 命令的一部分添加。例如,使用 Metricbeat

$ docker run -e AWS_ACCESS_KEY_ID=abcd -e AWS_SECRET_ACCESS_KEY=abcd -d --name=metricbeat --user=root --volume="$(pwd)/metricbeat.aws.yml:/usr/share/metricbeat/metricbeat.yml:ro" docker.elastic.co/beats/metricbeat:7.11.1 metricbeat -e -E cloud.auth=elastic:1234 -E cloud.id=test-aws:1234

示例 metricbeat.aws.yml 如下所示

metricbeat.modules:
- module: aws
  period: 5m
  access_key_id: ${AWS_ACCESS_KEY_ID}
  secret_access_key: ${AWS_SECRET_ACCESS_KEY}
  session_token: ${AWS_SESSION_TOKEN}
  metricsets:
    - ec2

也可以通过文件添加环境变量。例如

$ cat env.list
AWS_ACCESS_KEY_ID=abcd
AWS_SECRET_ACCESS_KEY=abcd

$ docker run --env-file env.list -d --name=metricbeat --user=root --volume="$(pwd)/metricbeat.aws.yml:/usr/share/metricbeat/metricbeat.yml:ro" docker.elastic.co/beats/metricbeat:7.11.1 metricbeat -e -E cloud.auth=elastic:1234 -E cloud.id=test-aws:1234
  • 使用 credential_profile_name 和/或 shared_credential_file

如果没有给出 access_key_idsecret_access_keyrole_arn,则 Heartbeat 将检查 credential_profile_name。如果您为不同的工具或应用程序使用不同的凭证,则可以使用配置文件在同一个配置文件中配置多个访问密钥。如果没有给出 credential_profile_name,则将使用默认配置文件。

shared_credential_file 可选,用于指定共享凭证文件的目录。如果为空,则将使用默认目录。在 Windows 中,共享凭证文件位于 C:\Users\<yourUserName>\.aws\credentials。对于 Linux、macOS 或 Unix,该文件位于 ~/.aws/credentials。以服务身份运行时,主目录取决于管理服务的用户,因此可以使用 shared_credential_file 参数来避免歧义。更多详细信息,请参见 创建共享凭证文件

  • 使用 role_arn

role_arn 用于指定要承担哪个 AWS IAM 角色以生成临时凭证。如果给出了 role_arn,Heartbeat 将检查是否给出了访问密钥。如果没有,Heartbeat 将检查凭证配置文件名。如果两者都没有给出,则将使用默认凭证配置文件。请确保在凭证配置文件或访问密钥下都给出了凭证。

如果在 Docker 上运行,则需要通过卷挂载提供凭证文件。例如,使用 Metricbeat

docker run -d --name=metricbeat --user=root --volume="$(pwd)/metricbeat.aws.yml:/usr/share/metricbeat/metricbeat.yml:ro" --volume="/Users/foo/.aws/credentials:/usr/share/metricbeat/credentials:ro" docker.elastic.co/beats/metricbeat:7.11.1 metricbeat -e -E cloud.auth=elastic:1234 -E cloud.id=test-aws:1234

示例 metricbeat.aws.yml 如下所示

metricbeat.modules:
- module: aws
  period: 5m
  credential_profile_name: elastic-beats
  shared_credential_file: /usr/share/metricbeat/credentials
  metricsets:
    - ec2
heartbeat.autodiscover:
  providers:
  - type: aws_elb
    period: 1m
    regions: ["us-east-1", "us-east-2"]
    access_key_id: '<access_key_id>'
    secret_access_key: '<secret_access_key>'
    session_token: '<session_token>'
    templates:
    - type: tcp
      hosts: ["${data.host}:${data.port}"]
      schedule: "@every 5s"
      timeout: 1s

heartbeat.autodiscover:
  providers:
  - type: aws_elb
    period: 1m
    regions: ["us-east-1", "us-east-2"]
    access_key_id: '${AWS_ACCESS_KEY_ID:""}'
    secret_access_key: '${AWS_SECRET_ACCESS_KEY:""}'
    session_token: '${AWS_SESSION_TOKEN:""}'
    templates:
    - type: tcp
      hosts: ["${data.host}:${data.port}"]
      schedule: "@every 5s"
      timeout: 1s
  • 使用共享 AWS 凭证文件
heartbeat.autodiscover:
  providers:
  - type: aws_elb
    period: 1m
    regions: ["us-east-1", "us-east-2"]
    credential_profile_name: test-hb
    templates:
    - type: tcp
      hosts: ["${data.host}:${data.port}"]
      schedule: "@every 5s"
      timeout: 1s

AWS 凭证类型

编辑

可以使用两种不同类型的 AWS 凭证:访问密钥和临时安全凭证。

  • 访问密钥

AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 是访问密钥的两个部分。它们是 IAM 用户或 AWS 帐户根用户的长期凭证。更多详细信息,请参见 AWS 访问密钥和秘密访问密钥

  • IAM 角色 ARN

IAM 角色是在您的帐户中可以创建的 IAM 身份,它具有特定权限,这些权限决定了该身份在 AWS 中可以做什么和不能做什么。角色没有与之关联的标准长期凭证,例如密码或访问密钥。相反,当您承担角色时,它会为您提供的角色会话提供临时安全凭证。可以使用 IAM 角色 Amazon 资源名称 (ARN) 指定要承担哪个 AWS IAM 角色以生成临时凭证。更多详细信息,请参见 AssumeRole API 文档

以下是使用 AWS CLI 为 Metricbeat 设置 IAM 角色的步骤。请将 123456789012 替换为您自己的帐户 ID。

步骤 1. 创建 example-policy.json 文件以包含所有权限

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "sqs:ReceiveMessage"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "sqs:ChangeMessageVisibility",
            "Resource": "arn:aws:sqs:us-east-1:123456789012:test-fb-ks"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "sqs:DeleteMessage",
            "Resource": "arn:aws:sqs:us-east-1:123456789012:test-fb-ks"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole",
                "sqs:ListQueues",
                "tag:GetResources",
                "ec2:DescribeInstances",
                "cloudwatch:GetMetricData",
                "ec2:DescribeRegions",
                "iam:ListAccountAliases",
                "sts:GetCallerIdentity",
                "cloudwatch:ListMetrics"
            ],
            "Resource": "*"
        }
    ]
}

步骤 2. 使用 aws iam create-policy 命令创建 IAM 策略

$ aws iam create-policy --policy-name example-policy --policy-document file://example-policy.json

步骤 3. 创建 JSON 文件 example-role-trust-policy.json,该文件定义 IAM 角色的信任关系

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Principal": { "AWS": "arn:aws:iam::123456789012:root" },
        "Action": "sts:AssumeRole"
    }
}

步骤 4. 创建 IAM 角色并附加策略

$ aws iam create-role --role-name example-role --assume-role-policy-document file://example-role-trust-policy.json
$ aws iam attach-role-policy --role-name example-role --policy-arn "arn:aws:iam::123456789012:policy/example-policy"

完成这些步骤后,可以在 Metricbeat aws 模块中使用 IAM 角色 ARN 进行身份验证。

  • 临时安全凭证

临时安全凭证的有效期有限,由访问密钥 ID、秘密访问密钥和安全令牌组成,这些令牌通常由 GetSessionToken 返回。启用 MFA 的 IAM 用户需要在调用 GetSessionToken 时提交 MFA 代码。更多详细信息,请参见 临时安全凭证sts get-session-token AWS CLI 可用于生成临时凭证。例如,使用启用 MFA 的

aws> sts get-session-token --serial-number arn:aws:iam::1234:mfa/[email protected] --token-code 456789 --duration-seconds 129600

由于临时安全凭证是短期凭证,因此在它们过期后,用户需要生成新的凭证并使用新凭证修改 aws.yml 配置文件。除非为 Metricbeat 启用了 实时重新加载 功能,否则用户需要在更新配置文件后手动重新启动 Metricbeat 才能继续收集 Cloudwatch 指标。如果在旧凭证过期之前没有使用新凭证更新配置文件,这将导致数据丢失。对于 Metricbeat,我们建议用户在配置文件中使用访问密钥,以启用 aws 模块进行 AWS API 调用,而无需频繁生成新的临时凭证并更新配置。

IAM 策略是定义对 AWS 环境中对象的权限的实体。需要将特定权限添加到 IAM 用户的策略中,以授权 Metricbeat 收集 AWS 监控指标。有关所需权限,请参阅每个指标集下的文档。