全部产品
阿里云办公

使用云助手自动化管理实例

更新时间:2018-07-18 11:16:22

运维 ECS 实例的目的是保持 ECS 实例的最佳状态以及确保排错的效率,但是手动维护会花费您大量的时间和精力,因此阿里云研制了 云助手,用以解决如何自动化、批量处理日常维护任务。本文举例如何使用云助手 API,为 ECS 实例执行相应命令,达到自动化运维 ECS 实例的目的。

命令类型介绍

目前,云助手支持如下三种命令类型。

命令类型 参数 描述
Shell 脚本 RunShellScript 为运行中的 Linux 实例执行 Shell 脚本,命令内容为需要执行的 Shell 脚本内容。
PowerShell 脚本 RunPowerShellScript 为运行中的 Windows 实例执行 PowerShell 脚本,命令内容为需要执行的 PowerShell 脚本内容。
Bat 脚本 RunBatScript 为运行中的 Windows 实例执行 Bat 脚本,命令内容为需要执行的 Bat 脚本内容。

前提条件

  • 您需要确保目标 ECS 实例的网络类型为 专有网络(VPC)

  • 目标 ECS 实例的状态必须为 运行中Running)。

  • 目标 ECS 实例必须预先安装云助手客户端。您可以参阅 阿里云助手 安装并使用云助手客户端。

  • 执行类型为 PowerShell 的命令时,您需要确保目标 Windows 实例已经配置了 PowerShell 模块。

  • 以下示例在命令行工具中完成,您需要确保您已经安装了阿里云命令行工具 CLI(Command-Line Interface)。

  • 您需要 升级 SDK

  • 修改 CLI 配置:

    1. 下载文件 aliyunOpenApiData.py
    2. 使用下载的文件替换路径中 %python_install_path%\Lib\site-packages\aliyuncli 中的文件 aliyunOpenApiData.py。
      AliyunOpenApiData

关于如何配置阿里云 CLI,参阅文档 配置命令行工具和 SDK

操作步骤

以下举例说明怎么在阿里云 CLI 中通过 API 使用云助手,为 ECS 实例执行相应命令。以执行一条 echo 123 命令为例。

  1. 在本地计算机的 CMD、PowerShell 或者 Shell 中运行 aliyuncli ecs CreateCommand --CommandContent ZWNobyAxMjM= --Type RunShellScript --Name test --Description test 创建命令CreateCommand)。

    注意

    • CommandContent 中的 ZWNobyAxMjM= 是命令 echo 123 转化后的 Base64 码。关于 Base64 编码或者译码,您可以参阅 Wikipedia 相关介绍。Base64
    • 如果目标 ECS 实例为 Windows 实例,将 type 修改为 RunBatScript 或者 RunPowershellScript
    • 创建成功后,将返回 CommandId 信息。

    Example

  2. 运行 aliyuncli ecs InvokeCommand --InstanceIds your-vm-instance-id1 instance-id2 --CommandId your-command-id --Timed false 执行命令InvokeCommand)。

    注意

    • InstanceIds 为您的 ECS 实例 ID,支持多台 ECS 实例,最多 100 台。
    • Timed 表示是否为周期性任务,Timed True 表示是周期性任务,Timed False表示不是周期性任务。
    • 当您的任务为周期性任务时,即参数 Timed 取值为 True 时,您需要通过参数 Frequency 指定周期,例如 0 */20 * * * * 表示周期为每 20 分钟。更多关于 Cron 表达式详情,请参阅 Cron 表达式取值说明
    • 返回结果为所有的目标 ECS 实例返回一个共同的 InvokeId。您可以使用该 InvokeId 查询命令的执行情况。
  3. (可选)运行 aliyuncli ecs DescribeInvocations --InstanceId your-vm-instance-id --InvokeId your-invoke-id 查看命令执行状态DescribeInvocations)。其中,InvokeId第二步 为 ECS 实例执行命令时返回的执行 ID。

    返回参数 InvokeStatusFinished 时仅表示命令进程 执行完成,不代表一定有预期的命令效果,您需要通过 DescribeInvocationResults 中的参数 Output 查看实际的具体执行结果。

  4. (可选)运行 aliyuncli ecs DescribeInvocationResults --InstanceId your-vm-instance-id --InvokeId your-invoke-id 查看指定 ECS 实例的命令的实际执行结果DescribeInvocationResults)。其中,InvokeId第二步 为 ECS 实例执行命令时返回的执行 ID。

创建命令CreateCommand) 时,您还可以为命令设置如下请求参数。

命令属性 参数 描述
执行目录 WorkingDir 命令将在 ECS 实例中的什么路径下执行。默认值:
  • 对于 Linux 实例,默认在管理员 root 用户的 home 目录下,具体为 /root 目录。
  • 对于 Windows 实例,默认在云助手客户端进程所在目录,例如 C:\ProgramData\aliyun\assist\$(version)
超时时间 TimeOut 修改命令在 ECS 实例中执行时最大的超时时间,单位为秒。
当因为某种原因无法运行您创建的命令时,会出现超时现象;超时后,云助手客户端会强制终止命令进程,即取消命令的 PID。
参数取值必须大于等于 60,如果取值小于 60,默认为 60 秒。
默认值:3600
  • 单次执行
    • 超时后,该命令针对指定的 ECS 实例的执行状态(InvokeRecordStatus)变为执行失败(Failed)。
  • 周期执行
    • 周期执行的超时时间对每一次执行记录均有效。
    • 某次执行超时后,该次执行记录的状态(InvokeRecordStatus)变为执行失败(Failed)。
    • 上次执行超时与否不影响下一次执行。

通过 Python SDK 使用云助手的完整代码示例

您也可以通过 阿里云 SDK 使用云助手。关于如何配置阿里云 SDK,参阅文档 配置命令行工具和 SDK。以下为通过 Python SDK 使用云助手的完整代码示例。

  1. # coding=utf-8
  2. # if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
  3. # if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
  4. # make sure the sdk version is 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check
  5. import json
  6. import logging
  7. import os
  8. import time
  9. import datetime
  10. import base64
  11. from aliyunsdkcore import client
  12. from aliyunsdkecs.request.v20140526.CreateCommandRequest import CreateCommandRequest
  13. from aliyunsdkecs.request.v20140526.InvokeCommandRequest import InvokeCommandRequest
  14. from aliyunsdkecs.request.v20140526.DescribeInvocationResultsRequest import DescribeInvocationResultsRequest
  15. # configuration the log output formatter, if you want to save the output to file,
  16. # append ",filename='ecs_invoke.log'" after datefmt.
  17. logging.basicConfig(level=logging.INFO,
  18. format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
  19. datefmt='%a, %d %b %Y %H:%M:%S',filename='aliyun_assist_openapi_test.log', filemode='w')
  20. #access_key = 'Your Access Key Id'
  21. #acess_key_secrect = 'Your Access Key Secrect'
  22. #region_name = 'cn-shanghai'
  23. #zone_id = 'cn-shanghai-b'
  24. access_key = 'LTAIXXXXXXXXXXXX'
  25. acess_key_secrect = '4dZXXXXXXXXXXXXXXXXXXXXXXXX'
  26. region_name = 'cn-hangzhou'
  27. zone_id = 'cn-hangzhou-f'
  28. clt = client.AcsClient(access_key, acess_key_secrect, region_name)
  29. def create_command(command_content, type, name, description):
  30. request = CreateCommandRequest()
  31. request.set_CommandContent(command_content)
  32. request.set_Type(type)
  33. request.set_Name(name)
  34. request.set_Description(description)
  35. response = _send_request(request)
  36. if response is None:
  37. return None
  38. command_id = response.get('CommandId')
  39. return command_id;
  40. def invoke_command(instance_id, command_id, timed, cronat):
  41. request = InvokeCommandRequest()
  42. request.set_Timed(timed)
  43. InstanceIds = [instance_id]
  44. request.set_InstanceIds(InstanceIds)
  45. request.set_CommandId(command_id)
  46. request.set_Frequency(cronat)
  47. response = _send_request(request)
  48. invoke_id = response.get('InvokeId')
  49. return invoke_id;
  50. def get_task_output_by_id(instance_id, invoke_id):
  51. logging.info("Check instance %s invoke_id is %s", instance_id, invoke_id)
  52. request = DescribeInvocationResultsRequest()
  53. request.set_InstanceId(instance_id)
  54. request.set_InvokeId(invoke_id)
  55. response = _send_request(request)
  56. invoke_detail = None
  57. output = None
  58. if response is not None:
  59. result_list = response.get('Invocation').get('InvocationResults').get('InvocationResult')
  60. for item in result_list:
  61. invoke_detail = item
  62. output = base64.b64decode(item.get('Output'))
  63. break;
  64. return output;
  65. def execute_command(instance_id):
  66. command_str = 'yum check-update'
  67. command_id = create_command(base64.b64encode(command_str), 'RunShellScript', 'test', 'test')
  68. if(command_id is None):
  69. logging.info('create command failed')
  70. return
  71. invoke_id = invoke_command(instance_id, command_id, 'false', '')
  72. if(invoke_id is None):
  73. logging.info('invoke command failed')
  74. return
  75. time.sleep(15)
  76. output = get_task_output_by_id(instance_id, invoke_id)
  77. if(output is None):
  78. logging.info('get result failed')
  79. return
  80. logging.info("output: %s is \n", output)
  81. # send open api request
  82. def _send_request(request):
  83. request.set_accept_format('json')
  84. try:
  85. response_str = clt.do_action(request)
  86. logging.info(response_str)
  87. response_detail = json.loads(response_str)
  88. return response_detail
  89. except Exception as e:
  90. logging.error(e)
  91. if __name__ == '__main__':
  92. execute_command('i-bp17zhpbXXXXXXXXXXXXX')

相关链接

以上示例示范了如何通过阿里云 CLI 以及云助手 API CreateCommandInvokeCommandDescribeInvocationsDescribeInvocationResults 自动化运维 ECS 实例,您还可以使用云助手其他 API 便捷地管理您的 ECS 实例。