亚马逊AWS官方博客

使用 Amazon EC2 Systems Manager 创建自定义 AMI 并将更新推送至正在运行的 Amazon EMR 集群

Original URL:https://aws.amazon.com/blogs/big-data/create-custom-amis-and-push-updates-to-a-running-amazon-emr-cluster-using-amazon-ec2-systems-manager/

使用 Amazon EMR,您可以完全控制集群,并且可以灵活地自定义集群并轻松安装其他应用程序。 EMR客户经常使用 引导操作(bootstrap actions)来在群集中安装和配置自定义软件。但是,引导操作仅在群集或节点启动期间运行。这使您很难在集群已运行之后进行配置更改。Amazon EMR也可以使用自定义的Amazon Machine Image(AMI)来启动集群。 通过自定义Amazon Linux AMI启动集群,现在让EMR集群管理变得更加容易。 但是,随着环境中AMI的数量开始增加,创建和管理自定义AMI的任务会变得越来越困难。Amazon EC2 Systems Manager可帮助您自动化各种管理任务,例如自动化AMI创建或跨数百个实例运行命令或脚本。 在本文中,我将展示如何使用Systems Manager Automation来自动创建用于EMR的自定义Amazon Linux AMI和为AMI打补丁。使用Systems Manager Run Command ,您可以远程管理Amazon EC2实例或本地计算机的配置。 Run Command可用于帮助您在EMR群集节点上执行以下类型的任务:安装应用程序,重新启动守护程序(HDFS,YARN,Presto等),并进行配置更改。 我还将展示如何使用Run Command将命令发送到正在运行的EMR群集的所有节点。

使用自定义AMI的好处

尽管您可以使用引导操作轻松地自定义EMR群集,但是使用自定义AMI可能会有好处。

    • 缩短集群启动时间

在某些情况下,引导操作可能会影响您的群集启动时间。 例如,您的引导操作可能是在做一些事情,例如通过Internet下载大型程序并延迟群集准备就绪的时间。 通过直接在AMI中添加和安装程序,可以减少完成集群启动的时间。

    • 防止由于意外引起的引导操作失败

在某些情况下,直接在AMI中安装和配置自定义软件可以降低意外失败的风险。 例如,您的引导操作用于下载程序的镜像或存储库可能处于脱机状态或无法访问。 这可能会导致引导操作失败,从而可能导致集群启动失败。

    • 支持Amazon EBS根卷加密

EMR安全配置提供了许多安全和加密功能。 这包括为HDFS(本地卷/ Amazon EBS)和Amazon S3加密静态数据的功能。 但是,某些法规/合规性策略可能要求对根(引导)卷也进行加密。 通过使用您自己的Amazon Linux AMI,您可以创建使用加密的EBS根卷的AMI,并将这些AMI用于您的EMR集群。

使用您自定义AMI的要求

用于EMR的自定义AMI必须满足以下要求:

      • 必须是Amazon Linux AMI
      • 必须是HVM AMI
      • 必须是EBS支持的AMI
      • 不得有多个EBS卷
      • 必须是64位AMI
      • 不得具有与应用程序同名的用户(例如:hadoop,hdfs,yarn或spark)

这个AMI不一定属于您自己,但是您的service role 必须具有启动该AMI的权限。 因此,AMI应该是以下之一:

      • 由您拥有
      • 公共AMI
      • 由其所有者与您共享

有关EMR定制AMI的最佳实践和注意事项,请参阅使用定制AMI。

演练

通过本文中的示例,我将向您展示如何实现以下方案:

      • 使用预安装的软件自动执行创建自定义AMI的工作流程
      • 在运行中的EMR群集的所有节点上运行命令或更改应用程序配置

开始之前

在本文中,将使用AWS CLI来执行所示的示例和步骤。 但是, AWS CLI不是必须要安装的,也可以使用AWS管理控制台执行相同的任务。

本文示例所使用的区域是us-east-1(N. Virginia)。

使用Systems Manager Automation构建自定义AMI

在本节中,我将展示如何使用System Manager Automation来创建自定义AMI。 下图概述了自动化将执行的操作:

 

1)为Automation配置角色

在开始之前,您必须为Automation配置IAM实例配置文件角色(instance profile role)和服务角色(service role)。 实例配置文件角色授予Automation对您的实例执行操作的权限,例如执行命令或启动和停止服务。 服务角色(或 assume 角色)授予Automation代表您执行操作的权限。

配置Automation所需的IAM角色通常是设置Automation最困难的部分之一。 幸运的是,您只需要配置一次。 我们还有一个AWS CloudFormation模板,可用于创建和配置Automation所需的角色。 有关更多信息,请参阅方法1:使用AWS CloudFormation配置Automation角色

要手动为Automation配置角色,请参阅使用IAM配置自动化角色

2)创建一个自定义的Automation文档

Automation文档定义了Systems Manager执行的操作。在此步骤中,您将创建一个执行以下步骤的自定义Automation文档(customEmrAmiDocument):

      • 从基础的Amazon Linux AMI启动一个EC2实例
      • 更新实例上已安装的软件
      • 运行其他Linux命令(可选)
      • 关闭实例
      • 创建实例的AMI
      • 终止实例

创建自定义Automation文档,请首先将customEmrAmiDocument.json文档下载到本地计算机。 然后,您可以使用控制台,AWS CLI或AWS开发工具包在您的账户中创建(上传)该Automation文档。 以下示例显示了如何使用AWS CLI创建名为“ customEmrAmiDocument”的自动化文档:

$ aws ssm create-document –name “customEmrAmiDocument” –content file:///<PATH_TO>/customEmrAmiDocument.json –document-type Automation –region us-east-1

注意:创建Automation文档后,该文档不会被执行。 您可以在下一步中执行此文档。 还要注意,必须引用file://,后跟内容文件的路径。

有关更多信息,请参见创建Automation文档

3)执行自定义Automation文档

在上一步中创建的“ customEmrAmiDocument”自动化文档具有参数列表(SourceAmiId,InstanceIamRole等),以及每个参数的描述。 要查看文档参数,请运行以下命令:

$ aws ssm describe-document –name customEmrAmiDocument –query “Document.Parameters” –region us-east-1

前面的命令返回类似于以下内容的输出:

[

{

“Type”: “String”,

“Description”: “(Required) The source Amazon Machine Image ID.”,

“Name”: “SourceAmiId”

},

{

“Type”: “String”,

“Description”: “(Required) The name of the role that enables Systems Manager (SSM) to manage the instance.”,

“DefaultValue”: “ManagedInstanceProfile”,

“Name”: “InstanceIamRole”

},

启动Automation执行时,必须传递所需的参数(SourceAmiId)以及要覆盖其默认值的所有其他参数。如果使用CloudFormation创建所需的IAM角色,则无需指定InstanceRole和AutomationAssumeRole参数。

要执行文档而不包括InstanceRole和AutomationAssumeRole参数,请运行以下命令:

aws ssm start-automation-execution –document-name “customEmrAmiDocument” –parameters “SourceAmiId=<AMI_ID>, CustomCommands=[<List_of_linux_commands_to_run>]” –region us-east-1

如果您的角色名称或ARN的值不是默认值,请确保相应地指定这些参数。 例如,如果您的实例配置文件/角色称为“ MyManagedInstanceProfile”,而Automation服务角色ARN为“ arn:aws:iam::012345678910:role/MyAutomationServiceRole”,则用于执行Automation的参数应类似于以下内容:

–parameters “SourceAmiId=<AMI_ID>, InstanceIamRole=MyManagedInstanceProfile, AutomationAssumeRole=arn:aws:iam::<ACCOUNT_ID>:role/MyAutomationServiceRole, InstanceType=<Instance_Type>, CustomCommands=[<List_of_linux_commands_to_run>]”

使用以下命令,启动Automation执行创建自定义Amazon Linux AMI。该AMI会安装Python 3.5和 boto3:

aws ssm start-automation-execution –document-name “customEmrAmiDocument” –parameters “SourceAmiId=ami-4fffc834, InstanceIamRole=<INSTANCE_PROFILE_NAME>, AutomationAssumeRole=arn:aws:iam:: <ACCOUNT_ID>:role/<AUTOMATION_SERVICE_ROLE_NAME>, InstanceType=m3.large, CustomCommands=[yum -y install python35-devel python35-pip, /usr/bin/python35 -m pip install boto3]” –region us-east-1

这里,我把SourceAmiId参数指定了“ ami-4fffc834”,并无其他含义,只因为它是该文章发布时us-east-1(N. Virginia)地区中最新的Amazon Linux AMI。 它还具有EMR定制AMI所需的所有要求。 如果要在其他区域中运行Automation文档,请将SourceAmiId参数设置为在该特定区域中可用的AMI(例如:us-west-2为“ ami-aa5ebdd2”)。

4)查找有关Automation执行的详细信息

Automation执行完成后,除了每个步骤的状态及其输出之外,您还可以查看已执行的步骤。 可以运行以下命令,查看使用“ customEmrAmiDocument”文档的所有Automation执行情况:

$ aws ssm describe-automation-executions –query ‘AutomationExecutionMetadataList[?DocumentName==`customEmrAmiDocument`]’ –region us-east-1

要收集指定Automation执行的详细信息,请将前面命令中返回的AutomationExecutionId参数值,填入下面命令中:

$ aws ssm get-automation-execution –region us-east-1 –automation-execution-id <AutomationExecutionId>

上述命令的输出,包含该Automation所执行过程的每个步骤的详细信息。 运行以下命令,可以轻松查找在自动化createImage步骤中创建的AMI的AMI ID / imageID:

$ aws ssm get-automation-execution –region us-east-1 –automation-execution-id <AutomationExecutionId> –query ‘AutomationExecution.StepExecutions[?StepName==`createImage`]’

如果Automation执行失败,则可能需要手动停止实例或禁用在Automation执行过程中启动的服务。 有关更多信息,请参见Automation CLI演练和《 Systems Manager自动化疑难解答》

5)使用自定义AMI启动EMR集群

完成上述步骤后,您现在就有了可用于EMR的自定义Amazon Linux AMI。 有关更多信息,请参阅使用自定义AMI

可以使用以下命令通过AWS CLI启动EMR集群:

$ aws emr create-cluster –name “Cluster with My Custom AMI” –custom-ami-id <custom_AMI_ID> –ebs-root-volume-size 20 –release-label emr-5.8.0 –use-default-roles –instance-count 2 –instance-type m3.xlarge –ec2-attributes

有关如何查找由Automation创建的自定义AMI的AMI ID的信息,请参阅步骤4。

Run CommandEMR结合使用

在本节中,我将说明如何使用“Run Command”将命令发送到正在运行的EMR群集的节点。下图概述了“Run Command”执行过程:

 

1)为Systems Manager配置实例IAM角色

EC2实例(EMR群集节点)需要IAM角色才能与Systems Manager API通信。 因为EMR已经为每个群集节点分配了IAM角色(通常称为EMR_EC2_DefaultRole),所以您可以将附加的托管策略(系统管理器策略)附加到该角色。

以下命令将“ AmazonEC2RoleforSSM”托管策略附加到EMR_EC2_DefaultRole角色:

$ aws iam attach-role-policy –policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM –role-name EMR_EC2_DefaultRole

如果您没有使用默认的EC2角色,则将 role-name参数值替换为您用于该角色的角色名称。

有关为Systems Manager配置IAM角色和策略的详细信息,请参阅为Systems Manager配置安全角色

2)安装SSM代理

如果您的自定义AMI是由Automation创建的,请跳过此步骤。 默认情况下,用于创建定制AMI的customEmrAmiDocument Automation文档将安装SSM代理。

Systems Manager(SSM)代理用于处理System Manager请求,并按照请求中的指定内容,配置您的实例。 有关更多信息,请参阅在Linux上安装SSM代理

3)使用Run Command运行命令

现在,您应该能够在运行了SSM代理并且配置了SSM的IAM角色的实例上运行命令或Linux脚本(本节中的步骤1)。 要查看准备接收命令的实例列表,请运行以下命令:

$ aws ssm describe-instance-information –output json –query “InstanceInformationList[*]” –region us-east-1

向所有群集节点发送命令的最简单方法是使用资源标签作为Run Command的目标。 如果在启动过程中未将任何标签添加到EMR群集,则可以使用以下命令添加标签:

$ aws emr add-tags –resource-id <EMR_CLUSTER_ID> –tags environment=”emr-ssm” –region us-east-1

前面的命令将标签添加到EMR群集。 标签的键是“environment”,值是“ emr-ssm”。 您现在可以使用标签作为目标发送命令:

$ aws ssm send-command –document-name “AWS-RunShellScript” –targets ‘{“Key”:”tag:environment”,”Values”:[“emr-ssm”]}’ –parameters ‘{“commands”:[“hostname -f”,”python3 -V”]}’ –timeout-seconds 60 –region us-east-1

前面的命令将发送(executed)到具有以下标记的所有EC2实例:environment =“ emr-ssm”。

4)查看Run Command执行的详细信息

对于在上一步中执行的运行命令(send-command),Run Command执行的命令是,显示实例的主机名(hostname -f)及其Python 3版本(python3 -V)。

执行Run Command(send-command)后,它应在输出中返回“ CommandID”字段。 您可以使用该命令ID来收集有关命令发送到的实例的信息,并查看命令执行的状态:

$ aws ssm list-command-invocations –command-id <command_id> –region us-east-1

您还可以查看在特定EC2实例中由Run Command执行的命令的输出(在我们的示例中为’hostname -f’和’python3 -V’):

$ aws ssm get-command-invocation –command-id <command_id> –instance-id <instance_id> –query “StandardOutputContent” –region us-east-1

前面的命令返回类似于以下内容的内容:

“ip-xxxxxxxxxx\nPython 3.5.1\n”

有关使用Run Command运行命令和Shell脚本的更多信息,请参见Systems Manager运行命令

结论

这篇文章向您展示了为Amazon EMR使用自定义AMI的一些好处,以及如何使用Automation来自动化的管理和创建自定义AMI。 我还展示了如何使用Run Command来发送命令并在运行的EMR集群的所有节点上进行配置更改。

如果您有任何疑问或建议,请在下面评论。

 


附加阅读

了解如何在Amazon EMR上运行Jupyter Notebook和JupyterHub

 


关于作者

Bruno Faria 是 AWS 的 EMR 解决方案架构师。 他与我们的客户合作,为他们在 Amazon EMR 上运行复杂应用程序提供架构方面的指导。在业余时间,他喜欢与家人共度时光和学习新的大数据解决方案。