我想创建一个 ASG,以便我可以将现有的 EBS 卷(因为我在这些卷上有持久数据)重用到通过 ASG 实例化的新 EC2 实例。这可能吗?
从评论中复制更新
为了澄清我最初的问题,我并不是想同时将一个 EBS 卷附加到两个 EC2 实例。相反,当一个 EC2 实例终止时,我想使用之前的 EBS 卷启动一个新的 EC2 实例,而不是创建一个全新的 EBS 卷
答案1
不。
自动扩展组启动多个 EC2 实例。每个 EBS 卷只能附加到一个 EC2 实例。因此您不应该这样做,而且这可能是不可能的。如果您有多个卷和多个实例,您可能可以实现一些复杂的逻辑来使其工作,但您不应该这样做 - 简单的架构往往是最好的。
您可以运行一个 EC2 实例,通过 ASG 访问的 NFS 共享数据,或者您可以使用AWS 弹性文件系统,但要注意延迟相对较高。
如果您扩展您的要求和用例,您可能会得到更多有用的答案。
更新
根据附加要求,这可能是可行的。这不是标准要求,所以我认为没有任何明确的支持。
我可能会考虑编写某种启动脚本,将卷与 EC2 实例关联,然后挂载它。有一个在这里回答这可能会有些用处。使用 SNS 和 Lambda 进行某种设置可能可行,但 EC2 实例可能仍需要运行某些程序来映射卷。
其他人也许可以给你提供更多信息,我从来没有做过这样的事情。
答案2
在我看来,你可以尝试这样做(我做了类似的事情,但使用了弹性网络接口)。这假设你了解 AWSCloudFormation
服务或AWS CLI
:
- 创建 EBS 卷
- 创建一个
AutoScaling group
最小/最大尺寸设置为 1 的裸实例。这将确保当实例变得不健康时,唯一会被新的健康实例所取代。 UserData
从AutoScaling 资源部分将卷附加到实例LaunchConfiguration
。- 现在,当实例终止时,卷会发生什么情况?AutoScaling 组将启动一个新的卷。该卷将保持连接/使用状态,直到旧卷终止。然后,该卷将再次可用,并且可以连接到新实例。
- 附加/重新附加卷更多的是关于此类操作的时间安排。您可以盲目地假设
UserData
将在卷再次可用后执行(实例是否会“快速”终止?)。或者您可以进行一些状态检查,例如描述卷元数据,检查其状态并在未使用时重新附加它。
Linux bash shell 中的一个简单示例:
INST_ID='i-xyzxyzxyz'
VOL_ID='vol-xyzxyzxyz'
VOL_STATUS=''
until [[ $VOL_STATUS == '"available"' ]]; do
VOL_STATUS=$(aws ec2 describe-volumes --volume-ids $VOL_ID --query 'Volumes[0].State')
sleep 5
done
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $INST_ID --device /dev/sdh
- 如果你希望它更具弹性,你可以尝试使用AutoScaling 生命周期挂钩在实例进入
InService
状态之前,您可以附加卷。它将保持此状态,直到您告诉组继续(否则默认情况下它有 1 小时的超时时间)。这适用于扩展事件或启动新实例时。当它被终止或缩减时,它也可以等待信号。您可以分离卷并发出信号让它继续终止它。 - 所有
AWS CLI
命令都假定您的实例已附加适当的 IAM 实例配置文件,该配置文件允许附加/分离 EBS 卷或描述它们。
答案3
如果您的要求仅仅是在 ASG 实例之间共享数据,那么您应该继续遵循以下文章:
一旦您拥有可用的共享/多挂载 EBS 卷,请确保所有应用程序数据都位于其挂载点上。因此,下次从 ASG 启动实例时,应在该挂载点获取相同的数据。
但是,托管的应用程序必须支持共享文件系统方法,或者至少其配置的大多数应该能够位于共享文件系统上。如果应用程序创建了锁文件,则这可能不起作用。
如果你只想保留具有基本应用程序配置(无运行时/动态数据)的映像,则可以选择从已完成应用程序配置的 EC2 实例创建自定义 AMI,然后在 ASG 中使用它