

# 在 Amazon EKS 和 Kubernetes 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup"></a>

本节介绍如何在运行 Amazon EKS 或 Kubernetes 的集群中设置带有 Prometheus 监控功能的 CloudWatch 代理。执行此操作后，代理会自动抓取并导入该集群中运行的以下工作负载的指标。
+ AWS App Mesh
+ NGINX
+ Memcached
+ Java/JMX
+ HAProxy
+ Fluent Bit

您还可以将代理配置为抓取和导入其他 Prometheus 工作负载和源。

在按照下面这些步骤安装 CloudWatch 代理来收集 Prometheus 指标之前，您必须有在 Amazon EKS 上运行的集群或者在 Amazon EC2 实例上运行的 Kubernetes 集群。

**VPC 安全组要求**

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

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

**Topics**
+ [在 Amazon EKS 和 Kubernetes 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理](#ContainerInsights-Prometheus-Setup-roles)
+ [抓取其他 Prometheus 源并导入这些指标](ContainerInsights-Prometheus-Setup-configure.md)
+ [（可选）为 Prometheus 指标测试设置示例容器化 Amazon EKS 工作负载](ContainerInsights-Prometheus-Sample-Workloads.md)

## 在 Amazon EKS 和 Kubernetes 集群上安装带有 Prometheus 指标收集功能的 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup-roles"></a>

本节介绍如何在运行 Amazon EKS 或 Kubernetes 的集群中设置带有 Prometheus 监控功能的 CloudWatch 代理。执行此操作后，代理会自动抓取并导入该集群中运行的以下工作负载的指标。
+ AWS App Mesh
+ NGINX
+ Memcached
+ Java/JMX
+ HAProxy
+ Fluent Bit

您还可以将代理配置为抓取和导入其他 Prometheus 工作负载和源。

在按照下面这些步骤安装 CloudWatch 代理来收集 Prometheus 指标之前，您必须有在 Amazon EKS 上运行的集群或者在 Amazon EC2 实例上运行的 Kubernetes 集群。

**VPC 安全组要求**

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

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

**Topics**
+ [设置 IAM 角色](#ContainerInsights-Prometheus-Setup-roles)
+ [安装 CloudWatch 代理以收集 Prometheus 指标](#ContainerInsights-Prometheus-Setup-install-agent)

### 设置 IAM 角色
<a name="ContainerInsights-Prometheus-Setup-roles"></a>

第一步是在集群中设置必要的 IAM 角色。有两种方法：
+ 为服务账户设置 IAM 角色，也称为*服务角色*。此方法适用于 EC2 启动类型和 Fargate 启动类型。
+ 将 IAM 策略添加到集群的 IAM 角色。这仅适用于 EC2 启动类型。

**设置服务角色（EC2 启动类型和 Fargate 启动类型）**

要设置服务角色，请输入以下命令。将 *MyCluster* 替换为集群的名称。

```
eksctl create iamserviceaccount \
 --name cwagent-prometheus \
--namespace amazon-cloudwatch \
 --cluster MyCluster \
--attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
--approve \
--override-existing-serviceaccounts
```

**向节点组的 IAM 角色添加策略（仅限 EC2 启动类型）**

**在节点组中为 Prometheus 支持设置 IAM 策略**

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在导航窗格中，选择 **Instances (实例)**。

1. 您需要查找集群的 IAM 角色名称的前缀。为此，请选中集群中实例名称旁边的复选框，然后依次选择**操作**、**安全性**、**修改 IAM 角色**。然后复制 IAM 角色的前缀，例如 `eksctl-dev303-workshop-nodegroup`。

1. 通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中，选择**角色**。

1. 使用搜索框查找您在此过程前面复制的前缀，然后选择该角色。

1. 选择**附加策略**。

1. 使用搜索框查找 **CloudWatchAgentServerPolicy**。选中 **CloudWatchAgentServerPolicy** 旁边的复选框，然后选择**附加策略**。

### 安装 CloudWatch 代理以收集 Prometheus 指标
<a name="ContainerInsights-Prometheus-Setup-install-agent"></a>

您必须在集群中安装 CloudWatch 代理才能收集指标。对于 Amazon EKS 集群和 Kubernetes 集群，安装代理的方式有所不同。

**删除具有 Prometheus 支持的 CloudWatch 代理的早期版本**

如果您的集群中已安装了具有 Prometheus 支持的 CloudWatch 代理版本，则必须通过输入以下命令删除该版本。这仅对具有 Prometheus 支持的以前版本的代理是必要的。您无需删除启用了 Container Insights 但没有 Prometheus 支持的 CloudWatch 代理。

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

#### 在具有 EC2 启动类型的 Amazon EKS 集群上安装 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup-install-agent-EKS"></a>

要在 Amazon EKS 集群上安装具有 Prometheus 支持的 CloudWatch 代理，请按照下列步骤操作。

**在 Amazon EKS 集群上安装具有 Prometheus 支持的 CloudWatch 代理**

1. 输入以下命令，检查是否已创建 `amazon-cloudwatch` 命名空间：

   ```
   kubectl get namespace
   ```

1. 如果结果中未显示 `amazon-cloudwatch`，请输入以下命令来创建它：

   ```
   kubectl create namespace amazon-cloudwatch
   ```

1. 要使用默认配置部署代理并使其将数据发送到所在的 AWS 区域，请输入以下命令：

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

   要让代理将数据发送到不同的区域，请按照下列步骤操作：

   1. 输入以下命令，下载代理的 YAML 文件：

      ```
      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
      ```

   1. 使用文本编辑器打开文件，然后搜索文件的 `cwagentconfig.json` 块。

   1. 添加突出显示的行，并指定所需的区域：

      ```
      cwagentconfig.json: |
          {
            "agent": {
              "region": "us-east-2"
            },
            "logs": { ...
      ```

   1. 保存文件并使用更新后的文件部署代理。

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

#### 在具有 Fargate 启动类型的 Amazon EKS 集群上安装 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup-install-agent-EKS-fargate"></a>

要在具有 Fargate 启动类型的 Amazon EKS 集群上安装具有 Prometheus 支持的 CloudWatch 代理，请按照下列步骤操作。

**在具有 Fargate 启动类型的 Amazon EKS 集群上安装具有 Prometheus 支持的 CloudWatch 代理**

1. 输入以下命令为 CloudWatch 代理创建 Fargate 配置文件，以便它可以在集群内运行。将 *MyCluster* 替换为集群的名称。

   ```
   eksctl create fargateprofile --cluster MyCluster \
   --name amazon-cloudwatch \
   --namespace amazon-cloudwatch
   ```

1. 要安装 CloudWatch 代理，请输入以下命令。将 *MyCluster* 替换为集群的名称。此名称在存储代理收集的日志事件的日志组名称中使用，也用作代理收集的指标的维度。

   将 *region（区域）*替换为要将指标发送到的区域的名称。例如 `us-west-1`。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks-fargate.yaml | 
   sed "s/{{cluster_name}}/MyCluster/;s/{{region_name}}/region/" | 
   kubectl apply -f -
   ```

#### 在 Kubernetes 集群上安装 CloudWatch 代理
<a name="ContainerInsights-Prometheus-Setup-install-agent-Kubernetes"></a>

要在运行 Kubernetes 的集群上安装具有 Prometheus 支持的 CloudWatch 代理，请输入以下命令：

```
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-k8s.yaml | 
sed "s/{{cluster_name}}/MyCluster/;s/{{region_name}}/region/" | 
kubectl apply -f -
```

将 *MyCluster* 替换为集群的名称。此名称在存储代理收集的日志事件的日志组名称中使用，也用作代理收集的指标的维度。

将 *region（区域）*替换为要将指标发送到的 AWS 区域的名称。例如 **us-west-1**。

#### 验证代理是否正在运行
<a name="ContainerInsights-Prometheus-Setup-install-agent-verify"></a>

在 Amazon EKS 和 Kubernetes 集群上，您可以输入以下命令以确认代理正在运行。

```
kubectl get pod -l "app=cwagent-prometheus" -n amazon-cloudwatch
```

如果结果包含处于 `Running` 状态的单个 CloudWatch 代理 pod，则代理会运行并收集 Prometheus 指标。默认情况下，CloudWatch 代理每分钟会收集 App Mesh、NGINX、Memcached、Java/JMX 和 HAProxy 的指标。有关这些指标的更多信息，请参阅 [CloudWatch 代理收集的 Prometheus 指标](ContainerInsights-Prometheus-metrics.md)。有关如何在 CloudWatch 中查看 Prometheus 指标的说明，请参阅 [查看 Prometheus 指标](ContainerInsights-Prometheus-viewmetrics.md)

您还可以将 CloudWatch 代理配置为从其他 Prometheus 导出程序收集指标。有关更多信息，请参阅 [抓取其他 Prometheus 源并导入这些指标](ContainerInsights-Prometheus-Setup-configure.md)。

# 抓取其他 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.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

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

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. 选择**更新**、**保存控制面板**。

# （可选）为 Prometheus 指标测试设置示例容器化 Amazon EKS 工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads"></a>

要测试 CloudWatch Container Insights 中的 Prometheus 指标支持，您可设置以下一个或多个容器化工作负载。具有 Prometheus 支持的 CloudWatch 代理会自动从这些工作负载中的每一个收集指标。要查看默认情况下收集的指标，请参阅 [CloudWatch 代理收集的 Prometheus 指标](ContainerInsights-Prometheus-metrics.md)。

在安装任意这些工作负载之前，您必须输入以下命令来安装 Helm 3.x：

```
brew install helm
```

有关更多信息，请参阅 [Helm](https://helm.sh)。

**Topics**
+ [为 Amazon EKS 和 Kubernetes 设置 AWS App Mesh 示例工作负载](ContainerInsights-Prometheus-Sample-Workloads-appmesh.md)
+ [使用 Amazon EKS 和 Kubernetes 上的示例流量设置 NGINX](ContainerInsights-Prometheus-Sample-Workloads-nginx.md)
+ [使用 Amazon EKS 和 Kubernetes 上的指标导出器设置 memcached](ContainerInsights-Prometheus-Sample-Workloads-memcached.md)
+ [在 Amazon EKS 和 Kubernetes 上设置 Java/JMX 示例工作负载](ContainerInsights-Prometheus-Sample-Workloads-javajmx.md)
+ [使用 Amazon EKS 和 Kubernetes 上的指标导出器设置 HAProxy](ContainerInsights-Prometheus-Sample-Workloads-haproxy.md)
+ [添加新 Prometheus 抓取目标的教程：Amazon EKS 和 Kubernetes 集群上的 Redis OSS](ContainerInsights-Prometheus-Setup-redis-eks.md)

# 为 Amazon EKS 和 Kubernetes 设置 AWS App Mesh 示例工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh"></a>

CloudWatch Container Insights 支持 AWS App Mesh 中的 Prometheus 支持。以下部分介绍了如何设置 App Mesh。

**Topics**
+ [在具有 EC2 启动类型或 Kubernetes 集群的 Amazon EKS 集群上设置 AWS App Mesh 示例工作负载](ContainerInsights-Prometheus-Sample-Workloads-appmesh-EKS.md)
+ [使用 Fargate 启动类型在 Amazon EKS 集群上设置 AWS App Mesh 示例工作负载](ContainerInsights-Prometheus-Sample-Workloads-appmesh-Fargate.md)

# 在具有 EC2 启动类型或 Kubernetes 集群的 Amazon EKS 集群上设置 AWS App Mesh 示例工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-EKS"></a>

如果您要在运行 Amazon EKS 且具有 EC2 启动类型的集群或 Kubernetes 集群上设置 App Mesh，请使用这些说明。

## 配置 IAM 权限
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-iam"></a>

必须将 **AWSAppMeshFullAccess** 策略添加到您的 Amazon EKS 或 Kubernetes 节点组的 IAM 角色中。在 Amazon EKS 上，此节点组名称类似于 `eksctl-integ-test-eks-prometheus-NodeInstanceRole-ABCDEFHIJKL`。在 Kubernetes 上，它可能类似于 `nodes.integ-test-kops-prometheus.k8s.local`。

## 安装 App Mesh
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-install"></a>

要安装 App Mesh Kubernetes 控制器，请按照 [App Mesh 控制器](https://github.com/aws/eks-charts/tree/master/stable/appmesh-controller#app-mesh-controller)中的说明进行操作。

## 安装示例应用程序
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-application"></a>

[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) 包含多个 Kubernetes App Mesh 演练。在本教程中，您将安装一个示例颜色应用程序，该应用程序会展示 http 路由如何使用标头来匹配传入请求。

**使用示例 App Mesh 应用程序来测试 Container Insights**

1. 按照以下说明安装应用程序：[https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-http-headers](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-http-headers)。

1. 启动 curler pod 以生成流量：

   ```
   kubectl -n default run -it curler --image=tutum/curl /bin/bash
   ```

1. 通过更改 HTTP 标头来对不同的端点执行 curl。多次运行 curl 命令，如下所示：

   ```
   curl -H "color_header: blue" front.howto-k8s-http-headers.svc.cluster.local:8080/; echo;
   
   curl -H "color_header: red" front.howto-k8s-http-headers.svc.cluster.local:8080/; echo;
   
   curl -H "color_header: yellow" front.howto-k8s-http-headers.svc.cluster.local:8080/; echo;
   ```

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

1. 在集群运行的 AWS 区域的导航窗格中，选择 **Metrics（指标）**。指标位于 **ContainerInsights/Prometheus** 命名空间中。

1. 要查看 CloudWatch Logs 事件，请在导航窗格中选择 **Log groups（日志组）**。事件位于日志流 `kubernetes-pod-appmesh-envoy` 的日志组 ` /aws/containerinsights/your_cluster_name/prometheus ` 中。

## 删除 App Mesh 测试环境
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-delete"></a>

App Mesh 和示例应用程序使用完成后，请使用以下命令删除不必要的资源。输入以下命令删除示例应用程序：

```
cd aws-app-mesh-examples/walkthroughs/howto-k8s-http-headers/
kubectl delete -f _output/manifest.yaml
```

输入以下命令删除 App Mesh 控制器：

```
helm delete appmesh-controller -n appmesh-system
```

# 使用 Fargate 启动类型在 Amazon EKS 集群上设置 AWS App Mesh 示例工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-Fargate"></a>

如果您要在运行 Amazon EKS 且具有 Fargate 启动类型的集群上设置 App Mesh，请遵循这些说明。

## 配置 IAM 权限
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh--fargate-iam"></a>

要设置 IAM 权限，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

```
eksctl create iamserviceaccount --cluster MyCluster \
 --namespace howto-k8s-fargate \
 --name appmesh-pod \
 --attach-policy-arn arn:aws:iam::aws:policy/AWSAppMeshEnvoyAccess \
 --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapDiscoverInstanceAccess \
 --attach-policy-arn arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess \
 --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess \
 --attach-policy-arn arn:aws:iam::aws:policy/AWSAppMeshFullAccess \
 --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess \
 --override-existing-serviceaccounts \
 --approve
```

## 安装 App Mesh
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-fargate-install"></a>

要安装 App Mesh Kubernetes 控制器，请按照 [App Mesh 控制器](https://github.com/aws/eks-charts/tree/master/stable/appmesh-controller#app-mesh-controller)中的说明进行操作。请务必按照有关 Fargate 启动类型的 Amazon EKS 的说明进行操作。

## 安装示例应用程序
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-fargate-application"></a>

[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) 包含多个 Kubernetes App Mesh 演练。在本教程中，您将安装适用于 Fargate 启动类型的 Amazon EKS 集群的示例颜色应用程序。

**使用示例 App Mesh 应用程序来测试 Container Insights**

1. 按照以下说明安装应用程序：[https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-fargate](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-fargate)。

   这些说明假定您正在使用正确的 Fargate 配置文件创建新集群。如果您想使用已设置的 Amazon EKS 集群，您可以使用以下命令为本演示设置该集群。将 *MyCluster* 替换为您的集群的名称。

   ```
   eksctl create iamserviceaccount --cluster MyCluster \
    --namespace howto-k8s-fargate \
    --name appmesh-pod \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSAppMeshEnvoyAccess \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapDiscoverInstanceAccess \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess \
    --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSAppMeshFullAccess \
    --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess \
    --override-existing-serviceaccounts \
    --approve
   ```

   ```
   eksctl create fargateprofile --cluster MyCluster \
   --namespace howto-k8s-fargate --name howto-k8s-fargate
   ```

1. 端口转发前端应用程序部署：

   ```
   kubectl -n howto-k8s-fargate port-forward deployment/front 8080:8080
   ```

1. Curl 前端应用程序：

   ```
   while true; do  curl -s http://localhost:8080/color; sleep 0.1; echo ; done
   ```

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

1. 在集群运行的 AWS 区域的导航窗格中，选择 **Metrics（指标）**。指标位于 **ContainerInsights/Prometheus** 命名空间中。

1. 要查看 CloudWatch Logs 事件，请在导航窗格中选择 **Log groups（日志组）**。事件位于日志流 `kubernetes-pod-appmesh-envoy` 的日志组 ` /aws/containerinsights/your_cluster_name/prometheus ` 中。

## 删除 App Mesh 测试环境
<a name="ContainerInsights-Prometheus-Sample-Workloads-appmesh-fargate-delete"></a>

App Mesh 和示例应用程序使用完成后，请使用以下命令删除不必要的资源。输入以下命令删除示例应用程序：

```
cd aws-app-mesh-examples/walkthroughs/howto-k8s-fargate/
kubectl delete -f _output/manifest.yaml
```

输入以下命令删除 App Mesh 控制器：

```
helm delete appmesh-controller -n appmesh-system
```

# 使用 Amazon EKS 和 Kubernetes 上的示例流量设置 NGINX
<a name="ContainerInsights-Prometheus-Sample-Workloads-nginx"></a>

NGINX 是一个 Web 服务器，也可以用作负载均衡器和反向代理。有关 Kubernetes 如何使用 NGINX for ingress 的更多信息，请参阅 [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx)。

**安装带有示例流量服务的 Ingress-NGINX 以测试 Container Insights Prometheus 支持**

1. 输入以下命令以添加 Helm ingress-nginx 存储库：

   ```
   helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
   ```

1. 输入以下命令：

   ```
   kubectl create namespace nginx-ingress-sample
   
   helm install my-nginx ingress-nginx/ingress-nginx \
   --namespace nginx-ingress-sample \
   --set controller.metrics.enabled=true \
   --set-string controller.metrics.service.annotations."prometheus\.io/port"="10254" \
   --set-string controller.metrics.service.annotations."prometheus\.io/scrape"="true"
   ```

1. 通过输入以下命令检查服务是否正确启动：

   ```
   kubectl get service -n nginx-ingress-sample
   ```

   此命令的输出应显示多列，包括一个 `EXTERNAL-IP` 列。

1. 将 `EXTERNAL-IP` 变量设置为 NGINX 摄取控制器的行中 `EXTERNAL-IP` 列的值。

   ```
   EXTERNAL_IP=your-nginx-controller-external-ip
   ```

1. 输入以下命令启动一些示例 NGINX 流量。

   ```
   SAMPLE_TRAFFIC_NAMESPACE=nginx-sample-traffic
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_traffic/nginx-traffic/nginx-traffic-sample.yaml | 
   sed "s/{{external_ip}}/$EXTERNAL_IP/g" | 
   sed "s/{{namespace}}/$SAMPLE_TRAFFIC_NAMESPACE/g" | 
   kubectl apply -f -
   ```

1. 输入以下命令以确认所有三个 pod 都处于 `Running` 状态。

   ```
   kubectl get pod -n $SAMPLE_TRAFFIC_NAMESPACE
   ```

   如果它们正在运行，您应该很快在 **ContainerInsights/Prometheus** 命名空间中看到指标。

**卸载 NGINX 和示例流量应用程序**

1. 输入以下命令删除示例流量服务：

   ```
   kubectl delete namespace $SAMPLE_TRAFFIC_NAMESPACE
   ```

1. 按 Helm 版本名称删除 NGINX 出口。

   ```
   helm uninstall my-nginx --namespace nginx-ingress-sample
   kubectl delete namespace nginx-ingress-sample
   ```

# 使用 Amazon EKS 和 Kubernetes 上的指标导出器设置 memcached
<a name="ContainerInsights-Prometheus-Sample-Workloads-memcached"></a>

memcached 是一个开源内存对象缓存系统。有关更多信息，请参阅[什么是 Memcached？](https://www.memcached.org)

如果您在具有 Fargate 启动类型的集群上运行 memcached，则需要在执行此过程中的步骤之前设置 Fargate 配置文件。要设置配置文件，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

```
eksctl create fargateprofile --cluster MyCluster \
--namespace memcached-sample --name memcached-sample
```

**安装带有 Metric Exporter 的 memcached 以测试 Container Insights Prometheus 支持**

1. 输入以下命令以添加存储库：

   ```
   helm repo add bitnami https://charts.bitnami.com/bitnami
   ```

1. 输入以下命令以创建新的命名空间：

   ```
   kubectl create namespace memcached-sample
   ```

1. 输入以下命令以安装 Memcached

   ```
   helm install my-memcached bitnami/memcached --namespace memcached-sample \
   --set metrics.enabled=true \
   --set-string serviceAnnotations.prometheus\\.io/port="9150" \
   --set-string serviceAnnotations.prometheus\\.io/scrape="true"
   ```

1. 输入以下命令以确认正在运行的服务的注释：

   ```
   kubectl describe service my-memcached-metrics -n memcached-sample
   ```

   您应该看到以下两个注释：

   ```
   Annotations:   prometheus.io/port: 9150
                  prometheus.io/scrape: true
   ```

**卸载 memcached**
+ 输入以下命令：

  ```
  helm uninstall my-memcached --namespace memcached-sample
  kubectl delete namespace memcached-sample
  ```

# 在 Amazon EKS 和 Kubernetes 上设置 Java/JMX 示例工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx"></a>

JMX Exporter 是 Prometheus 的官方导出程序，可以将 JMX MBeans 作为 Prometheus 指标进行抓取和公开。有关详细信息，请参阅 [prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter)。

Container Insights 可以使用 JMX Exporter 从 Java 虚拟机 (JVM)、Java 和 Tomcat (Catalina) 收集预定义的 Prometheus 指标。

## 默认 Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-default"></a>

默认情况下，支持 Prometheus 的 CloudWatch 代理从 Amazon EKS 或 Kubernetes 集群中的每个 pod 上的 `http://CLUSTER_IP:9404/metrics` 抓取 Java/JMX Prometheus 指标。这是通过 Prometheus `kubernetes_sd_config` 的 `role: pod` 发现来完成的。9404 是 Prometheus 为 JMX Exporter 分配的默认端口。有关 `role: pod` 发现的更多信息，请参阅 [pod](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#pod)。您可以将 JMX Exporter 配置为在不同端口或 metrics\$1path 上公开指标。如果您更改了端口或路径，请更新 CloudWatch 代理 config 映射中的默认 jmx scrape\$1config。运行以下命令以获取当前 CloudWatch 代理 Prometheus 配置：

```
kubectl describe cm prometheus-config -n amazon-cloudwatch
```

要更改的字段是 `/metrics` 和 `regex: '.*:9404$'` 字段，如以下示例中突出显示所示。

```
job_name: 'kubernetes-jmx-pod'
sample_limit: 10000
metrics_path: /metrics
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__address__]
  action: keep
  regex: '.*:9404$'
- action: replace
  regex: (.+)
  source_labels:
```

## 其他 Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-other"></a>

如果您通过 Kubernetes Service 使用 Java/JMX Prometheus 导出器公开在一组 pod 上运行的应用程序，您还可以切换到使用 Prometheus `kubernetes_sd_config` 的 `role: service` 发现或 `role: endpoint` 发现。有关这些发现方法的更多信息，请参阅[服务](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#service)、[端点](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#endpoints) 和 [<kubernetes\$1sd\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config)。

这两种服务发现模式提供了更多元标签，这对构建 CloudWatch 指标维度大有裨益。例如，您可以将 `__meta_kubernetes_service_name` 其重新标记为 `Service` 并将其包含在指标维度中。有关自定义 CloudWatch 指标及其维度的更多信息，请参阅 [Prometheus 的 CloudWatch 代理配置](ContainerInsights-Prometheus-Setup-configure-ECS.md#ContainerInsights-Prometheus-Setup-cw-agent-config)。

## 带有 JMX Exporter 的 Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-docker"></a>

接下来，构建 Docker 镜像。以下各节提供了两个示例 Dockerfiles。

构建镜像后，请将其加载到 Amazon EKS 或 Kubernetes 中，然后运行以下命令以验证 `JMX_EXPORTER` 是否在端口 9404 上公开 Prometheus 指标。使用正在运行的 pod 名称替换 *\$1JAR\$1SAMPLE\$1TRAFFIC\$1POD*，并使用您的应用程序命名空间替换 *\$1JAR\$1SAMPLE\$1TRAFFIC\$1NAMESPACE*。

如果您在具有 Fargate 启动类型的集群上运行 JMX Exporter，则在执行此过程中的步骤之前，您还需要设置 Fargate 配置文件。要设置配置文件，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

```
eksctl create fargateprofile --cluster MyCluster \
--namespace $JAR_SAMPLE_TRAFFIC_NAMESPACE\
 --name $JAR_SAMPLE_TRAFFIC_NAMESPACE
```

```
kubectl exec $JAR_SAMPLE_TRAFFIC_POD -n $JARCAT_SAMPLE_TRAFFIC_NAMESPACE -- curl http://localhost:9404
```

## 示例：具有 Prometheus 指标的 Apache Tomcat Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-tomcat"></a>

默认情况下，Apache Tomcat 服务器公开 JMX MBeans。您可以将 JMX Exporter 与 Tomcat 集成，以便将 JMX MBeans 作为 Prometheus 指标公开。以下示例 Dockerfile 显示了构建测试镜像的步骤：

```
# From Tomcat 9.0 JDK8 OpenJDK 
FROM tomcat:9.0-jdk8-openjdk 

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter
COPY ./setenv.sh /usr/local/tomcat/bin 
COPY your web application.war /usr/local/tomcat/webapps/

RUN chmod  o+x /usr/local/tomcat/bin/setenv.sh

ENTRYPOINT ["catalina.sh", "run"]
```

下面的列表解释了此 Dockerfile 中的四个 `COPY` 行。
+ 从 [https://github.com/prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter) 下载最新的 JMX Exporter jar 文件。
+ `config.yaml` 是 JMX Exporter 配置文件。有关更多信息，请参阅 [https://github.com/prometheus/jmx\$1exporter\$1Configuration](https://github.com/prometheus/jmx_exporter#Configuration )。

  以下是 Java 和 Tomcat 的示例配置文件：

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `setenv.sh` 是一个 Tomcat 启动脚本，用于启动 JMX Exporter 和 Tomcat，并在本地主机的端口 9404 上公开 Prometheus 指标。它还为 JMX Exporter 提供 `config.yaml` 文件路径。

  ```
  $ cat setenv.sh 
  export JAVA_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml $JAVA_OPTS"
  ```
+ 您的 Web 应用程序 .war 是由 Tomcat 加载的 Web 应用程序 `war` 文件。

使用此配置构建 Docker 镜像并将其上载到镜像存储库。

## 示例：具有 Prometheus 指标的 Java Jar 应用程序 Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-jar"></a>

以下示例 Dockerfile 显示了构建测试镜像的步骤：

```
# Alpine Linux with OpenJDK JRE
FROM openjdk:8-jre-alpine

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./SampleJavaApplication-1.0-SNAPSHOT.jar /opt/jmx_exporter
COPY ./start_exporter_example.sh /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter

RUN chmod -R o+x /opt/jmx_exporter
RUN apk add curl

ENTRYPOINT exec /opt/jmx_exporter/start_exporter_example.sh
```

下面的列表解释了此 Dockerfile 中的四个 `COPY` 行。
+ 从 [https://github.com/prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter) 下载最新的 JMX Exporter jar 文件。
+ `config.yaml` 是 JMX Exporter 配置文件。有关更多信息，请参阅 [https://github.com/prometheus/jmx\$1exporter\$1Configuration](https://github.com/prometheus/jmx_exporter#Configuration )。

  以下是 Java 和 Tomcat 的示例配置文件：

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `start_exporter_example.sh` 是用于启动导出了 Prometheus 指标的 JAR 应用程序的脚本。它还为 JMX Exporter 提供 `config.yaml` 文件路径。

  ```
  $ cat start_exporter_example.sh 
  java -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml -cp  /opt/jmx_exporter/SampleJavaApplication-1.0-SNAPSHOT.jar com.gubupt.sample.app.App
  ```
+ SampleJavaApplication-1.0-SNAPSHOT.jar 是示例 Java 应用程序 jar 文件。将其替换为要监控的 Java 应用程序。

使用此配置构建 Docker 镜像并将其上载到镜像存储库。

# 使用 Amazon EKS 和 Kubernetes 上的指标导出器设置 HAProxy
<a name="ContainerInsights-Prometheus-Sample-Workloads-haproxy"></a>

HAProxy 是一个开源代理应用程序。有关更多信息，请参阅 [HAProxy](https://www.haproxy.org)。

如果您在具有 Fargate 启动类型的集群上运行 HAProxy，则在执行此过程中的步骤之前，您需要设置 Fargate 配置文件。要设置配置文件，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

```
eksctl create fargateprofile --cluster MyCluster \
--namespace haproxy-ingress-sample --name haproxy-ingress-sample
```

**安装带有 Metric Exporter 的 HAProxy 以测试 Container Insights Prometheus 支持**

1. 输入以下命令以添加 Helm incubator 存储库：

   ```
   helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts
   ```

1. 输入以下命令以创建新的命名空间：

   ```
   kubectl create namespace haproxy-ingress-sample
   ```

1. 输入以下命令来安装 HAProxy：

   ```
   helm install haproxy haproxy-ingress/haproxy-ingress \
   --namespace haproxy-ingress-sample \
   --set defaultBackend.enabled=true \
   --set controller.stats.enabled=true \
   --set controller.metrics.enabled=true \
   --set-string controller.metrics.service.annotations."prometheus\.io/port"="9101" \
   --set-string controller.metrics.service.annotations."prometheus\.io/scrape"="true"
   ```

1. 输入以下命令以确认服务的注释：

   ```
   kubectl describe service haproxy-haproxy-ingress-metrics -n haproxy-ingress-sample
   ```

   您应该看到以下注释。

   ```
   Annotations:   prometheus.io/port: 9101
                  prometheus.io/scrape: true
   ```

**卸载 HAProxy**
+ 输入以下命令：

  ```
  helm uninstall haproxy --namespace haproxy-ingress-sample
  kubectl delete namespace haproxy-ingress-sample
  ```

# 添加新 Prometheus 抓取目标的教程：Amazon EKS 和 Kubernetes 集群上的 Redis OSS
<a name="ContainerInsights-Prometheus-Setup-redis-eks"></a>

本教程提供了在 Amazon EKS 和 Kubernetes 上抓取示例 Redis OSS 应用程序的 Prometheus 指标的实践介绍。Redis OSS（https://redis.io/）是一个开源（获得 BSD 许可）的内存数据结构存储，用作数据库、缓存和消息代理。有关更多信息，请参阅 [ redis](https://redis.io/)。

redis\$1exporter（获得 MIT 许可证）用于在指定端口（默认值：0.0.0.0:9121）上公开 Redis OSS prometheus 指标。有关更多信息，请参阅 [redis\$1exporter](https://github.com/oliver006/redis_exporter)。

本教程使用了以下两个 Docker Hub 存储库中的 Docker 镜像：
+ [redis](https://hub.docker.com/_/redis?tab=description)
+ [redis\$1exporter](https://hub.docker.com/r/oliver006/redis_exporter)

**安装公开 Prometheus 指标的示例 Redis OSS 工作负载**

1. 为示例 Redis OSS 工作负载设置命名空间。

   ```
   REDIS_NAMESPACE=redis-sample
   ```

1. 如果您在具有 Fargate 启动类型的集群上运行 Redis OSS，则需要设置 Fargate 配置文件。要设置配置文件，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

   ```
   eksctl create fargateprofile --cluster MyCluster \
   --namespace $REDIS_NAMESPACE --name $REDIS_NAMESPACE
   ```

1. 输入以下命令以安装示例 Redis OSS 工作负载。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_traffic/redis/redis-traffic-sample.yaml \
   | sed "s/{{namespace}}/$REDIS_NAMESPACE/g" \
   | kubectl apply -f -
   ```

1. 安装包括一个名为 `my-redis-metrics` 的服务，该服务在端口 9121 上公开 Redis OSS Prometheus 指标。输入以下命令以获取该服务的详细信息：

   ```
   kubectl describe service/my-redis-metrics  -n $REDIS_NAMESPACE
   ```

   在结果的 `Annotations` 部分，您将看到与 CloudWatch 代理的 Prometheus 抓取配置相匹配的两个注释，以便其可以自动发现工作负载：

   ```
   prometheus.io/port: 9121
   prometheus.io/scrape: true
   ```

   相关的 Prometheus 抓取配置可以在 `kubernetes-eks.yaml` 或 `kubernetes-k8s.yaml` 部分的 `- job_name: kubernetes-service-endpoints` 中找到。

**开始在 CloudWatch 中收集 Redis OSS Prometheus 指标**

1. 通过输入以下任一命令，下载 `kubernetes-eks.yaml` 或 `kubernetes-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. 使用文本编辑器打开文件，然后找到 `cwagentconfig.json` 部分。添加以下子部分并保存更改。确保遵循现有模式缩进。

   ```
   {
     "source_labels": ["pod_name"],
     "label_matcher": "^redis-instance$",
     "dimensions": [["Namespace","ClusterName"]],
     "metric_selectors": [
       "^redis_net_(in|out)put_bytes_total$",
       "^redis_(expired|evicted)_keys_total$",
       "^redis_keyspace_(hits|misses)_total$",
       "^redis_memory_used_bytes$",
       "^redis_connected_clients$"
     ]
   },
   {
     "source_labels": ["pod_name"],
     "label_matcher": "^redis-instance$",
     "dimensions": [["Namespace","ClusterName","cmd"]],
     "metric_selectors": [
       "^redis_commands_total$"
     ]
   },
   {
     "source_labels": ["pod_name"],
     "label_matcher": "^redis-instance$",
     "dimensions": [["Namespace","ClusterName","db"]],
     "metric_selectors": [
       "^redis_db_keys$"
     ]
   },
   ```

   您添加的部分会将 Redis OSS 指标放入 CloudWatch 代理允许列表中。有关这些指标的列表，请参阅以下部分。

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

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

1. 通过输入以下任一命令，使用更新的配置部署 CloudWatch 代理。替换 *MyCluster* 和 *region（区域）*以匹配您的设置。

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

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

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

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

   对于 Kubernetes 集群，请输入此命令。

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

## 查看 Redis OSS Prometheus 指标
<a name="ContainerInsights-Prometheus-Setup-redis-eks-view"></a>

本教程会将以下指标发送到 CloudWatch 中的 **ContainerInsights/Prometheus** 命名空间。您可以使用 CloudWatch 控制台查看该命名空间中的指标。


| 指标名称 | Dimensions | 
| --- | --- | 
|  `redis_net_input_bytes_total` |  ClusterName、`Namespace`  | 
|  `redis_net_output_bytes_total` |  ClusterName、`Namespace`  | 
|  `redis_expired_keys_total` |  ClusterName、`Namespace`  | 
|  `redis_evicted_keys_total` |  ClusterName、`Namespace`  | 
|  `redis_keyspace_hits_total` |  ClusterName、`Namespace`  | 
|  `redis_keyspace_misses_total` |  ClusterName、`Namespace`  | 
|  `redis_memory_used_bytes` |  ClusterName、`Namespace`  | 
|  `redis_connected_clients` |  ClusterName、`Namespace`  | 
|  `redis_commands_total` |  ClusterName、`Namespace`、cmd  | 
|  `redis_db_keys` |  Cluster、`Namespace`、db  | 

**注意**  
**cmd** 维度的值可以是 `append`、`client`、`command`、`config`、`dbsize`、`flushall`、`get`、`incr`、`info`、`latency` 或 `slowlog`。  
**db** 维度的值可以从 `db0` 到 `db15`。

您还可以为 Redis OSS Prometheus 指标创建 CloudWatch 控制面板。

**为 Redis OSS Prometheus 指标创建控制面板**

1. 创建环境变量，替换以下值以匹配部署。

   ```
   DASHBOARD_NAME=your_cw_dashboard_name
   REGION_NAME=your_metric_region_such_as_us-east-1
   CLUSTER_NAME=your_k8s_cluster_name_here
   NAMESPACE=your_redis_service_namespace_here
   ```

1. 输入以下命令以创建控制面板。

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_cloudwatch_dashboards/redis/cw_dashboard_redis.json \
   | sed "s/{{YOUR_AWS_REGION}}/${REGION_NAME}/g" \
   | sed "s/{{YOUR_CLUSTER_NAME}}/${CLUSTER_NAME}/g" \
   | sed "s/{{YOUR_NAMESPACE}}/${NAMESPACE}/g" \
   ```