

# 使用 Helm OTel Container Insights
<a name="container-insights-eks-otel-helm"></a>

Amazon CloudWatch 可观测性 Helm 图表为 OTel Container Insights 提供了灵活的部署选项。该图表安装了带有 OpenTelemetry 文件日志接收器（用于收集日志）的 CloudWatch 代理（基于 OTel）。Helm 图表在 [https://github.com/aws-observability/helm-charts](https://github.com/aws-observability/helm-charts) 中维护。

若需要以下一项或多项功能时，请使用 Helm 图表：
+ 对代理配置的精细控制
+ 使用文件日志接收器收集 OTEL 原生日志（没有 Fluent Bit 依赖项）
+ 通过 cert-manager 进行自定义 TLS 证书管理
+ 非 EKS Kubernetes 集群（ROSA，自主管理型 Kubernetes）
+ 使用 ArgoCD 或 Flux 的 GitOps 工作流程

## 先决条件
<a name="container-insights-eks-otel-helm-prereqs"></a>

使用 Helm 部署 OTel Container Insights 之前，请确认已满足以下要求。
+ 运行 Kubernetes 1.28 版本或更高版本的现有 Amazon EKS 集群
+ Helm 版本 3.9 或更高版本
+ 已配置 `kubectl` 以与目标集群通信
+ IAM 权限：附加到代理角色的 `CloudWatchAgentServerPolicy` 托管策略
+ 为服务账户的 IAM 角色（IRSA）配置的 OpenID Connect（OIDC）提供者
+ 从集群到 CloudWatch 端点的出站互联网访问

## 安装 Helm 图表
<a name="container-insights-eks-otel-helm-setup"></a>

完成以下步骤，使用 Helm 图表部署 OTel Container Insights。

### 步骤 1：添加 Helm 存储库
<a name="container-insights-eks-otel-helm-step1"></a>

将 Amazon 可观测性 Helm 图表存储库添加到本地 Helm 配置中。

**添加 Helm 存储库**

1. 运行以下命令以添加存储库。

   ```
   helm repo add aws-observability \
     https://aws-observability.github.io/helm-charts
   ```

1. 更新存储库以获取最新的图表版本。

   ```
   helm repo update
   ```

### 步骤 2：创建 IAM 角色
<a name="container-insights-eks-otel-helm-step2"></a>

创建一个 IAM 角色，让 CloudWatch 代理可以将数据发送到 CloudWatch。此角色使用 IRSA 将 IAM 权限与 Kubernetes 服务账户相关联。

**为 CloudWatch 代理创建 IAM 角色**

1. 检索集群的 OIDC 发布者 URL。将 {{cluster-name}} 替换为 Amazon EKS 集群的名称。

   ```
   aws eks describe-cluster \
     --name {{cluster-name}} \
     --query "cluster.identity.oidc.issuer" \
     --output text
   ```

1. 为 IRSA 创建带有信任策略的 IAM 角色。将 {{account-id}} 替换为 Amazon 账户 ID，并将 {{oidc-id}} 替换为上述步骤中的 OIDC 提供者 ID（`https://oidc.eks.region.amazonaws.com/id/` 之后的部分）。

   ```
   aws iam create-role \
     --role-name EKS-CW-Observability-Role \
     --assume-role-policy-document '{
       "Version": "2012-10-17",
       "Statement": [{
         "Effect": "Allow",
         "Principal": {
           "Federated": "arn:aws:iam::{{account-id}}:oidc-provider/oidc.eks.{{region}}.amazonaws.com/id/{{oidc-id}}"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "oidc.eks.{{region}}.amazonaws.com/id/{{oidc-id}}:sub": "system:serviceaccount:amazon-cloudwatch:cloudwatch-agent"
           }
         }
       }]
     }'
   ```

1. 将 `CloudWatchAgentServerPolicy` 托管式策略附加到角色。

   ```
   aws iam attach-role-policy \
     --role-name EKS-CW-Observability-Role \
     --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
   ```

### 步骤 3：安装图表
<a name="container-insights-eks-otel-helm-step3"></a>

安装启用了 OTel Container Insights 的 Amazon CloudWatch 可观测性 Helm 图表。

**安装 Helm 图表**
+ 运行如下命令。将 {{cluster-name}} 替换为 Amazon EKS 集群名称，将 {{region}} 替换为您的 Amazon 区域，并将 {{account-id}} 替换为您的 Amazon 账户 ID。

  ```
  helm install amazon-cloudwatch-observability \
    aws-observability/amazon-cloudwatch-observability \
    --namespace amazon-cloudwatch \
    --create-namespace \
    --set clusterName={{cluster-name}} \
    --set region={{region}} \
    --set agent.serviceAccount.name=cloudwatch-agent \
    --set "agent.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=arn:aws:iam::{{account-id}}:role/EKS-CW-Observability-Role" \
    --set otelContainerInsights.enabled=true
  ```
**重要**  
`otelContainerInsights.enabled` 参数是必需的。默认情况下，OTel Container Insights 未启用。

### 步骤 4：验证安装
<a name="container-insights-eks-otel-helm-step4"></a>

确认 Helm 版本和代理容器组（pod）已成功部署。

**验证 Helm 安装**

1. 确认 Helm 版本状态是否显示 `deployed`。

   ```
   helm list -n amazon-cloudwatch
   ```

1. 确认 Operator 容器组（pod）是否在运行。

   ```
   kubectl get pods -n amazon-cloudwatch -l app.kubernetes.io/name=amazon-cloudwatch-observability
   ```

1. 确认 CloudWatch 代理容器组（pod）是否在所有节点上运行。

   ```
   kubectl get pods -n amazon-cloudwatch -l app.kubernetes.io/name=cloudwatch-agent
   ```

   所有代理容器组（pod）都必须显示 `Running` 状态。

## 关键配置选项
<a name="container-insights-eks-otel-helm-config"></a>

下表描述了可以配置的关键 Helm 图表值。使用 `--set` 标志或自定义 `values.yaml` 文件传递这些值。

### 集群设置
<a name="container-insights-eks-otel-helm-config-cluster"></a>


| 参数 | 默认值 | 说明 | 
| --- | --- | --- | 
| clusterName | — | Amazon EKS 集群的名称。必需。 | 
| region | — | 集群运行所在的 Amazon 区域。必需。 | 
| otelContainerInsights.enabled | false | 使用文件日志接收器启用 OTel Container Insights。 | 

### 容器日志（OTel 文件日志接收器）
<a name="container-insights-eks-otel-helm-config-logs"></a>


| 参数 | 默认值 | 说明 | 
| --- | --- | --- | 
| containerLogs.enabled | true | 使用 OTel 文件日志接收器启用容器日志收集。 | 
| containerLogs.logGroupName | /aws/containerinsights/{{cluster-name}}/application | 容器日志的 CloudWatch Logs 日志组名称。 | 
| containerLogs.logRetentionDays | 7 | 在 CloudWatch Logs 中保留容器日志的天数。 | 

### 代理（指标）
<a name="container-insights-eks-otel-helm-config-agent"></a>


| 参数 | 默认值 | 说明 | 
| --- | --- | --- | 
| agent.enabled | true | 启用 CloudWatch 代理 DaemonSet 以收集指标。 | 
| agent.serviceAccount.name | cloudwatch-agent | 代理的 Kubernetes 服务账户的名称。 | 
| agent.resources.requests.cpu | 100m | 代理容器的 CPU 请求。 | 
| agent.resources.requests.memory | 128Mi | 代理容器的内存请求。 | 
| agent.resources.limits.cpu | 200m | 代理容器的 CPU 限制。 | 
| agent.resources.limits.memory | 256Mi | 代理容器的内存限制。 | 

### GPU 监控
<a name="container-insights-eks-otel-helm-config-gpu"></a>


| 参数 | 默认值 | 说明 | 
| --- | --- | --- | 
| agent.config.logs.metrics\_collected.kubernetes.enhanced\_container\_insights | true | 启用 Enhanced Container Insights 指标，包括 GPU 指标。 | 
| dcgmExporter.enabled | false | 为 NVIDIA GPU 指标启用 DCGM 导出器。需要 NVIDIA GPU 节点。 | 
| neuronMonitor.enabled | false | 为 Amazon Inferentia 和 Trainium 指标启用 Neuron 显示器。 | 

## TLS 证书管理
<a name="container-insights-eks-otel-helm-tls"></a>

CloudWatch 可观测性操作员需要 TLS 证书才能进行 Webhook 通信。默认情况下，图表会生成自签名证书。可以使用 cert-manager 自动管理证书。

### 自签名证书（默认）
<a name="container-insights-eks-otel-helm-tls-default"></a>

默认情况下，Helm 图表会生成自签名 CA 并从该 CA 颁发证书。无需其他配置。升级期间，图表会自动轮换这些证书。

### cert-manager 集成
<a name="container-insights-eks-otel-helm-tls-certmanager"></a>

可以使用 cert-manager 自动颁发和续订证书。组织需要外部签名的证书或需要进行集中证书管理时，此方法很有用。

**配置 cert-manager 集成**

1. 确认集群中是否安装了 cert-manager。

   ```
   kubectl get pods -n cert-manager
   ```

1. 安装启用了 cert-manager 的 Helm 图表。将 {{cluster-name}} 替换为 Amazon EKS 集群名称，将 {{region}} 替换为您的 Amazon 区域，并将 {{account-id}} 替换为您的 Amazon 账户 ID。

   ```
   helm install amazon-cloudwatch-observability \
     aws-observability/amazon-cloudwatch-observability \
     --namespace amazon-cloudwatch \
     --create-namespace \
     --set clusterName={{cluster-name}} \
     --set region={{region}} \
     --set agent.serviceAccount.name=cloudwatch-agent \
     --set "agent.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=arn:aws:iam::{{account-id}}:role/EKS-CW-Observability-Role" \
     --set otelContainerInsights.enabled=true \
     --set admissionWebhooks.certManager.enabled=true
   ```

启用 cert-manager 后，图表会创建一个 `Certificate` 资源，cert-manager 会使用该资源来自动颁发和管理 Webhook TLS 证书。

**注意**  
也可以将 cert-manager 与外部颁发者（例如 HashiCorp Vault）一起使用。要配置外部颁发者，请设置 `admissionWebhooks.certManager.issuerRef.name` 和 `admissionWebhooks.certManager.issuerRef.kind` 以匹配 cert-manager 颁发者。

## 升级图表
<a name="container-insights-eks-otel-helm-upgrade"></a>

升级 Helm 图表以应用新的配置值或更新到更新的图表版本。

**升级 Helm 图表**

1. 更新 Helm 存储库以获取最新的图表版本。

   ```
   helm repo update
   ```

1. 使用所需值运行升级命令。将 {{cluster-name}} 替换为 Amazon EKS 集群名称，将 {{region}} 替换为您的 Amazon 区域，并将 {{account-id}} 替换为您的 Amazon 账户 ID。

   ```
   helm upgrade amazon-cloudwatch-observability \
     aws-observability/amazon-cloudwatch-observability \
     --namespace amazon-cloudwatch \
     --set clusterName={{cluster-name}} \
     --set region={{region}} \
     --set agent.serviceAccount.name=cloudwatch-agent \
     --set "agent.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=arn:aws:iam::{{account-id}}:role/EKS-CW-Observability-Role" \
     --set otelContainerInsights.enabled=true
   ```

1. 确认升级已成功完成。

   ```
   helm list -n amazon-cloudwatch
   ```

   修订号必须递增且状态必须显示为 `deployed`。

**提示**  
为避免在升级期间丢失配置值，请将自定义值存储在 `values.yaml` 文件中，然后将其与 `-f values.yaml` 标志一起传递。

## 卸载图表
<a name="container-insights-eks-otel-helm-uninstall"></a>

要从集群中移除 OTel Container Insights，请卸载 Helm 版本。

**卸载 Helm 图表**

1. 运行以下命令卸载相关版本。

   ```
   helm uninstall amazon-cloudwatch-observability \
     --namespace amazon-cloudwatch
   ```

1. （可选）可删除不再需要的命名空间。

   ```
   kubectl delete namespace amazon-cloudwatch
   ```

卸载 Helm 图表后，IAM 角色和 OIDC 提供者配置仍保留在 Amazon 账户中。可单独删除不再需要的这些资源。

```
aws iam detach-role-policy \
  --role-name EKS-CW-Observability-Role \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

aws iam delete-role \
  --role-name EKS-CW-Observability-Role
```

## 验证 CloudWatch 中的数据
<a name="container-insights-eks-otel-helm-verify"></a>

安装 Helm 图表后，Container Insights 数据将在 3 到 5 分钟内显示在 CloudWatch 中。

### 检查指标
<a name="container-insights-eks-otel-helm-verify-metrics"></a>

**在 CloudWatch 中检查指标**

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

1. 在导航窗格中，选择 **Container Insights**。

1. 确认集群显示在集群列表中，并且基础设施指标已在填充。

### 检查 日志
<a name="container-insights-eks-otel-helm-verify-logs"></a>

要确认集群的日志组是否存在，请运行以下命令。将 {{cluster-name}} 替换为 Amazon EKS 集群的名称。

```
aws logs describe-log-groups \
  --log-group-name-prefix "/aws/containerinsights/{{cluster-name}}" \
  --query "logGroups[].logGroupName" \
  --output table
```

## 问题排查
<a name="container-insights-eks-otel-helm-troubleshoot"></a>

按照以下指南解决在使用 Helm 部署 OTel Container Insights 时遇到的常见问题。

### CrashLoopBackOff 中的 Operator 容器组（pod）
<a name="container-insights-eks-otel-helm-ts-operator-crash"></a>

**症状：**运行 `kubectl get pods -n amazon-cloudwatch` 时，Operator 容器组（pod）显示 `CrashLoopBackOff` 状态。

**原因：**由于 TLS 证书问题或权限不足，Operator 容器组（pod）无法启动。

**解决方案：**要解决这个问题，请完成以下步骤。

1. 检查 Operator 容器组（pod）日志中是否存在与证书相关的错误。

   ```
   kubectl logs -n amazon-cloudwatch -l app.kubernetes.io/name=amazon-cloudwatch-observability --tail=50
   ```

1. 确认命名空间中是否存在 Webhook TLS 密码。

   ```
   kubectl get secrets -n amazon-cloudwatch | grep webhook
   ```

1. 若使用 cert-manager，请确认 `Certificate` 资源状态是否显示为 `Ready`。

   ```
   kubectl get certificate -n amazon-cloudwatch
   ```

1. 如果证书丢失或无效，请卸载并重新安装图表以重新生成证书。

   ```
   helm uninstall amazon-cloudwatch-observability -n amazon-cloudwatch
   ```

### 未在所有节点上调度代理容器组（pod）
<a name="container-insights-eks-otel-helm-ts-agent-scheduling"></a>

**症状：**代理 DaemonSet 显示的容器组（pod）少于集群中的节点数。

**原因：**节点污点、资源限制或节点选择器使代理容器组（pod）无法在某些节点上调度。

**解决方案：**要解决这个问题，请完成以下步骤。

1. 检查 DaemonSet 的状态是否存在调度问题。

   ```
   kubectl get daemonset -n amazon-cloudwatch cloudwatch-agent
   ```

1. 检查是否有不可调度的容器组（pod）并查看其事件。

   ```
   kubectl get pods -n amazon-cloudwatch -l app.kubernetes.io/name=cloudwatch-agent --field-selector=status.phase!=Running
   ```

1. 如果节点有污点，请在 Helm 图表值中添加容差。例如，要容忍所有污点，请使用以下标志升级图表。

   ```
   helm upgrade amazon-cloudwatch-observability \
     aws-observability/amazon-cloudwatch-observability \
     --namespace amazon-cloudwatch \
     --reuse-values \
     --set "agent.tolerations[0].operator=Exists"
   ```

1. 确认代理容器组（pod）现在是否在所有节点上运行。

   ```
   kubectl get pods -n amazon-cloudwatch -l app.kubernetes.io/name=cloudwatch-agent -o wide
   ```