

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon Managed Grafana 监控 Amazon EKS 基础设施的解决方案
<a name="solution-eks"></a>

监控 Amazon Elastic Kubernetes Service 基础设施是使用 Amazon Managed Grafana 的最常见场景之一。本页介绍的模板为您提供适用于此场景的解决方案。该解决方案可以使用 [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) 进行安装或与 [Terraform](https://www.terraform.io/) 一起安装。

此解决方案配置：
+ 您的 Amazon Managed Service for Prometheus 工作区，用于存储 Amazon EKS 集群中的指标，并创建一个托管收集器来收集指标并将指标推送到该工作区。有关更多信息，请参阅[使用 AWS 托管收集器提取指标](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-collector.html)。
+ 使用 CloudWatch 代理从您的 Amazon EKS 集群收集日志。日志存储在 Amazon Managed Grafana 中 CloudWatch，并由亚马逊托管 Grafana 查询。有关详细信息，请参阅 [Amazon EKS 日志记录](https://docs.aws.amazon.com/prescriptive-guidance/latest/implementing-logging-monitoring-cloudwatch/kubernetes-eks-logging.html)。
+ 您的 Amazon Managed Grafana 工作区用于摄取这些日志和指标，并创建控制面板和警报以帮助您监控集群。

应用此解决方案将创建控制面板和警报，以便：
+ 评估 Amazon EKS 集群的整体运行状况。
+ 显示 Amazon EKS 控制面板的运行状况和性能。
+ 显示 Amazon EKS 数据面板的运行状况和性能。
+ 显示有关 Kubernetes 命名空间中的 Amazon EKS 工作负载的见解。
+ 显示命名空间中的资源使用情况，包括 CPU、内存、磁盘和网络使用情况。

## 关于此解决方案
<a name="solution-eks-about"></a>

此解决方案配置 Amazon Managed Grafana 工作区，以为您的 Amazon EKS 集群提供指标。这些指标用于生成控制面板和警报。

这些指标通过提供对 Kubernetes 控制面板和数据面板的运行状况和性能的见解，帮助您更有效地运营 Amazon EKS 集群。您可以了解从节点级别到容器组再到 Kubernetes 级别的 Amazon EKS 集群，包括对资源使用情况的详细监控。

该解决方案提供预测和纠正能力：
+ **预测**能力包括：
  + 通过推动日程安排决策来管理资源效率。例如，要向 Amazon EKS 集群的内部用户提供性能和可靠性 SLA，您可以根据跟踪历史使用情况为其工作负载分配足够的 CPU 和内存资源。
  + 使用情况预测：根据您的 Amazon EKS 集群资源（例如节点、[Amazon EBS 支持的持久卷](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html)或[应用程序负载均衡器](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)）的当前利用率，您可以提前计划具有类似需求的新产品或项目。
  + 尽早发现潜在问题：例如，通过分析 Kubernetes 命名空间级别的资源消耗趋势，您可以了解工作负载使用情况随时间变化的趋势。
+ **纠正**能力包括：
  + 缩短基础设施和 Kubernetes 工作负载级别的问题的平均检测时间（MTTD）。例如，通过查看故障排除控制面板，您可以快速检验有关出错原因的假设并消除这些假设。
  + 确定问题在堆栈中的哪个位置出现。例如，Amazon EKS 控制平面完全由 AWS 管理，如果 API 服务器过载或连接受到影响，某些操作（例如更新 Kubernetes 部署）可能会失败。

下图显示了解决方案的控制面板文件夹示例。

![该图显示了使用此解决方案构建的 Grafana 控制面板文件夹的示例。](http://docs.aws.amazon.com/zh_cn/grafana/latest/userguide/images/eks-solution-dashboard-folder.png)


您可以选择控制面板以查看更多详细信息，例如，选择查看工作负载的计算资源将显示一个控制面板，如下图所示。

![该图显示了使用此解决方案构建的 Grafana 控制面板的示例，其中显示了 CPU 使用情况。](http://docs.aws.amazon.com/zh_cn/grafana/latest/userguide/images/eks-solution-dashboard-resource-usage.png)


这些指标以 1 分钟的抓取间隔进行抓取。控制面板根据特定指标显示聚合到 1 分钟、5 分钟或更长时间的指标。

日志也显示在控制面板中，因此您可以查询和分析日志，找出问题的根本原因。下图显示了日志控制面板。

![该图显示了使用此解决方案构建的带有日志的 Grafana 控制面板示例。](http://docs.aws.amazon.com/zh_cn/grafana/latest/userguide/images/eks-solution-dashboard-logs.png)


有关此解决方案跟踪的指标的列表，请参阅 [跟踪的指标的列表](#solution-eks-metrics)。

有关此解决方案创建的警报的列表，请参阅 [创建的警报列表](#solution-eks-alerts)。

## 成本
<a name="solution-eks-costs"></a>

此解决方案在您的工作区中创建和使用资源。您需要为创建的资源的标准使用量付费，包括：
+ 用户的 Amazon Managed Grafana 工作区访问权限。有关定价的更多信息，请参阅 [Amazon Managed Grafana 定价](https://aws.amazon.com/grafana/pricing/)。
+ Amazon Managed Service for Prometheus 指标摄取和存储，包括 Amazon Managed Service for Prometheus 的使用和指标分析（查询样本处理）。此解决方案使用的指标数量取决于 Amazon EKS 集群的配置和使用情况。

  *您可以使用在 Prometheus 的亚马逊托管服务中查看摄取和存储指标。有关更多信息，请参阅适用于 Prometheus CloudWatch 的亚马逊托管服务用户[CloudWatch指南中的](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-CW-usage-metrics.html)指标。*

  您可以使用 [Amazon Managed Service for Prometheus 定价](https://aws.amazon.com/prometheus/pricing/)页面上的定价计算器估算成本。指标的数量将取决于集群中的节点数量以及您的应用程序生成的指标。
+ CloudWatch 日志摄取、存储和分析。默认情况下，日志保留期设置为永不过期。你可以在中对此进行调整 CloudWatch。有关定价的更多信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。
+ 联网成本。跨可用区、区域或其他流量可能会产生标准 AWS 网络费用。

每种产品的定价页面上都有定价计算器，可以帮助您了解解决方案的潜在成本。以下信息可以帮助获取与 Amazon EKS 集群在同一个可用区中运行的解决方案的基本成本。


| 产品 | 计算器指标 | 值 | 
| --- | --- | --- | 
| Amazon Managed Service for Prometheus | 活跃序列 | 8000（基本）<br />15000（每个节点） | 
|  | 平均收集间隔 | 60（秒） | 
| Amazon Managed Service for Prometheus（托管收集器） | 收集器数量 | 1 | 
|  | 样本数量 | 15（基本）<br />150（每个节点） | 
|  | 规则数量 | 161 | 
|  | 平均规则提取间隔 | 60（秒） | 
| Amazon Managed Grafana | 活跃人数 editors/administrators | 1（或更多，视您的用户而定） | 
| CloudWatch （日志） | 标准日志：已摄取的数据 | 24.5GB（基本）<br />0.5GB（每个节点） | 
|  | 日志 Storage/Archival （标准日志和销售日志） | 请存储日志：假设保留期为 1 个月 | 
|  | 已扫描的预期日志数据 | 来自 Grafana 的每个日志见解查询都将扫描指定时间段内该组中的所有日志内容。 | 

这些数字是在没有其他软件的情况下运行 EKS 的解决方案的基数。这些数字将为您提供基本成本的估算。它还省略了网络使用成本，具体取决于亚马逊托管Grafana工作空间、适用于Prometheus的亚马逊托管服务工作空间和Amazon EKS集群是否位于同一可用区以及VPN。 AWS 区域

**注意**  
如果此表中的项目包含 `(base)` 值和每个资源（例如，`(per node)`）的一个值，则应将每个资源值乘以拥有的该资源的数量，再与基值相加。例如，对于**平均活动时间序列**，请输入一个数字 `8000 + the number of nodes in your cluster * 15,000`。如果您有 2 个节点，则需要输入 `38,000`，也就是 `8000 + ( 2 * 15,000 )`。

## 先决条件
<a name="solution-eks-prerequisites"></a>

此解决方案要求您在使用该解决方案之前完成以下操作。

1. 您必须拥有或**创建要监控的 Amazon Elastic Kubernetes Service 集群**，并且该集群必须至少有一个节点。集群必须将 API 服务器端点访问权限设置为包括私有访问权限（它也可以允许公共访问）。

   [身份验证模式](https://docs.aws.amazon.com/eks/latest/userguide/grant-k8s-access.html#set-cam)必须包括 API 访问权限（可以将其设置为 `API` 或 `API_AND_CONFIG_MAP`）。这允许解决方案部署使用访问权限条目。

   应在集群中安装以下内容（通过控制台创建集群时默认为真，但如果您使用 AWS API 或创建集群，则必须添加 AWS CLI）： AWS CNI、CoreDNS 和。 Kube-proxy AddOns

   *保存集群名称以便稍后指定*。可以在 Amazon EKS 控制台上的集群详细信息中找到该名称。
**注意**  
有关如何创建 Amazon EKS 集群的详细信息，请参阅 [Amazon EKS 入门](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)。

1. 您必须**在 Amazon EKS 集群中创建适用于 Prometheus 的亚马逊托管服务**工作空间。 AWS 账户 有关详细信息，请参阅《Amazon Managed Service for Prometheus 用户指南》**中的[创建工作区](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-create-workspace.html)。

   *保存 Amazon Managed Service for Prometheus 工作区 ARN，以便稍后指定。*

1. 您必须**使用 Grafana 版本 9 或更高版本创建亚马逊托管 Grafana 工作空间**，与您的亚马逊 EKS 集群相同。 AWS 区域 有关创建新工作区的详细信息，请参阅 [创建 Amazon Managed Grafana 工作区](AMG-create-workspace.md)。

   工作空间角色必须有权访问适用于 Prometheus 的亚马逊托管服务和亚马逊 API。 CloudWatch 最简单的方法是使用[Service-managed权限](AMG-manage-permissions.md)并选择 Prometheus 和 Amazon 托管服务。 CloudWatch您也可以手动将[AmazonPrometheusQueryAccess](https://docs.aws.amazon.com/prometheus/latest/userguide/security-iam-awsmanpol.html#AmazonPrometheusQueryAccess)和[AmazonGrafanaCloudWatchAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonGrafanaCloudWatchAccess)策略添加到您的工作空间 IAM 角色中。

   *保存 Amazon Managed Grafana 工作区 ID 和端点，以便日后指定。*ID 的格式为 `g-123example`。ID 和端点可在 Amazon Managed Grafana 控制台中找到。端点是工作区的 URL，包括 ID。例如 `https://g-123example.grafana-workspace.<region>.amazonaws.com/`。

1. 如果您使用 Terraform 部署解决方案，则必须创建一个可从您的账户访问的 **Amazon S3 存储桶**。这将用于存储部署的 Terraform 状态文件。

   *保存 Amazon S3 存储桶 ID 以备日后指定。*

1. 要查看 Amazon Managed Service for Prometheus 警报规则，您必须为 Amazon Managed Grafana 工作区启用 [Grafana Alerting](v10-alerting-use-grafana-alerts.md)。

   另外，Amazon Managed Grafana 必须具有以下权限才能访问您的 Prometheus 资源。您必须将其添加到 [亚马逊托管 Grafana 数据源的权限和政策 AWS](AMG-manage-permissions.md) 中所述的服务管理策略或客户管理策略中。
   + `aps:ListRules`
   + `aps:ListAlertManagerSilences`
   + `aps:ListAlertManagerAlerts`
   + `aps:GetAlertManagerStatus`
   + `aps:ListAlertManagerAlertGroups`
   + `aps:PutAlertManagerSilences`
   + `aps:DeleteAlertManagerSilence`

**注意**  
虽然不是严格要求设置解决方案，但您必须先在 Amazon Managed Grafana 工作区中设置用户身份验证，然后用户才能访问创建的控制面板。有关更多信息，请参阅 [在 Amazon Managed Grafana 工作区中对用户进行身份验证](authentication-in-AMG.md)。

## 使用此解决方案
<a name="solution-eks-use"></a>

此解决方案配置 AWS 基础设施以支持来自 Amazon EKS 集群的报告和监控指标。您可以使用 [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) 或通过 [Terraform](https://www.terraform.io/) 进行安装。

------
#### [ Using AWS CDK ]

向您提供此解决方案的一种方式是作为 AWS CDK 应用程序提供。您将提供有关要使用的资源的信息，解决方案将为您创建抓取程序、日志和控制面板。

**注意**  
此处的步骤假设您有一个安装了 AWS CLI、和、和 AWS CDK、[Node.js](https://nodeja.org/)和 [NPM](https://docs.npmjs.com/) 的环境。您将使用 `make` 和 `brew` 来简化构建和其他常见操作。

**使用此解决方案监控 Amazon EKS 集群 AWS CDK**

1. 请确保您已完成了所有[先决条件](#solution-eks-prerequisites)步骤。

1. 从 Amazon S3 中下载解决方案的所有文件。这些文件位于 `s3://aws-observability-solutions/EKS/OSS/CDK/v3.0.0/iac`，您可以使用以下 Amazon S3 命令下载它们。在命令行环境中的文件夹中运行此命令。

   ```
   aws s3 sync s3://aws-observability-solutions/EKS/OSS/CDK/v3.0.0/iac/ .
   ```

   您无需修改这些文件。

1. 在您的命令行环境中（从您下载解决方案文件的文件夹），运行以下命令。

   设置所需的环境变量。将{{REGION}}、{{AMG\_ENDPOINT}}{{EKS\_CLUSTER}}、和{{AMP\_ARN}}替换为您 AWS 区域的 Amazon Managed Grafana 工作空间终端节点（表格中`http://g-123example.grafana-workspace.us-east-1.amazonaws.com`）、亚马逊 EKS 集群名称和适用于 Prometheus 的亚马逊托管服务工作空间 ARN。

   ```
   export AWS_REGION={{REGION}}
   export AMG_ENDPOINT={{AMG_ENDPOINT}}
   export EKS_CLUSTER_NAME={{EKS_CLUSTER}}
   export AMP_WS_ARN={{AMP_ARN}}
   ```

1. 您必须创建具有管理员权限的服务账户令牌才能调用 Grafana HTTP API。有关更多信息，请参阅 [使用服务账号](v12-authenticating-grafana-apis.md#v12-service-accounts)。您可以通过以下命令使用来创建令牌。 AWS CLI 您需要将 Grafana 工作区的 ID 替换为 Grafana 工作区的 ID（它将在表单中）。{{GRAFANA\_ID}} `g-123example`此密钥将在 7200 秒或 2 小时后过期。如果需要，可以更改时间（`seconds-to-live`）。部署需要不到一小时的时间。

   ```
   GRAFANA_SA_ID=$(aws grafana create-workspace-service-account \
     --workspace-id {{GRAFANA_ID}} \
     --grafana-role ADMIN \
     --name grafana-operator-key \
     --query 'id' \
     --output text)
     
   # creates a new token for calling APIs
   export AMG_API_KEY=$(aws grafana create-workspace-service-account-token \
     --workspace-id $managed_grafana_workspace_id \
     --name "grafana-operator-key-$(date +%s)" \
     --seconds-to-live 7200 \
     --service-account-id $GRAFANA_SA_ID \
     --query 'serviceAccountToken.key' \
     --output text)
   ```

   使用以下命令将 API 密钥添加到 AWS Systems Manager ，使其可用。 AWS CDK {{AWS\_REGION}}替换为您的解决方案将要运行的区域（在表单中`us-east-1`）。

   ```
   aws ssm put-parameter --name "/observability-aws-solution-eks-infra/grafana-api-key" \
       --type "SecureString" \
       --value $AMG_API_KEY \
       --region {{AWS_REGION}} \
       --overwrite
   ```

1. 运行以下 `make` 命令，这将为项目安装任何其他依赖项。

   ```
   make deps
   ```

1. 最后，运行该 AWS CDK 项目：

   ```
   make build && make pattern aws-observability-solution-eks-infra-$EKS_CLUSTER_NAME deploy
   ```

1. [可选] 堆栈创建完成后，您可以使用相同的环境为同一区域的其他 Amazon EKS 集群创建更多堆栈实例，前提是您完成每个集群的其他先决条件（包括单独的 Amazon Managed Grafana 和 Amazon Managed Service for Prometheus 工作区）。您将需要使用新参数重新定义 `export` 命令。

堆栈创建完成后，您的 Amazon Managed Grafana 工作区中将填充一个控制面板，显示您的 Amazon EKS 集群的指标。当抓取程序开始收集指标时，需要几分钟才能显示指标。

------
#### [ Using Terraform ]

向您提供此解决方案的一种方法是作为 Terraform 解决方案提供。您将提供有关要使用的资源的信息，解决方案将为您创建抓取程序、日志和控制面板。

**要使用此解决方案通过 Terraform 监控 Amazon EKS 集群**

1. 请确保您已完成了所有[先决条件](#solution-eks-prerequisites)步骤。

1. 从 Amazon S3 中下载解决方案的所有文件。这些文件位于 `s3://aws-observability-solutions/EKS/OSS/Terraform/v3.0.0/`，您可以使用以下 Amazon S3 命令下载它们。在命令行环境中的某个文件夹中运行此命令，然后将目录更改为要从中进行部署的文件夹。

   ```
   aws s3 sync s3://aws-observability-solutions/EKS/OSS/Terraform/v3.0.0/ .
   cd eks-monitoring
   ```

   您无需修改这些文件。

1. 在您的命令行环境中（从您下载解决方案文件的文件夹），运行以下命令。

   设置所需的环境变量。将{{REGION}}、、{{AMG\_ENDPOINT}}{{EKS\_CLUSTER}}{{AMP\_ARN}}、和替换为您想要部署新资源 AWS 区域 的位置（例如）{{S3\_ID}}、亚马逊托管 Grafana 工作空间终端节点（表单中`us-east-1`）、Amazon EKS 集群名称、适用于 Prometheus 的亚马逊托管服务工作空间 ARN 和 Amazon S3 存储桶 ID。`http://g-123example.grafana-workspace.us-east-1.amazonaws.com`

   ```
   export TF_VAR_aws_region={{REGION}}
   export TF_VAR_amg_endpoint={{AMG_ENDPOINT}}
   export TF_VAR_eks_cluster_name={{EKS_CLUSTER}}
   export TF_VAR_amp_ws_arn={{AMP_ARN}}
   export TF_VAR_s3_bucket_id={{S3_ID}}
   ```

1. 您必须创建具有管理员权限的服务账户令牌才能调用 Grafana HTTP API。有关更多信息，请参阅 [使用服务账号](v12-authenticating-grafana-apis.md#v12-service-accounts)。您可以通过以下命令使用来创建令牌。 AWS CLI 您需要将 Grafana 工作区的 ID 替换为 Grafana 工作区的 ID（它将在表单中）。{{GRAFANA\_ID}} `g-123example`此密钥将在 7200 秒或 2 小时后过期。如果需要，可以更改时间（`seconds-to-live`）。部署需要不到一小时的时间。

   ```
   GRAFANA_SA_ID=$(aws grafana create-workspace-service-account \
     --workspace-id {{GRAFANA_ID}} \
     --grafana-role ADMIN \
     --name grafana-operator-key \
     --query 'id' \
     --output text)
     
   # creates a new token for running Terraform
   export TF_VAR_grafana_api_key=$(aws grafana create-workspace-service-account-token \
     --workspace-id $managed_grafana_workspace_id \
     --name "grafana-operator-key-$(date +%s)" \
     --seconds-to-live 7200 \
     --service-account-id $GRAFANA_SA_ID \
     --query 'serviceAccountToken.key' \
     --output text)
   ```
**注意**  
如果您已经拥有服务账户，则不需要第一步操作，即无需为工作区创建服务账户。在这种情况下，请将{{$GRAFANA\_SA\_ID}}替换为您的服务帐号的 ID。

1. 运行以下 `terraform` 命令以使用解决方案初始化 Terraform。

   ```
   terraform init -reconfigure \
   -backend-config="bucket=${TF_VAR_s3_bucket_id}" \
   -backend-config="region=${TF_VAR_aws_region}" \
   -backend-config="key=state/${TF_VAR_eks_cluster_name}/terraform.tfstate"
   ```

1. 最后，部署 Terraform 项目：

   ```
   terraform apply
   ```

解决方案创建完成后，您的 Amazon Managed Grafana 工作区中将填充一个控制面板，显示您的 Amazon EKS 集群的指标。当抓取程序开始收集指标时，需要几分钟才能显示指标。

------

## 跟踪的指标的列表
<a name="solution-eks-metrics"></a>

此解决方案将创建一个抓取程序，用于收集您的 Amazon EKS 集群中的指标。这些指标存储在 Amazon Managed Service for Prometheus 中，然后显示在 Amazon Managed Grafana 控制面板中。默认情况下，抓取器会收集集群公开的所有[Prometheus-compatible 指标](https://docs.aws.amazon.com/prometheus/latest/userguide/prom-compatible-metrics.html)。在集群中安装生成更多指标的软件将增加收集到的指标数量。如果您愿意，您可以通过[使用筛选指标的配置更新抓取程序](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-collector-how-to.html#AMP-collector-configuration)来减少指标的数量。

可通过此解决方案在基本 Amazon EKS 集群中跟踪以下指标，而无需安装任何其他软件。


| 指标 | 描述/用途 | 
| --- | --- | 
| `aggregator_unavailable_apiservice` | 标记为不可用的 APIService 的计量表标准，按照 APIService 名称细分。 | 
| `apiserver_admission_webhook_admission_duration_seconds_bucket` | 准入 Webhook 延迟直方图（以秒为单位），按名称标识，并按每个操作以及 API 资源和类型（验证或准入）进行细分。 | 
| `apiserver_current_inflight_requests` | 最后一秒钟内，对于每种请求类型，此 apiserver 当前使用的传输中请求数量上限。 | 
| `apiserver_envelope_encryption_dek_cache_fill_percent` | 缓存 DEK 当前占用的缓存插槽百分比。 | 
| `apiserver_flowcontrol_current_executing_requests` | 在 API 优先级和公平性子系统中，处于初始（对于监视）或任何（对于非监视）执行阶段的请求数。 | 
| `apiserver_flowcontrol_rejected_requests_total` | 在 API 优先级和公平性子系统中，处于初始（对于监视）或任何（对于非监视）执行阶段的被拒绝的请求数。 | 
| `apiserver_flowcontrol_request_concurrency_limit` | 为每个优先级配置的执行席位的标称数量。 | 
| `apiserver_flowcontrol_request_execution_seconds_bucket` | 在 API 优先级和公平性子系统中，处于请求执行的初始阶段（对于监视）或任何（对于非监视）阶段的持续时间分桶直方图。 | 
| `apiserver_flowcontrol_request_queue_length_after_enqueue_count` | 在 API 优先级和公平性子系统中，处于请求执行的初始阶段（对于监视）或任何（对于非监视）阶段的计数。 | 
| `apiserver_request` | 表示 API 服务器请求。 | 
| `apiserver_requested_deprecated_apis` | 已请求的弃用 API 计量表，按 API 组、版本、资源、子资源和 removed\_release 细分。 | 
| `apiserver_request_duration_seconds` | 每个动词、试运行值、组、版本、资源、子资源、范围和组件的响应延迟分布（以秒为单位）。 | 
| `apiserver_request_duration_seconds_bucket` | 每个动词、试运行值、组、版本、资源、子资源、范围和组件的响应延迟分布分桶直方图（以秒为单位）。 | 
| `apiserver_request_slo_duration_seconds` | 每个动词、试运行值、组、版本、资源、子资源、范围和组件的服务级别目标（SLO）响应延迟分布（以秒为单位）。 | 
| `apiserver_request_terminations_total` | apiserver 出于自我防御而终止的请求数。 | 
| `apiserver_request_total` | 对于每个动词、试运行值、组、版本、资源、范围、组件和 HTTP 响应代码划分的 apiserver 请求的计数器。 | 
| `container_cpu_usage_seconds_total` | 累计 cpu 消耗时间。 | 
| `container_fs_reads_bytes_total` | 累计已读取字节数。 | 
| `container_fs_reads_total` | 累计已完成读取计数。 | 
| `container_fs_writes_bytes_total` | 累计写入的字节计数。 | 
| `container_fs_writes_total` | 累计完成的写入计数。 | 
| `container_memory_cache` | 页面缓存总内存。 | 
| `container_memory_rss` | RSS 的大小。 | 
| `container_memory_swap` | 容器交换使用情况。 | 
| `container_memory_working_set_bytes` | 当前工作集。 | 
| `container_network_receive_bytes_total` | 累计接收的字节计数。 | 
| `container_network_receive_packets_dropped_total` | 接收时累计丢弃的数据包计数。 | 
| `container_network_receive_packets_total` | 累计收到的数据包计数。 | 
| `container_network_transmit_bytes_total` | 累计传输的字节数。 | 
| `container_network_transmit_packets_dropped_total` | 传输时累计丢弃的数据包计数。 | 
| `container_network_transmit_packets_total` | 累计传输的数据包的计数。 | 
| `etcd_request_duration_seconds_bucket` | 每种操作和对象类型的 etcd 请求延迟（以秒为单位）的分桶直方图。 | 
| `go_goroutines` | 当前存在的 goroutine 数量。 | 
| `go_threads` | 已创建的操作系统线程数。 | 
| `kubelet_cgroup_manager_duration_seconds_bucket` | cgroup 管理器操作的持续时间（以秒为单位）的分桶直方图。按方法细分。 | 
| `kubelet_cgroup_manager_duration_seconds_count` | cgroup 管理器操作的持续时间（以秒为单位）。按方法细分。 | 
| `kubelet_node_config_error` | 如果节点遇到与配置相关的错误，则此指标为 true（1），否则为 false（0）。 | 
| `kubelet_node_name` | 节点的名称。计数始终为 1。 | 
| `kubelet_pleg_relist_duration_seconds_bucket` | 在 PLEG 中重新列出容器组的持续时间（以秒为单位）的分桶直方图。 | 
| `kubelet_pleg_relist_duration_seconds_count` | 在 PLEG 中重新列出容器组的持续时间计数（以秒为单位）。 | 
| `kubelet_pleg_relist_interval_seconds_bucket` | PLEG 中重新列出操作之间间隔（以秒为单位）的分桶直方图。 | 
| `kubelet_pod_start_duration_seconds_count` | 从 kubelet 第一次看到容器组（pod）到容器组（pod）开始运行的持续时间计数（以秒为单位）。 | 
| `kubelet_pod_worker_duration_seconds_bucket` | 同步单个容器组（pod）的持续时间（以秒为单位）的分桶直方图。按操作类型细分：创建、更新或同步。 | 
| `kubelet_pod_worker_duration_seconds_count` | 同步单个容器组（pod）的持续时间计数（以秒为单位）。按操作类型细分：创建、更新或同步。 | 
| `kubelet_running_containers` | 当前运行的容器数量。 | 
| `kubelet_running_pods` | 有正在运行的容器组（pod）沙盒的容器组（pod）数量。 | 
| `kubelet_runtime_operations_duration_seconds_bucket` | 运行时操作的持续时间（以秒为单位）的分桶直方图。按操作类型细分。 | 
| `kubelet_runtime_operations_errors_total` | 累积运行时操作错误数（按操作类型细分）。 | 
| `kubelet_runtime_operations_total` | 累积运行时操作数（按操作类型细分）。 | 
| `kube_node_status_allocatable` | 可为容器组（pod）分配的资源量（在为系统进程守护程序保留部分资源之后）。 | 
| `kube_node_status_capacity` | 节点可用的资源总量。 | 
| `kube_pod_container_resource_limits (CPU)` | 容器请求的限制资源数量。 | 
| `kube_pod_container_resource_limits (Memory)` | 容器请求的限制资源数量。 | 
| `kube_pod_container_resource_requests (CPU)` | 容器请求的请求资源数量。 | 
| `kube_pod_container_resource_requests (Memory)` | 容器请求的请求资源数量。 | 
| `kube_pod_owner` | 有关容器组（pod）所有者的信息。 | 
| `kube_resourcequota` | Kubernetes 中的资源配额对命名空间中的 CPU、内存和存储等资源强制实施使用限制。 | 
| `node_cpu` | 节点的 CPU 使用率指标，包括每个核心的使用率和总使用率。 | 
| `node_cpu_seconds_total` | CPU 在每种模式下花费的秒数。 | 
| `node_disk_io_time_seconds` | 节点在磁盘上执行 I/O 操作所花费的累积时间。 | 
| `node_disk_io_time_seconds_total` | 节点在磁盘上执行 I/O 操作所花费的总时间。 | 
| `node_disk_read_bytes_total` | 节点从磁盘中读取的总字节数。 | 
| `node_disk_written_bytes_total` | 节点写入到磁盘的总字节数。 | 
| `node_filesystem_avail_bytes` | Kubernetes 集群中节点文件系统上的可用空间量（以字节为单位）。 | 
| `node_filesystem_size_bytes` | 节点上文件系统的总大小。 | 
| `node_load1` | 节点 CPU 使用率的 1 分钟平均负载。 | 
| `node_load15` | 节点 CPU 使用率的 15 分钟平均负载。 | 
| `node_load5` | 节点 CPU 使用率的 5 分钟平均负载。 | 
| `node_memory_Buffers_bytes` | 节点操作系统用于缓冲区缓存的内存量。 | 
| `node_memory_Cached_bytes,` | 节点操作系统用于磁盘缓存的内存量。 | 
| `node_memory_MemAvailable_bytes` | 可供应用程序和缓存使用的内存量。 | 
| `node_memory_MemFree_bytes` | 节点上可用的空闲内存量。 | 
| `node_memory_MemTotal_bytes` | 节点上可用的物理内存总量。 | 
| `node_network_receive_bytes_total` | 节点通过网络接收的总字节数。 | 
| `node_network_transmit_bytes_total` | 节点通过网络传输的总字节数。 | 
| `process_cpu_seconds_total` | 用户和系统 CPU 花费的总时间（以秒为单位）。 | 
| `process_resident_memory_bytes` | 常驻内存大小（以字节为单位）。 | 
| `rest_client_requests_total` | HTTP 请求数，按状态码、方法和主机分区。 | 
| `rest_client_request_duration_seconds_bucket` | 请求延迟（以秒为单位）的分桶直方图。按动词和主机细分。 | 
| `storage_operation_duration_seconds_bucket` | 存储操作持续时间的分桶直方图。 | 
| `storage_operation_duration_seconds_count` | 存储操作的持续时间计数。 | 
| `storage_operation_errors_total` | 存储操作期间的累计错误数。 | 
| `up` | 用于指示受监控目标（例如节点）是否已启动并正在运行的指标。 | 
| `volume_manager_total_volumes` | 卷管理器管理的卷总数。 | 
| `workqueue_adds_total` | 工作队列处理的添加总数。 | 
| `workqueue_depth` | 当前工作队列的深度。 | 
| `workqueue_queue_duration_seconds_bucket` | 分桶直方图，显示项目在被请求之前在工作队列中停留的时长（以秒为单位）。 | 
| `workqueue_work_duration_seconds_bucket` | 分桶直方图，显示处理工作队列中的项目所需的时长（以秒为单位）。 | 

## 创建的警报列表
<a name="solution-eks-alerts"></a>

下表列出了此解决方案创建的警报。警报在 Amazon Managed Service for Prometheus 中创建为规则，并显示在您的 Amazon Managed Grafana 工作区中。

您可以通过在 Amazon Managed Service for Prometheus 工作区中[编辑规则配置文件](https://docs.aws.amazon.com/prometheus/latest/userguide/AMP-rules-edit.html)来修改规则，包括添加或删除规则。

这两个警报是特殊警报，其处理方式与典型警报略有不同。他们不会提醒您注意问题，而是向您提供用于监控系统的信息。说明包括有关如何使用这些警报的详细信息。


| 警报 | 描述和使用情况 | 
| --- | --- | 
| `Watchdog` | 此警报旨在确保整个警报管道正常运行。此警报始终会触发，因此它应该始终在 Alertmanager 中触发并始终针对接收器触发。您可以将其与通知机制集成，以便在此警报*未*触发时发送通知。例如，您可以在中使用集**DeadMansSnitch**成 PagerDuty。 | 
| `InfoInhibitor` | 这是一种用于抑制信息警报的警报。信息级别的警报本身可能非常嘈杂，但是当与其他警报结合使用时，它们会具有相关性。每当出现 `severity=info` 警报时，就会触发此警报，当另一个严重性为 `warning` 或 `critical` 的警报开始在同一命名空间上触发时，该警报就会停止触发。此警报应路由到空接收器，并配置为抑制严重性为 `severity=info` 的警报。 | 

以下警报为您提供有关您的系统的信息或警告。


| 警报 | 严重性 | 说明 | 
| --- | --- | --- | 
| `NodeNetworkInterfaceFlapping` | warning | 网络接口经常更改其状态 | 
| `NodeFilesystemSpaceFillingUp` | warning | 预计在接下来的 24 小时内文件系统空间将耗尽。 | 
| `NodeFilesystemSpaceFillingUp` | critical | 预计在接下来的 4 小时内文件系统空间将耗尽。 | 
| `NodeFilesystemAlmostOutOfSpace` | warning | 文件系统的剩余空间不到 5%。 | 
| `NodeFilesystemAlmostOutOfSpace` | critical | 文件系统的剩余空间不到 3%。 | 
| `NodeFilesystemFilesFillingUp` | warning | 预计在接下来的 24 小时内文件系统 inode 将耗尽。 | 
| `NodeFilesystemFilesFillingUp` | critical | 预计在接下来的 4 小时内文件系统 inode 将耗尽。 | 
| `NodeFilesystemAlmostOutOfFiles` | warning | 文件系统剩余的 inode 不到 5%。 | 
| `NodeFilesystemAlmostOutOfFiles` | critical | 文件系统剩余的 inode 不到 3%。 | 
| `NodeNetworkReceiveErrs` | warning | 网络接口报告了许多接收错误。 | 
| `NodeNetworkTransmitErrs` | warning | 网络接口报告了许多传输错误。 | 
| `NodeHighNumberConntrackEntriesUsed` | warning | conntrack 的条目数量已接近上限。 | 
| `NodeTextFileCollectorScrapeError` | warning | Node Exporter 文本文件收集器无法抓取。 | 
| `NodeClockSkewDetected` | warning | 检测到时钟偏差。 | 
| `NodeClockNotSynchronizzing` | warning | 时钟未同步。 | 
| `NodeRAIDDegraded` | critical | RAID 阵列已降级 | 
| `NodeRAIDDiskFailure` | warning | RAID 阵列中的设备出现故障 | 
| `NodeFileDescriptorLimit` | warning | 预计内核很快就会耗尽文件描述符的限制。 | 
| `NodeFileDescriptorLimit` | critical | 预计内核很快就会耗尽文件描述符的限制。 | 
| `KubeNodeNotReady` | warning | 节点未准备就绪。 | 
| `KubeNodeUnreachable` | warning | 无法访问节点。 | 
| `KubeletTooManyPods` | info | Kubelet 正在满负荷运行。 | 
| `KubeNodeReadinessFlapping` | warning | 节点就绪状态存在抖动。 | 
| `KubeletPlegDurationHigh` | warning | Kubelet 容器组（pod）生命周期事件生成器重新上架时间过长。 | 
| `KubeletPodStartUpLatencyHigh` | warning | Kubelet 容器组（pod）的启动延迟太高。 | 
| `KubeletClientCertificateExpiration` | warning | Kubelet 客户端证书即将过期。 | 
| `KubeletClientCertificateExpiration` | critical | Kubelet 客户端证书即将过期。 | 
| `KubeletServerCertificateExpiration` | warning | Kubelet 服务器证书即将过期。 | 
| `KubeletServerCertificateExpiration` | critical | Kubelet 服务器证书即将过期。 | 
| `KubeletClientCertificateRenewalErrors` | warning | Kubelet 未能续订其客户端证书。 | 
| `KubeletServerCertificateRenewalErrors` | warning | Kubelet 未能续订其服务器证书。 | 
| `KubeletDown` | critical | 目标从 Prometheus 的目标发现中消失。 | 
| `KubeVersionMismatch` | warning | Kubernetes 组件的不同语义版本正在运行。 | 
| `KubeClientErrors` | warning | Kubernetes API 服务器客户端遇到错误。 | 
| `KubeClientCertificateExpiration` | warning | 客户端证书即将过期。 | 
| `KubeClientCertificateExpiration` | critical | 客户端证书即将过期。 | 
| `KubeAggregatedAPIErrors` | warning | Kubernetes 聚合 API 报告了错误。 | 
| `KubeAggregatedAPIDown` | warning | Kubernetes 聚合 API 已关闭。 | 
| `KubeAPIDown` | critical | 目标从 Prometheus 的目标发现中消失。 | 
| `KubeAPITerminatedRequests` | warning | Kubernetes apiserver 已终止其传入请求的 {{ $value \| humanizePercentage }}。 | 
| `KubePersistentVolumeFillingUp` | critical | 持久卷已满。 | 
| `KubePersistentVolumeFillingUp` | warning | 持久卷已满。 | 
| `KubePersistentVolumeInodesFillingUp` | critical | 持久卷 Inode 已满。 | 
| `KubePersistentVolumeInodesFillingUp` | warning | 持久卷 Inode 已满。 | 
| `KubePersistentVolumeErrors` | critical | 持久卷存在预置问题。 | 
| `KubeCPUOvercommit` | warning | 集群已超量提交了 CPU 资源请求。 | 
| `KubeMemoryOvercommit` | warning | 集群已超量提交了内存资源请求。 | 
| `KubeCPUQuotaOvercommit` | warning | 集群已超量提交了 CPU 资源请求。 | 
| `KubeMemoryQuotaOvercommit` | warning | 集群已超量提交了内存资源请求。 | 
| `KubeQuotaAlmostFull` | info | 命名空间配额将用完。 | 
| `KubeQuotaFullyUsed` | info | 命名空间配额已用完。 | 
| `KubeQuotaExceeded` | warning | 命名空间配额已超过限制。 | 
| `CPUThrottlingHigh` | info | 进程遇到 CPU 节流升高的情况。 | 
| `KubePodCrashLooping` | warning | 容器组（pod）正在崩溃循环。 | 
| `KubePodNotReady` | warning | 容器组（pod）处于未就绪状态的时间已超过 15 分钟。 | 
| `KubeDeploymentGenerationMismatch` | warning | 由于可能回滚，部署生成不匹配 | 
| `KubeDeploymentReplicasMismatch` | warning | 部署的副本数量与预期的副本数量不匹配。 | 
| `KubeStatefulSetReplicasMismatch` | warning | StatefulSet 与预期的副本数量不匹配。 | 
| `KubeStatefulSetGenerationMismatch` | warning | StatefulSet 由于可能回滚而导致世代不匹配 | 
| `KubeStatefulSetUpdateNotRolledOut` | warning | StatefulSet 更新尚未推出。 | 
| `KubeDaemonSetRolloutStuck` | warning | DaemonSet 推出卡住了。 | 
| `KubeContainerWaiting` | warning | 容器组（pod）容器等待时间超过 1 小时 | 
| `KubeDaemonSetNotScheduled` | warning | DaemonSet Pod 未被调度。 | 
| `KubeDaemonSetMisScheduled` | warning | DaemonSet Pod 调度错误。 | 
| `KubeJobNotCompleted` | warning | 作业未及时完成 | 
| `KubeJobFailed` | warning | 作业未能完成。 | 
| `KubeHpaReplicasMismatch` | warning | HPA 未匹配所需的副本数量。 | 
| `KubeHpaMaxedOut` | warning | HPA 正在以最大副本数运行 | 
| `KubeStateMetricsListErrors` | critical | kube-state-metrics 在列表操作中遇到错误。 | 
| `KubeStateMetricsWatchErrors` | critical | kube-state-metrics 在监视操作中遇到错误。 | 
| `KubeStateMetricsShardingMismatch` | critical | kube-state-metrics 分片配置错误。 | 
| `KubeStateMetricsShardsMissing` | critical | 缺少 kube-state-metrics 分片。 | 
| `KubeAPIErrorBudgetBurn` | critical | API 服务器消耗了太多的错误预算。 | 
| `KubeAPIErrorBudgetBurn` | critical | API 服务器消耗了太多的错误预算。 | 
| `KubeAPIErrorBudgetBurn` | warning | API 服务器消耗了太多的错误预算。 | 
| `KubeAPIErrorBudgetBurn` | warning | API 服务器消耗了太多的错误预算。 | 
| `TargetDown` | warning | 一个或多个目标已关闭。 | 
| `etcdInsufficientMembers` | critical | Etcd 集群的成员不足。 | 
| `etcdHighNumberOfLeaderChanges` | warning | Etcd 集群的领导者变动太多。 | 
| `etcdNoLeader` | critical | Etcd 集群没有领导者。 | 
| `etcdHighNumberOfFailedGRPCRequests` | warning | Etcd 集群的失败 gRPC 请求的数量太高。 | 
| `etcdGRPCRequestsSlow` | critical | Etcd 集群 gRPC 请求速度很慢。 | 
| `etcdMemberCommunicationSlow` | warning | Etcd 集群成员通信速度很慢。 | 
| `etcdHighNumberOfFailedProposals` | warning | Etcd 集群的失败提议的数量太高。 | 
| `etcdHighFsyncDurations` | warning | Etcd 集群的 fsync 持续时间太长。 | 
| `etcdHighCommitDurations` | warning | Etcd 集群的提交持续时间高于预期。 | 
| `etcdHighNumberOfFailedHTTPRequests` | warning | Etcd 集群有失败的 HTTP 请求。 | 
| `etcdHighNumberOfFailedHTTPRequests` | critical | Etcd 集群有大量失败的 HTTP 请求。 | 
| `etcdHTTPRequestsSlow` | warning | Etcd 集群 HTTP 请求很慢。 | 
| `HostClockNotSynchronizing` | warning | 主机时钟不同步。 | 
| `HostOomKillDetected` | warning | 检测到主机 OOM 终止。 | 

## 问题排查
<a name="solution-eks-troubleshooting"></a>

有几种情况可能会导致项目设置失败。务必检查以下内容：
+ 安装解决方案之前，必须完成所有[先决条件](#solution-eks-prerequisites)。
+ 在尝试创建解决方案或访问指标之前，集群中必须至少有一个节点。
+ 您的 Amazon EKS 集群必须已安装 `AWS CNI`、`CoreDNS` 和 `kube-proxy` 附加组件。如果未安装这些附加组件，则解决方案将无法正常运行。默认情况下，会在通过控制台创建集群时进行安装。如果集群是通过 AWS SDK 创建的，则可能需要安装它们。
+ Amazon EKS 容器组（pod）安装超时。如果没有足够的可用节点容量，就会发生这种情况。造成这些问题的原因有多种，包括：
  + Amazon EKS 集群是使用 Fargate 而不是 Amazon EC2 初始化的。此项目需要 Amazon EC2。
  + 节点已[被污染](https://docs.aws.amazon.com/eks/latest/userguide/node-taints-managed-node-groups.html)，因此不可用。

    您可以使用 `kubectl describe node {{NODENAME}} | grep Taints` 来检查污点。然后使用 `kubectl taint node {{NODENAME}} {{TAINT_NAME}}-` 来移除污点。请确保在污点名称后加上 `-`。
  + 节点已达到容量限制。在这种情况下，您可以创建新节点或增加容量。
+ 您在 Grafana 中看不到任何控制面板：使用了错误的 Grafana 工作区 ID。

  运行以下命令可获取有关 Grafana 的信息。

  ```
  kubectl describe grafanas external-grafana -n grafana-operator
  ```

  您可以检查结果以获取正确的工作区 URL。如果 URL 不是您期望的 URL，请使用正确的工作区 ID 重新部署。

  ```
  Spec:
    External:
      API Key:
        Key:   GF_SECURITY_ADMIN_APIKEY
        Name:  grafana-admin-credentials
      URL:     https://{{g-123example}}.grafana-workspace.{{aws-region}}.amazonaws.com
  Status:
    Admin URL:  https://{{g-123example}}.grafana-workspace.{{aws-region}}.amazonaws.com
    Dashboards:
      ...
  ```
+ 您在 Grafana 中看不到任何控制面板：您使用的 API 密钥已过期。

  要查找这种情况，您需要找到 Grafana 操作员并检查日志中是否有错误。使用以下命令获取 Grafana 操作员的姓名：

  ```
  kubectl get pods -n grafana-operator
  ```

  这将返回操作员姓名，例如：

  ```
  NAME                               READY   STATUS    RESTARTS   AGE
  {{grafana-operator-1234abcd5678ef90}}   1/1     Running   0          1h2m
  ```

  在以下命令中使用操作员名称：

  ```
  kubectl logs {{grafana-operator-1234abcd5678ef90}} -n grafana-operator
  ```

  下面的错误消息表明 API 密钥已过期：

  ```
  ERROR   error reconciling datasource    {"controller": "grafanadatasource", "controllerGroup": "grafana.integreatly.org", "controllerKind": "GrafanaDatasource", "GrafanaDatasource": {"name":"grafanadatasource-sample-amp","namespace":"grafana-operator"}, "namespace": "grafana-operator", "name": "grafanadatasource-sample-amp", "reconcileID": "72cfd60c-a255-44a1-bfbd-88b0cbc4f90c", "datasource": "grafanadatasource-sample-amp", "grafana": "external-grafana", "error": "status: 401, body: {\"message\":\"Expired API key\"}\n"}
  github.com/grafana-operator/grafana-operator/controllers.(*GrafanaDatasourceReconciler).Reconcile
  ```

  在这种情况下，请创建一个新的 API 密钥并重新部署解决方案。如果问题仍然存在，则可以在重新部署之前使用以下命令强制同步：

  ```
  kubectl delete externalsecret/external-secrets-sm -n grafana-operator
  ```
+ *CDK 安装*：缺少 SSM 参数。如果您看到类似于以下内容的错误，请运行 `cdk bootstrap` 并重试。

  ```
  Deployment failed: Error: aws-observability-solution-eks-infra-{{$EKS_CLUSTER_NAME}}: SSM 
  parameter /cdk-bootstrap/{{xxxxxxx}}/version not found. Has the environment been 
  bootstrapped? Please run 'cdk bootstrap' (see https://docs.aws.amazon.com/cdk/latest/
  guide/bootstrapping.html)
  ```
+ 如果 OIDC 提供商已经存在，则部署可能会失败。您将看到如下错误（在本例中为与 CDK 安装相关的错误）：

  ```
  | CREATE_FAILED | Custom::AWSCDKOpenIdConnectProvider | OIDCProvider/Resource/Default
  Received response status [FAILED] from custom resource. Message returned: 
  EntityAlreadyExistsException: Provider with url https://oidc.eks.{{REGION}}.amazonaws.com/id/{{PROVIDER ID}} already exists.
  ```

  在这种情况下，请转到 IAM 门户并删除 OIDC 提供商，然后重试。
+ *Terraform 已安装*：您会看到一条包含 `cluster-secretstore-sm failed to create kubernetes rest client for update of resource` 和 `failed to create kubernetes rest client for update of resource` 的错误消息。

  此错误通常表示您的 Kubernetes 集群中未安装或启用 External Secrets Operator。External Secrets Operator 是作为解决方案部署的一部分安装的，但有时在解决方案需要它时，它却没有准备就绪。

  使用以下命令验证是否已安装 External Secrets Operator：

  ```
  kubectl get deployments -n external-secrets
  ```

  如果已安装，则 External Secrets Operator 可能需要一段时间之后才能完全准备就绪以供使用。您可以运行以下命令，检查所需自定义资源定义（CRD）的状态：

  ```
  kubectl get crds|grep external-secrets
  ```

  此命令应列出与 External Secrets Operator 相关的 CRD，包括 `clustersecretstores.external-secrets.io` 和 `externalsecrets.external-secrets.io`。如果未列出所需 CRD，请等待几分钟，然后再次检查。

  注册 CRD 后，您可以再次运行 `terraform apply` 以部署解决方案。