【问题标题】:AWS autoscaling starts not ready instances because of userdata script由于 userdata 脚本,AWS 自动缩放启动未准备好的实例
【发布时间】:2016-02-10 10:33:31
【问题描述】:

我有一个效果很好的自动缩放,在启动配置中我定义了一个在新实例启动时执行的用户数据脚本。

用户脚本更新基本代码并生成缓存,这需要几秒钟。但只要实例“创建”(而不是“准备好”),自动缩放就会将其添加到负载均衡器中。

这是一个问题,因为在执行 userdata 脚本时,实例没有给出良好的响应(基本上会抛出 500 个错误)。

我想避免这种情况,当然我看到了这个文档:http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/InstallingAdd

与独立 EC2 实例一样,您可以选择使用用户数据配置启动到 Auto Scaling 组的实例。例如,您可以使用 AWS 管理控制台中的用户数据字段或 AWS CLI 中的 --userdata 参数指定配置脚本。

如果您有无法使用配置脚本安装的软件,或者如果您需要在 Auto Scaling 将实例添加到组之前手动修改软件,请向您的 Auto Scaling 组添加生命周期挂钩,以便在Auto Scaling 组启动实例。当您安装和配置附加软件时,此挂钩将实例保持在 Pending:Wait 状态。

看起来我不是这种情况。此外,修改 userdata 脚本上的挂起钩子也很复杂。必须有一个简单的解决方案来解决我的问题。

感谢您的帮助!

【问题讨论】:

  • 我不确定我是否理解这是一个问题。当实例被“创建”并且 Autoscale 将其添加到 ELB 时,ELB 将测试该实例,并且该实例需要通过您配置的运行状况检查次数,然后 ELB 才能使其可用。然后,您当然需要进行健康检查,以便在您的用户数据脚本执行时它会失败。
  • 您的意思是当用户数据未完全执行时,aws 认为实例“健康”?
  • EC2 在 VM 运行后认为实例“健康”(即当操作系统启动时,AMI 已完全启动等)。它不考虑正在完成的 userdata 命令。例如,我经常通过 SSH 连接到一个新实例,跟踪日志文件并在执行 userdata 命令时观察它们的输出。但是,除此之外,ELB 不会认为实例健康并开始向其发送流量,直到它通过您在启动 ELB 时配置的健康检查。所以,这就是你需要关注的地方。
  • 谢谢。我通过在 userdata 脚本开始时关闭 http 服务器解决了我的问题。所以负载均衡器不能有绿色的健康状态,它不会将客户端发送到实例。我在脚本结束时重新启动了http服务器,健康状况良好,因此ELB为其提供服务。

标签: amazon-web-services amazon-ec2


【解决方案1】:

EC2 实例 Userdata 不会使用生命周期挂钩来阻止新启动的实例投入使用,直到它完成执行。

在您的用户数据脚本开始时停止您的网络服务器对我来说听起来有点不可靠,因此我强烈建议您利用 AutoScaling 提供的旨在解决这个问题的功能。

我有两个建议:

  • 选项 1:

    阅读docs 后,使用生命周期挂钩一点也不复杂。并且在您的用户数据中,您可以轻松地使用 CLI 来控制挂钩,检查 this 即可。事实上,可以从任何受支持的语言或脚本语言控制挂钩。

  • 选项 2:

    如果手动处理生命周期挂钩对您没有吸引力,那么我建议您废弃您的用户数据脚本并使用 AWS CodeDeploy 解决问题。您可以让 CodeDeploy 什么都不部署(例如空的 S3 文件夹),但您可以使用部署挂钩脚本来替换您的用户数据脚本。 Code Deploy 与 AutoScaling 无缝集成并自动处理生命周期挂钩。在部署成功之前,AutoScaling 不会将新启动的实例投入使用。阅读文档herehere 了解更多信息。

但是,我强烈建议您选择选项 1。生命周期挂钩旨在解决您遇到的问题。它们功能强大、强大、令人敬畏且免费。使用它们。

【讨论】:

  • 生命周期使用起来很复杂,因为您不能确保从 SQS 中检索到当前实例的好消息。可能有一种解决方法,例如将您在当前实例中不关心的消息重新放入队列,但是并发呢? :/ 所有这些问题引导我找到另一个解决方案,即简单地使用健康状态。
  • 正如我在回答中所说,生命周期挂钩并不难使用。请阅读文档并熟悉核心概念。我不知道你在谈论什么关于 SQS,你在这篇文章的其他任何地方都没有提到 SQS。也许您需要详细说明您的特定用例?使用已经构建和设计的工具来解决您的问题,不要重新发明轮子。我敦促您遵循文档并尝试使用生命周期挂钩测试解决方案。
  • 我不想使用代码部署进行部署:我们有一个复杂的部署过程和一个已经运行良好的部署脚本(使用结构和 boto),代码部署也不是免费的,所以改为付费对于意味着双重成本的解决方案(我说的是开发成本)并不是一个真正好的解决方案。另外,我知道该文档(正如我在第一篇文章中所说),并且我尝试使用 SQS 使用生命周期挂钩(主题订阅看起来像一个笑话解决方案,因为它在其最佳解决方案上重定向到 SQS)。这就是我的问题:我没有看到任何简单的方法来处理并发、SQS 和生命周期钩子。
  • EC2 的代码部署是免费的。您在问题中没有提到并发或 SQS。您应该使用更多关于您的情况的信息来更新它,并准确描述您想要实现的目标。
【解决方案2】:

@Brooks 说在 ELB 服务实例之前“等待”的最简单方法是处理 ELB 健康状态。

我通过在 userdata 脚本开始时关闭 http 服务器解决了我的问题。所以 ELB 不能有绿色健康状态,它不会向实例发送客户端。我在脚本结束时重新启动了http服务器,健康状况良好,因此ELB为其提供服务。

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 2017-03-17
    • 2019-10-09
    • 1970-01-01
    • 2015-03-18
    • 2016-04-04
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    相关资源
    最近更新 更多