

# 抓取其他 Prometheus 源并导入这些指标
<a name="ContainerInsights-Prometheus-Setup-configure"></a>

具有 Prometheus 监控功能的 CloudWatch 代理需要两种配置来抓取 Prometheus 指标。一个用于 Prometheus 文档中 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 记录的标准 Prometheus 配置。另一种配置是 CloudWatch 代理配置文件。

对于 Amazon EKS 集群，配置在 `prometheus-eks.yaml`（适用于 EC2 启动类型）或 `prometheus-eks-fargate.yaml`（适用于 Fargate 启动类型）中定义为两个 Config 映射：
+ `name: prometheus-config` 部分包含 Prometheus 抓取的设置。
+ `name: prometheus-cwagentconfig` 部分包含 CloudWatch 代理的配置。您可以使用此部分配置 CloudWatch 如何收集 Prometheus 指标。例如，您指定要导入 CloudWatch 的指标，并定义其维度。

对于在 Amazon EC2 实例上运行的 Kubernetes 集群，配置在 `prometheus-k8s.yaml` YAML 文件中定义为两个 config 映射：
+ `name: prometheus-config` 部分包含 Prometheus 抓取的设置。
+ `name: prometheus-cwagentconfig` 部分包含 CloudWatch 代理的配置。

要抓取其他 Prometheus 指标源并将这些指标导入 CloudWatch，您需要修改 Prometheus 抓取配置和 CloudWatch 代理配置，然后使用更新的配置重新部署代理。

**VPC 安全组要求**

Prometheus 工作负载的安全组的入口规则必须向 CloudWatch 代理打开 Prometheus 端口，以便通过私有 IP 抓取 Prometheus 指标。

CloudWatch 代理的安全组的出口规则必须允许 CloudWatch 代理通过私有 IP 连接到 Prometheus 工作负载的端口。

## Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Setup-config-global"></a>

CloudWatch 代理支持标准的 Prometheus 抓取配置，如 Prometheus 文档中的 [<scrape\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) 所述。您可以编辑此部分以更新此文件中已有的配置，并添加其他 Prometheus 抓取目标。默认情况下，示例配置文件包含以下全局配置行：

```
global:
  scrape_interval: 1m
  scrape_timeout: 10s
```
+ **scrape\$1interval** – 定义抓取目标的频率。
+ **scrape\$1timeout** – 定义抓取请求超时之前的等待时间。

您还可以在作业级别为这些设置定义不同的值，以覆盖全局配置。

### Prometheus 抓取任务
<a name="ContainerInsights-Prometheus-Setup-config-scrape"></a>

CloudWatch 代理 YAML 文件已配置了一些默认的抓取任务。例如在 `prometheus-eks.yaml` 中，在 `scrape_configs` 部分中的 `job_name` 行中配置了默认的抓取任务。在此文件中，以下默认 `kubernetes-pod-jmx` 部分会抓取 JMX Exporter 指标。

```
   - job_name: 'kubernetes-pod-jmx'
      sample_limit: 10000
      metrics_path: /metrics
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__address__]
        action: keep
        regex: '.*:9404$'
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: Namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container_name
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_controller_name
        target_label: pod_controller_name
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_controller_kind
        target_label: pod_controller_kind
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_phase
        target_label: pod_phase
```

这些默认目标中的每个目标都会被抓取，并使用嵌入式指标格式在日志事件中将指标发送到 CloudWatch。有关更多信息，请参阅 [在日志中嵌入指标](CloudWatch_Embedded_Metric_Format.md)。

来自 Amazon EKS 和 Kubernetes 集群的日志事件存储在 CloudWatch Logs 的 **/aws/containerinsights/*cluster\$1name*/prometheus** 日志组中。来自 Amazon ECS 集群的日志事件存储在 **/aws/ecs/containerinsights/*cluster\$1name*/prometheus** 日志组中。

每个抓取作业都包含在此日志组中的不同日志流中。例如，为 App Mesh 定义了 Prometheus 抓取任务 `kubernetes-pod-appmesh-envoy`。所有来自 Amazon EKS 和 Kubernetes 集群的 App Mesh Prometheus 指标都发送到名为 **/aws/containerinsights/*cluster\$1name*>prometheus/kubernetes-pod-appmesh-envoy/** 的日志流。

要添加新的抓取目标，请将新的 `job_name` 部分添加到 YAML 文件的 `scrape_configs` 部分，然后重新启动代理。有关此过程的示例，请参阅 [添加新 Prometheus 抓取目标的教程：Prometheus API 服务器指标](#ContainerInsights-Prometheus-Setup-new-exporters)。

## Prometheus 的 CloudWatch 代理配置
<a name="ContainerInsights-Prometheus-Setup-cw-agent-config2"></a>

CloudWatch 代理配置文件在 `metrics_collected` 下面有一个 `prometheus` 部分用于 Prometheus 抓取配置。它包含以下配置选项：
+ **cluster\$1name** – 指定要在日志事件中添加为标签的集群名称。该字段是可选的。如果省略它，代理可以检测到 Amazon EKS 或 Kubernetes 集群名称。
+ **log\$1group\$1name** – 指定已抓取 Prometheus 指标的日志组名称。该字段是可选的。如果省略它，CloudWatch 会将 **/aws/containerinsights/*cluster\$1name*/prometheus** 用于来自 Amazon EKS 和 Kubernetes 集群的日志。
+ **prometheus\$1config\$1path** – 指定 Prometheus 抓取配置文件路径。如果此字段的值以 `env:` 开头，Prometheus 抓取配置文件内容将从容器的环境变量中检索。请勿更改此字段。
+ **ecs\$1service\$1discovery** – 是指定 Amazon ECS Prometheus 服务发现配置的部分。有关更多信息，请参阅 [Amazon ECS 集群上自动发现的详细指南](ContainerInsights-Prometheus-Setup-autodiscovery-ecs.md)。

  `ecs_service_discovery` 部分包含以下字段：
  + `sd_frequency` 是发现 Prometheus 导出器的频率。指定数字和单位后缀。例如，`1m` 表示每分钟一次或 `30s` 表示每 30 秒一次。有效的单位后缀为 `ns`、`us`、`ms`、`s`、`m` 和 `h`。

    该字段是可选的。默认值为 60 秒（1 分钟）。
  + `sd_target_cluster` 是用于自动发现的目标 Amazon ECS 集群名称。该字段是可选的。默认名称为安装 CloudWatch 代理的 Amazon ECS 集群的名称。
  + `sd_cluster_region` 是目标 Amazon ECS 集群的区域。该字段是可选的。默认区域为安装 CloudWatch 代理的 Amazon ECS 集群的区域。
  + `sd_result_file` 是 Prometheus 目标结果的 YAML 文件的路径。Prometheus 抓取配置将引用此文件。
  + `docker_label` 是可选部分，您可以使用它来指定基于 docker 标签的服务发现的配置。如果省略此部分，则不会使用基于 docker 标签的发现。此部分包含以下字段：
    + `sd_port_label` 是容器的 docker 标签名称，用于指定 Prometheus 指标的容器端口。默认值为 `ECS_PROMETHEUS_EXPORTER_PORT`。如果容器没有此 docker 标签，CloudWatch 代理将跳过它。
    + `sd_metrics_path_label` 是容器的 docker 标签名称，用于指定 Prometheus 指标路径。默认值为 `ECS_PROMETHEUS_METRICS_PATH`。如果容器没有此 docker 标签，则代理会采用默认路径 `/metrics`。
    + `sd_job_name_label` 是容器的 docker 标签名称，用于指定 Prometheus 抓取任务名称。默认值为 `job`。如果容器没有此 docker 标签，CloudWatch 代理会使用 Prometheus 抓取配置中的任务名称。
  + `task_definition_list` 是可选部分，可用于指定基于任务定义的服务发现的配置。如果省略此部分，则不会使用基于任务定义的发现。此部分包含以下字段：
    + `sd_task_definition_arn_pattern` 是用于指定要发现的 Amazon ECS 任务定义的模式。这是正则表达式。
    + `sd_metrics_ports` 列出 Prometheus 指标的 containerPort。用分号分隔 containerPorts。
    + `sd_container_name_pattern` 指定 Amazon ECS 任务容器名称。这是正则表达式。
    + `sd_metrics_path` 指定 Prometheus 指标路径。如果省略此项，代理会采用默认路径 `/metrics`
    + `sd_job_name` 指定 Prometheus 抓取任务名称。如果省略此字段，CloudWatch 代理会使用 Prometheus 抓取配置中的任务名称。
+ **metric\$1declaration** – 是指定要生成的采用嵌入式指标格式的日志数组的部分。默认情况下，CloudWatch 代理从中进行导入的每个 Prometheus 源都有 `metric_declaration` 部分。这些部分各包括以下字段：
  + `label_matcher` 是一个正则表达式，用于检查 `source_labels` 中列出的标签的值。匹配的指标将启用，以包含在发送到 CloudWatch 的嵌入式指标格式中。

    如果您在 `source_labels` 中指定了多个标签，我们建议您不要在 `label_matcher` 的正则表达式中使用 `^` 或 `$` 字符。
  + `source_labels` 指定由 `label_matcher` 行检查的标签的值。
  + `label_separator` 指定要在 ` label_matcher` 行中使用的分隔符（如果指定了多个 `source_labels`）。默认值为 `;`。您可以在以下示例中看到 `label_matcher` 行中使用的此默认值。
  + `metric_selectors` 是一个正则表达式，用于指定要收集并发送到 CloudWatch 的指标。
  + `dimensions` 是要用作每个选定指标的 CloudWatch 维度的标签列表。

请参阅以下 `metric_declaration` 示例。

```
"metric_declaration": [
  {
     "source_labels":[ "Service", "Namespace"],
     "label_matcher":"(.*node-exporter.*|.*kube-dns.*);kube-system",
     "dimensions":[
        ["Service", "Namespace"]
     ],
     "metric_selectors":[
        "^coredns_dns_request_type_count_total$"
     ]
  }
]
```

此示例配置嵌入式指标格式部分，以便在满足以下条件时作为日志事件发送：
+ `Service` 的值包含 `node-exporter` 或 `kube-dns`。
+ `Namespace` 的值为 `kube-system`。
+ Prometheus 指标 `coredns_dns_request_type_count_total` 同时包含 `Service` 和 `Namespace` 标签。

发送的日志事件包括以下突出显示的部分：

```
{
   "CloudWatchMetrics":[
      {
         "Metrics":[
            {
               "Name":"coredns_dns_request_type_count_total"
            }
         ],
         "Dimensions":[
            [
               "Namespace",
               "Service"
            ]
         ],
         "Namespace":"ContainerInsights/Prometheus"
      }
   ],
   "Namespace":"kube-system",
   "Service":"kube-dns",
   "coredns_dns_request_type_count_total":2562,
   "eks_amazonaws_com_component":"kube-dns",
   "instance":"192.168.61.254:9153",
   "job":"kubernetes-service-endpoints",
   ...
}
```

## 添加新 Prometheus 抓取目标的教程：Prometheus API 服务器指标
<a name="ContainerInsights-Prometheus-Setup-new-exporters"></a>

默认情况下，Kubernetes API 服务器会在端点上公开 Prometheus 指标。Kubernetes API 服务器抓取配置的官方示例可在 [Github](https://github.com/prometheus/prometheus/blob/main/documentation/examples/prometheus-kubernetes.yml) 上找到。

以下教程演示如何执行以下步骤以开始将 Kubernetes API 服务器指标导入到 CloudWatch 中：
+ 将 Kubernetes API 服务器的 Prometheus 抓取配置添加到 CloudWatch 代理 YAML 文件。
+ 在 CloudWatch 代理 YAML 文件中配置嵌入式指标格式指标定义。
+ （可选）为 Kubernetes API 服务器指标创建 CloudWatch 控制面板。

**注意**  
Kubernetes API 服务器公开计量表、计数器、直方图和摘要指标。在此版本的 Prometheus 指标支持中，CloudWatch 仅导入具有计量表、计数器和汇总类型的指标。

**开始在 CloudWatch 中收集 Kubernetes API 服务器 Prometheus 指标**

1. 通过输入以下命令之一，下载 `prometheus-eks.yaml`、`prometheus-eks-fargate.yaml` 或 `prometheus-k8s.yaml` 文件的最新版本。

   对于具有 EC2 启动类型的 Amazon EKS 集群，请输入以下命令：

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks.yaml
   ```

   对于具有 Fargate 启动类型的 Amazon EKS 集群，请输入以下命令：

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks-fargate.yaml
   ```

   对于在 Amazon EC2 实例上运行的 Kubernetes 集群，请输入以下命令：

   ```
   curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-k8s.yaml
   ```

1. 使用文本编辑器打开文件，找到 `prometheus-config` 部分，然后在该部分中添加以下部分。然后，保存更改：

   ```
       # Scrape config for API servers
       - job_name: 'kubernetes-apiservers'
         kubernetes_sd_configs:
           - role: endpoints
             namespaces:
               names:
                 - default
         scheme: https
         tls_config:
           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
           insecure_skip_verify: true
         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
         relabel_configs:
         - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
           action: keep
           regex: kubernetes;https
         - action: replace
           source_labels:
           - __meta_kubernetes_namespace
           target_label: Namespace
         - action: replace
           source_labels:
           - __meta_kubernetes_service_name
           target_label: Service
   ```

1. 当 YAML 文件仍在文本编辑器中处于打开状态时，找到 `cwagentconfig.json` 部分。添加以下子部分并保存更改。此部分将 API 服务器指标放到 CloudWatch 代理允许列表中。将三种类型的 API 服务器指标添加到允许列表中：
   + etcd 对象计数
   + API 服务器注册控制器指标
   + API 服务器请求指标

   ```
   {"source_labels": ["job", "resource"],
     "label_matcher": "^kubernetes-apiservers;(services|daemonsets.apps|deployments.apps|configmaps|endpoints|secrets|serviceaccounts|replicasets.apps)",
     "dimensions": [["ClusterName","Service","resource"]],
     "metric_selectors": [
     "^etcd_object_counts$"
     ]
   },
   {"source_labels": ["job", "name"],
      "label_matcher": "^kubernetes-apiservers;APIServiceRegistrationController$",
      "dimensions": [["ClusterName","Service","name"]],
      "metric_selectors": [
      "^workqueue_depth$",
      "^workqueue_adds_total$",
      "^workqueue_retries_total$"
     ]
   },
   {"source_labels": ["job","code"],
     "label_matcher": "^kubernetes-apiservers;2[0-9]{2}$",
     "dimensions": [["ClusterName","Service","code"]],
     "metric_selectors": [
      "^apiserver_request_total$"
     ]
   },
   {"source_labels": ["job"],
     "label_matcher": "^kubernetes-apiservers",
     "dimensions": [["ClusterName","Service"]],
     "metric_selectors": [
     "^apiserver_request_total$"
     ]
   },
   ```

1. 如果您已在集群中部署了具有 Prometheus 支持的 CloudWatch 代理，则必须通过输入以下命令将其删除：

   ```
   kubectl delete deployment cwagent-prometheus -n amazon-cloudwatch
   ```

1. 通过输入以下任一命令，使用更新的配置部署 CloudWatch 代理。对于具有 EC2 启动类型的 Amazon EKS 集群，请输入：

   ```
   kubectl apply -f prometheus-eks.yaml
   ```

   对于具有 Fargate 启动类型的 Amazon EKS 集群，请输入以下命令。将 *MyCluster* 和 *region（区域）*替换为值以匹配您的部署。

   ```
   cat prometheus-eks-fargate.yaml \
   | sed "s/{{cluster_name}}/MyCluster/;s/{{region_name}}/region/" \
   | kubectl apply -f -
   ```

   对于 Kubernetes 集群，请输入以下命令。将 *MyCluster* 和 *region（区域）*替换为值以匹配您的部署。

   ```
   cat prometheus-k8s.yaml \
   | sed "s/{{cluster_name}}/MyCluster/;s/{{region_name}}/region/" \
   | kubectl apply -f -
   ```

完成此操作后，您应该会看到 **/aws/containerinsights/*cluster\$1name*/prometheus** 日志组中名为 **kubernetes-apiservers** 的新日志流。此日志流应使用嵌入式指标格式定义来嵌入日志事件，如下所示：

```
{
   "CloudWatchMetrics":[
      {
         "Metrics":[
            {
               "Name":"apiserver_request_total"
            }
         ],
         "Dimensions":[
            [
               "ClusterName",
               "Service"
            ]
         ],
         "Namespace":"ContainerInsights/Prometheus"
      }
   ],
   "ClusterName":"my-cluster-name",
   "Namespace":"default",
   "Service":"kubernetes",
   "Timestamp":"1592267020339",
   "Version":"0",
   "apiserver_request_count":0,
   "apiserver_request_total":0,
   "code":"0",
   "component":"apiserver",
   "contentType":"application/json",
   "instance":"192.0.2.0:443",
   "job":"kubernetes-apiservers",
   "prom_metric_type":"counter",
   "resource":"pods",
   "scope":"namespace",
   "verb":"WATCH",
   "version":"v1"
}
```

您可以在 **ContainerInsights/Prometheus** 命名空间中的 CloudWatch 控制台中查看您的指标。（可选）还可以为 Prometheus Kubernetes API 服务器指标创建 CloudWatch 控制面板。

### （可选）为 Kubernetes API 服务器指标创建控制面板
<a name="ContainerInsights-Prometheus-Setup-KPI-dashboard"></a>

要在控制面板中查看 Kubernetes API 服务器指标，您必须先完成前面几个部分中的步骤，然后才能开始在 CloudWatch 中收集这些指标。

**为 Kubernetes API 服务器指标创建控制面板**

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

1. 确保选择了正确的 Amazon 区域。

1. 在导航窗格中，选择**控制面板**。

1. 选择**创建控制面板**。输入新控制面板的名称，然后选择**创建控制面板**。

1. 在**添加到该控制面板**中，选择**取消**。

1. 依次选择**操作**、**编辑控制面板**。

1. 下载以下 JSON 文件：[Kubernetes API 控制面板源](https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_cloudwatch_dashboards/kubernetes_api_server/cw_dashboard_kubernetes_api_server.json)。

1. 使用文本编辑器打开下载的 JSON 文件，然后执行以下更改：
   + 将所有 `{{YOUR_CLUSTER_NAME}}` 字符串替换为您的集群的确切名称。请勿在文本之前或之后添加空格。
   + 将所有 `{{YOUR_AWS_REGION}}` 字符串替换为在其中收集指标的区域的名称。例如 `us-west-2`。请勿在文本之前或之后添加空格。

1. 复制整个 JSON blob 并将其粘贴到 CloudWatch 控制台的文本框中，替换框中已有的内容。

1. 选择**更新**、**保存控制面板**。