在 Kubernetes 平台上启用 Application Signals - Amazon CloudWatch

在 Kubernetes 平台上启用 Application Signals

要启用在 Amazon EKS 以外的 Kubernetes 系统上运行的应用程序,请按照本节中的说明进行操作。当前,Application Signals 支持 Java、Python 和 .NET 应用程序。

要求

  • 您拥有启用 Application Signals 的 Kubernetes 集群的管理员权限。

  • 您必须在运行 Kubernetes 集群的环境中安装 AWS CLI。有关安装 AWS CLI 的更多信息,请参阅安装或更新 AWS CLI 的最新版本

  • 您已在本地终端上安装了 kubectl 和 helm。有关更多信息,请参阅 kubectlHelm 文档。

步骤 1:在账户中启用 Application Signals

如果您尚未在此账户中启用 Application Signals,则必须向 Application Signals 授予发现您的服务所需的权限。为此,请执行以下操作:您的账户只需执行一次该操作。

为您的应用程序启用 Application Signals
  1. 通过 https://console.aws.amazon.com/cloudwatch/ 打开 CloudWatch 控制台。

  2. 在导航窗格中,选择服务

  3. 选择开始发现您的服务

  4. 选中该复选框并选择开始发现您的服务

    首次在您的账户中完成此步骤时,Application Signals 会创建 AWSServiceRoleForCloudWatchApplicationSignals 服务相关角色。此角色授予 Application Signals 以下权限:

    • xray:GetServiceGraph

    • logs:StartQuery

    • logs:GetQueryResults

    • cloudwatch:GetMetricData

    • cloudwatch:ListMetrics

    • tag:GetResources

    有关该角色的更多信息,请参阅 CloudWatch Application Signals 的服务相关角色权限

步骤 2:在集群中安装 CloudWatch 代理 operator

安装 CloudWatch 代理 operator 会将 operator、CloudWatch 代理和其他自动检测工具安装到您的集群中。为此,请输入以下命令。将 $REGION 替换为您的 AWS 区域。将 $YOUR_CLUSTER_NAME 替换为要在 Application Signals 控制面板中为集群显示的名称。

helm repo add aws-observability https://aws-observability.github.io/helm-charts helm install amazon-cloudwatch-operator aws-observability/amazon-cloudwatch-observability \ --namespace amazon-cloudwatch --create-namespace \ --set region=$REGION \ --set clusterName=$YOUR_CLUSTER_NAME

有关更多信息,请参阅 GitHub 上的 amazon-cloudwatch-observability

步骤 3:为 Kubernetes 集群设置 AWS 凭证

重要

如果在 Amazon EC2 上托管您的 Kubernetes 集群,则可以跳过此部分并继续 步骤 4:添加注释

如果在本地托管您的 Kubernetes 集群,则必须按照本节中的说明向您的 Kubernetes 环境添加 AWS 凭证。

设置本地 Kubernetes 集群的权限
  1. 创建用于向本地主机提供权限的 IAM 用户:

    1. 通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。

    2. 依次选择用户创建用户

    3. 用户详情中,为用户名输入新 IAM 用户的名称。这是 AWS 的登录名,将用于对您的主机进行身份验证。然后选择下一个

    4. 设置权限页面的权限选项下,选择直接附加策略

    5. 权限策略列表中,选择要添加到您的用户的 CloudWatchAgentServerPolicy 策略。然后选择下一步

    6. 查看并创建页面上,确保您对用户名满意,并且 CloudWatchAgentServerPolicy 策略位于权限摘要中。

    7. 选择 Create user

  2. 创建和检索您的 AWS 访问密钥和秘密密钥:

    1. 在 IAM 控制台的导航窗格中,选择用户,然后选择您在上一步中所创建用户的用户名。

    2. 在用户的页面上,选择安全凭证选项卡。然后,在访问密钥部分,选择创建访问密钥

    3. 对于创建访问密钥步骤 1,选择命令行界面 (CLI)

    4. 对于创建访问密钥步骤 2,(可选)输入标记,然后选择下一步

    5. 对于创建访问密钥步骤 3,选择下载.csv 文件以保存包含您的 IAM 用户访问密钥和秘密访问密钥的 .csv 文件。您在后续步骤中需要此信息。

    6. 选择完成

  3. 通过输入以下命令,在本地主机中配置 AWS 凭证。将 ACCESS_KEY_IDSECRET_ACCESS_ID 替换为您在上一步中下载的 .csv 文件中新生成的访问密钥和秘密访问密钥。默认情况下,凭证文件保存在 /home/user/.aws/credentials.

    $ aws configure --profile AmazonCloudWatchAgent AWS Access Key ID [None]: ACCESS_KEY_ID AWS Secret Access Key [None]: SECRET_ACCESS_ID Default region name [None]: MY_REGION Default output format [None]: json
  4. 使用 Helm 图表编辑 CloudWatch 代理安装的自定义资源,以添加新创建的 AWS 凭证密钥。

    kubectl edit amazoncloudwatchagent cloudwatch-agent -n amazon-cloudwatch
  5. 当您的文件编辑器处于打开状态时,通过将以下配置添加到部署顶部,将 AWS 凭证挂载到 CloudWatch 代理容器中。将路径 /home/user/.aws/credentials 替换为本地 AWS 凭证文件的位置。

    apiVersion: cloudwatch.aws.amazon.com/v1alpha1 kind: AmazonCloudWatchAgent metadata: name: cloudwatch-agent namespace: amazon-cloudwatch spec: volumeMounts: - mountPath: /rootfs volumeMounts: - name: aws-credentials mountPath: /root/.aws readOnly: true volumes: - hostPath: path: /home/user/.aws/credentials name: aws-credentials ---

步骤 4:添加注释

注意

要为使用 ESM 的 Node.js 应用程序启用 Application Signals,改为跳过本节中的步骤并参阅

下一步是通过向您的 Kubernetes 工作负载命名空间添加特定于语言的注释,为 CloudWatch Application Signals 检测您的应用程序。此注释会自动检测应用程序以向 Application Signals 发送指标、跟踪和日志。

添加 Application Signals 的注释
  1. 您有两种注释选项:

    • 为工作负载添加注释会自动检测集群中的单个工作负载。

    • 注释命名空间会自动检测所选命名空间中部署的所有工作负载。

    选择其中一个选项,然后按照相应的步骤操作。

  2. 要注释单个工作负载,请输入以下命令之一。将 $WORKLOAD_TYPE$WORKLOAD_NAME 替换为工作负载的值。

    • 对于 Java 工作负载:

      kubectl patch $WORKLOAD_TYPE $WORKLOAD_NAME -p '{"spec": {"template": {"metadata": {"annotations": {"instrumentation.opentelemetry.io/inject-java": "true"}}}}}'
    • 对于 Python 工作负载:

      kubectl patch $WORKLOAD_TYPE $WORKLOAD_NAME -p '{"spec": {"template": {"metadata": {"annotations": {"instrumentation.opentelemetry.io/inject-python": "true"}}}}}'

      对于 Python 应用程序,还需要额外的配置。有关更多信息,请参阅 启用 Application Signals 后,Python 应用程序无法启动

    • 对于 .NET 工作负载:

      kubectl patch $WORKLOAD_TYPE $WORKLOAD_NAME -p '{"spec": {"template": {"metadata": {"annotations": {"instrumentation.opentelemetry.io/inject-dotnet": "true"}}}}}'
      注意

      要在基于 Alpine Linux (linux-musl-x64) 的映像上为 .NET 工作负载启用 Application Signals,请添加以下额外注释。

      instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"
    • 对于 Node.js 工作负载:

      kubectl patch $WORKLOAD_TYPE $WORKLOAD_NAME -p '{"spec": {"template": {"metadata": {"annotations": {"instrumentation.opentelemetry.io/inject-nodejs": "true"}}}}}'
  3. 要注释命名空间中的所有工作负载,请输入以下命令之一。将 $NAMESPACE 替换为您的命名空间的名称。

    如果命名空间同时包含 Java、Python 和 .NET 工作负载,请将所有注释都添加到命名空间。

    • 对于命名空间中的 Java 工作负载:

      kubectl annotate ns $NAMESPACE instrumentation.opentelemetry.io/inject-java=true
    • 对于命名空间中的 Python 工作负载:

      kubectl annotate ns $NAMESPACE instrumentation.opentelemetry.io/inject-python=true

      对于 Python 应用程序,还需要额外的配置。有关更多信息,请参阅 启用 Application Signals 后,Python 应用程序无法启动

    • 对于命名空间中的 .NET 工作负载:

      kubectl annotate ns $NAMESPACE instrumentation.opentelemetry.io/inject-dotnet=true
    • 对于命名空间中的 Node.js 工作负载:

      kubectl annotate ns $NAMESPACE instrumentation.opentelemetry.io/inject-nodejs=true

    添加注释后,通过输入以下命令重新启动命名空间中的所有容器组(pod):

    kubectl rollout restart
  4. 完成上述步骤后,在 CloudWatch 控制台中,依次选择 Application Signals服务。这将打开控制面板,您可以在其中查看 Application Signals 收集的数据。可能需要几分钟才会显示数据。

    有关服务视图的更多信息,请参阅 使用 Application Signals 监控应用程序的运行状况

设置采用 ESM 模块格式的 Node.js 应用程序

我们对采用 ESM 模块格式的 Node.js 应用程序提供有限的支持。有关详细信息,请参阅使用 ESM 的 Node.js 的已知限制

对于 ESM 模块格式,通过注释清单文件来启用 Application Signals 不起作用。跳过之前的程序,改为执行以下操作:

为使用 ESM 的 Node.js 应用程序启用 Application Signals
  1. 将相关依赖项安装到您的 Node.js 应用程序中以进行自动检测:

    npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation npm install @opentelemetry/instrumentation@0.54.0
  2. 将以下环境变量添加到应用程序的 Dockerfile 中并构建映像。

    ... ENV OTEL_AWS_APPLICATION_SIGNALS_ENABLED=true ENV OTEL_TRACES_SAMPLER_ARG='endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000' ENV OTEL_TRACES_SAMPLER='xray' ENV OTEL_EXPORTER_OTLP_PROTOCOL='http/protobuf' ENV OTEL_EXPORTER_OTLP_TRACES_ENDPOINT='http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces' ENV OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT='http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics' ENV OTEL_METRICS_EXPORTER='none' ENV OTEL_LOGS_EXPORTER='none' ENV NODE_OPTIONS='--import @aws/aws-distro-opentelemetry-node-autoinstrumentation/register --experimental-loader=@opentelemetry/instrumentation/hook.mjs' ENV OTEL_SERVICE_NAME='YOUR_SERVICE_NAME' #replace with a proper service name ENV OTEL_PROPAGATORS='tracecontext,baggage,b3,xray' ... # command to start the application # for example # CMD ["node", "index.mjs"]
  3. 将环境变量 OTEL_RESOURCE_ATTRIBUTES_POD_NAMEOTEL_RESOURCE_ATTRIBUTES_NODE_NAMEOTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_NAMEPOD_NAMESPACEOTEL_RESOURCE_ATTRIBUTES 添加到应用程序的部署 yaml 文件中。例如:

    apiVersion: apps/v1 kind: Deployment metadata: name: nodejs-app labels: app: nodejs-app spec: replicas: 2 selector: matchLabels: app: nodejs-app template: metadata: labels: app: nodejs-app # annotations: # make sure this annotation doesn't exit # instrumentation.opentelemetry.io/inject-nodejs: 'true' spec: containers: - name: nodejs-app image:your-nodejs-application-image #replace it with a proper image uri imagePullPolicy: Always ports: - containerPort: 8000 env: - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: OTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_NAME valueFrom: fieldRef: fieldPath: metadata.labels['app'] # Assuming 'app' label is set to the deployment name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: OTEL_RESOURCE_ATTRIBUTES value: "k8s.deployment.name=$(OTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_NAME),k8s.namespace.name=$(POD_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)"
  4. 将 Node.js 应用程序部署到 Kubernetes 集群。