亚马逊AWS官方博客

利用 Amazon Systems Manager 和 Terraform 批量为已运行的自定义范围的 Amazon EC2 安装 Amazon CloudWatch Agent 实现高阶 metrics 采集与展示

1. 问题提出

Amazon CloudWatch 是云上实现可观测性的重要服务。基本的 metrics 已经预置在 CloudWatch 中,所支持的具体的 metrics 如链接所示:ec2-cloudwatch-metrics。高阶的 metrics(具体信息如链接:metrics-collected-by-CloudWatch-agent),以及用户自定义的 metrics,需要通过安装 CloudWatch Agent 来实现收集。

向 EC2 上安装 CloudWatch Agent 的场景主要有以下几个:(1)在单台 EC2 上安装 CloudWatch Agent;(2)创建之前,在多台 EC2 上批量安装 CloudWatch Agent;(3)创建后,已经安装了应用的前提下,在某个 domain scope 范围内(如某个 Organization)的 EC2 上批量安装 CloudWatch Agent;(4)创建后,已经安装了应用的前提下,在某个 region 的指定的 EC2 上批量安装 CloudWatch Agent。

场景 1 可以通过 command line 方式实现,操作可以参考链接:installing-cloudwatch-agent-commandline;场景 2,可以通过 user data script,以及 AMI 方式实现。使用 User data script 实现的操作可以参考链接:deploy-cloudwatch-agent-user-data-script。通过 AMI 方式实现的操作可以参考链接:include-cloudwatch-agent-amis;场景 3 可以通过 Amazon Systems Manager 的 Quick Setup 方式实现。目前支持的 domain scope 的粒度是可以选择 Organization 下的 OU 和 region 两个维度;场景 4 对于很多客户来说有需求场景。实操发现通过 Amazon Systems Manager(以下简称 SSM)可以批量安装 CloudWatch Agent,但 EC2 实例所需要绑定的 IAM instance profile,iam role 及 iam policy 并没有自动生成及实现绑定。实战中很多客户已经广泛地使用 terraform 作为资源的管理和维护工具。这篇 blog 对如何利用 terraform 批量为已运行的自定义范围的 EC2 实例安装 CloudWatch Agent 实现高阶 metrics 采集给出实践指导。

2. 架构设计及简述

架构设计示意图如下图所示。

架构简述:

通过 SSM 为自定义范围的 EC2 实例批量安装 CloudWatch Agent,通过 SSM 的 Parameter Store 功能集中存放 CloudWatch Agent 的配置文件,通过 SSM 的 RUN Command 功能为自定义范围的 EC2 实例批量下发 CloudWatch Agent 的配置文件。通过 Terraform 生成目标 EC2 实例所需要关联的 IAM instance profile,IAM Role 以及 IAM Policy,并使用 AWS CLI 批量将这些 IAM 实体关联到目标的 EC2 实例上。

3. 操作指导

3.1 通过 SSM 在指定的 EC2 上批量安装 CloudWatch Agent

在 console 上部的搜索框内输入 Systems Manager,进入 SSM 的操作界面。点击Quick Setup(如下面截图所示):

切换到 Library 页,点击 Create(如下面截图所示):

勾选 Install and configure the CloudWatch agent,和 Update the CloudWatch agent once every 30 days 两个选项,分别点选 Current account, Current Region, Manual 选项,在 Instances 列表里根据需要勾选需要安装 CloudWatch Agent 的 EC2 实例(如下面截图所示)。

点击页面右下角的 create 按键,提交任务。任务执行完成后可以通过 console(如下面截图所示)跟踪查看任务执行的情况。

点选 Account number 左侧的按钮,可以激活 View details 按钮,点击该按钮可以查看任务执行的详细信息。

3.2 配置 CloudWatch Agent Configuration,并批量下发到目标 EC2

登录目标机器中的一台,以 ec2-user 用户运行下面的命令,配置 CloudWatch Agent。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

根据需要选择不同的配置项选项。对配置选项的详细说明,见链接:

create-cloudwatch-agent-configuration-file-wizard

当遇到下面这个问题的时候,选择 yes,将 CloudWatch Agent 的配置文件保存在 parameter store 中。

保存在 Parameter Store 中的配置文件如下图所示:

在 Systems Manager 界面的左侧导航栏选择 Node Management 下的 Run Command,在搜索框中输入 CloudWatch,点选下面列表中的 AmazonCloudWatch-ManageAgent,在 Optional Configuration Location 中填入 Parameter Store 存储的 CloudWatch Agent 的配置文件名称(本例中是 AmazonCloudWatch-linux)。如下面截图所示。

在 Target selection 部分,点选 Choose instances manually,然后选择目标的 EC2实例。之后在页面最右下角点击 Run,提交任务,将 CloudWatch Agent 的配置文件批量下发到所有目标 EC2 上。

3.3 通过 Terraform 生成 Cloudwatch Agent 需要的 instance profile,role 和 policy

Terraform 作为社区非常活跃的 IaC 工具,使高效便捷地管理 Infra 成为可能。本场景通过 Terraform 创建使能 CloudWatch Agent 所需的 instance prole, role 以及 policy。

在本机安装 Terraform 有两个必要的步骤:(1)安装 Terraform 应用;(2)安装 VS Code 客户端。安装 Terraform 应用的步骤可以参考官方链接:install-terraform-cli

VS Code 为操作 Terraform 提供了非常方便的工具,建议配合 Terraform 一起使用。下载链接:vscode-download

通过 3.1,3.2 安装和配置后的 CloudWatch Agent,仍然不能实现收集高阶 metrics 并在 CloudWatch 中展示,因为还没有给目标的 EC2 实例绑定所需要的 IAM Role。为了给 EC2 实例绑定 Role,需要定义一个 EC2 的 IAM instance_profile。Role 所具有的权限通过 Policy 来定义。使能 CloudWatch Agent 的 Amazon Managed IAM Policy 在官方文档中有阐述,链接如下:create-iam-roles-for-cloudwatch-agent

可以看到 CloudWatchAgentServerPolicy 是必要的 Policy。这个 managed policy 的具体赋权内容将出现在接下来的 Terraform 脚本中。

定义一个 Terraform 工程(文件夹),名为 cwagent。在这个文件夹下,创建 cwagent-iam.tf,内容如下:

provider "aws" {
    region = "us-west-2"
    access_key = ""
    secret_key = ""
}

resource "aws_iam_role_policy" "cwagent_enable_policy" {
  name = "cwagent_enable_policy"
  role = "${aws_iam_role.cwagent_enable_role.id}"
  policy = "${file("cwagent-enable-policy.json")}"
}

resource "aws_iam_role" "cwagent_enable_role" {
  name = "cwagent_enable_role"

  assume_role_policy = "${file("ec2-assume-policy.json")}"
}

resource "aws_iam_instance_profile" "ec2_profile" {
  name = "cwagent_enable_profile"
  role = "${aws_iam_role.cwagent_enable_role.
}

Ec2-assume-policy.json 文件内容如下:

{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Effect": "Allow",
        "Sid": "",
        "Principal": {
          "Service": "ec2.amazonaws.com"
        }
      }
    ]
  }

Cwagent-enable-policy.json 文件内容如下:

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "cloudwatch:PutMetricData",
              "ec2:DescribeVolumes",
              "ec2:DescribeTags",
              "logs:PutLogEvents",
              "logs:DescribeLogStreams",
              "logs:DescribeLogGroups",
              "logs:CreateLogStream",
              "logs:CreateLogGroup"
          ],
          "Resource": "*"
      },
      {
          "Effect": "Allow",
          "Action": [
              "ssm:GetParameter"
          ],
          "Resource": "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
      }
  ]
}

进入目标文件夹(cwgent)后,依次执行:

Terraform init
Terraform plan
Terraform apply

完成相关的 IAM instance profile,IAM Role,Policy 的创建。可以在 IAM console 中查看到创建出的 Role 以及 Policy。

3.4 通过 CLI 将相关的 instance profile,role,policy 批量挂到 EC2 上

通过下面的命令可以查看目标 EC2 实例上的关联 instance profile 的情况:

aws ec2 describe-iam-instance-profile-associations --filters "Name=instance-id,Values=<ec2 instance id> "

如果没有 instance profile 关联,可以直接把刚刚生成的 instance profile 关联给 EC2 实例,命令如下:

aws ec2 associate-iam-instance-profile --instance-id <ec2 instance id> --iam-instance-profile Name=cwagent_enable_profile

如果已经有 instance profile 关联,可以替换原有的 instance profile,命令如下:

aws ec2 replace-iam-instance-profile-association --association-id <instance-profile-association id, prefix is iip> --iam-instance-profile Name=cwagent_enable_profile

至此,CloudWatch Agent 已经可以收集高阶的 metrics 并在 CloudWatch 中进行展示。在 CloudWatch 左侧的导航栏中 Metrics 下,选择 all metrics,在右侧的 custom namespaces 下可以看到 CWAgent 的 namespace,点击进入会看到收集到的 metrics 的详细信息。

3.5 Cloudwatch Agent 安装,debug 的相关命令

查看 CloudWatch Agent 运行的情况:

systemctl status amazon-cloudwatch-agent

重启 CloudWatch Agent:

systemctl restart amazon-cloudwatch-agent

CloudWatch Agent 的运行日志存储在:

/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log

CloudWatch Agent troubleshooting 更多内容,可见:

CloudWatch-Agent-troubleshooting-no-metrics

参考文档

本篇作者

魏诗洋

AWS 资深解决方案架构师,专注在线券商及量化私募云上系统架构及解决方案设计,关注电商、游戏行业在推荐、用户精细化运营方向的架构设计及实践。10 年+数据领域研发及架构设计经验。