如何将EC2+EBS 标准实例迁移为竞价实例?

如何将EC2+EBS 标准实例迁移为竞价实例?

我一直在使用 EC2 竞价实例,最终目的是将托管网站的标准实例迁移到竞价实例(是的,我很清楚这实际上不是竞价实例的用途,但在这种情况下,我准备用价格换取可用性)。

然而,我有点惊讶地发现,当超过价格门槛时,现货实例会被终止,而不是停止,而且实际上根本不可能停止现货实例,而只能终止它。

那么:是否有某种(推荐的)方法可以让现货实例请求生成的实例在创建时简单地与特定的EBS卷关联,以便可以简单地将整个机器状态向前滚动到一系列现货实例中? 或者我从根本上误解了现货实例的全部含义?

答案1

首先,请允许我澄清几点。正如您所指出的,竞价实例并非全天候运行 - 它们旨在以较低的成本在短时间内提供额外的计算能力。本质上,它们适用于可以分解成小部分的任务 - 因此终止实例不会对整体任务产生重大影响。

话虽如此,我之前曾使用现货请求模型运行过一个实例 - 它的正常运行时间通常约为 3 个月 - 而且我通常会以高于平均市场价格 15 倍的价格出价。虽然这曾经是一种相当划算的方法,但我发现,随着越来越多的人采用相同的技术,价格波动性增加到不再比预留实例更具优势的程度。

平均现货价格往往徘徊在中等利用率预留实例的每小时成本附近。根据当前现货价格与高利用率实例进行计算,可得出以下结果:

+-------------+-----------------------------+------------------------------+----------+
|             |           1 year            |            3 year            |   Spot   |
+-------------+-----------------------------+------------------------------+----------+
| Small       | $0.016/h + $195 = $0.0383/h | $0.013/h +$300 = $0.0244/h   | $0.027/h |
| Medium      | $0.032/h + $390 = $0.0765/h | $0.026/h+$600 = $0.0488/h    | $0.038/h |
| Large       | $0.064/h + $780 = $0.153/h  | $0.052/h + $1200 = $0.0977/h | $0.108/h |
| Extra Large | $0.128/h + $1560 = $0.306/h | $0.104/h + $2400 = $0.195/h  | $0.216/h |
+-------------+-----------------------------+------------------------------+----------+

显然,在很多情况下,3 年高利用率预留实例的价格低于当前现货价格(易波动)。根据我的经验,实际平均现货价格往往比基准市场价格高出至少 50%,因为大幅上涨并不罕见。

现在,尝试回答您的问题:

您说得对,竞价型实例无法停止 - 在某种程度上,这确实符合竞价型实例背后的整个前提。传统上,实例将从快照中创建它正在使用的 EBS 卷,但可以编写附加 EBS 卷的过程的脚本。我曾经使用此脚本在 RAID0 中设置 2 个 EBS 卷(我很确定我从找到的某个脚本中修改了它,但目前我找不到原始脚本):

#! /bin/sh 
# 
# /etc/init.d/mountec2vol 
# 
# chkconfig: 234 20 50 
# description: Assigns an EC2 EBS Volume to a device and mounts the device 
# 
# To add this as a service run: 
# /sbin/chkconfig --add mountec2vol 
# 
# VARS 
# 
VOL1="vol-xxxxxxxa" 
VOL2="vol-xxxxxxxb" 
DEV1="/dev/sdh1" 
DEV2="/dev/sdh2" 
MOUNT_POINT="/raid" 

export PS1="[\T] [\W]# "
export JAVA_HOME=/usr/java/jre1.6.0_16
export EC2_HOME=/etc/ec2/apitools
export PATH=$PATH:$EC2_HOME/bin
export EC2_PRIVATE_KEY=/root/.ec2/pk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem 
export EC2_CERT=/root/.ec2/cert-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem

MAX_TRIES=10 

# start/stop functions for OS 

start() { 
touch /var/lock/subsys/mountec2vol
INSTANCE=`curl http://169.254.169.254/latest/meta-data/instance-id 2> /dev/null` 
CTR=0 
/bin/echo "Mounting Elastic Block Store Volumes." 
ec2-attach-volume $VOL1 -i $INSTANCE -d $DEV1 
while [ ! -e "$DEV1" ]; do 
/bin/sleep 1 
CTR=`expr $CTR + 1` 
if [ $CTR -eq $MAX_TRIES ] 
then 
/bin/echo "WARNING: Cannot attach volume $VOL1 to $DEV1 -- Giving up after $MAX_TRIES attempts" 
exit 1 
fi 
done 
ec2-attach-volume $VOL2 -i $INSTANCE -d $DEV2
while [ ! -e "$DEV2" ]; do 
/bin/sleep 1 
CTR=`expr $CTR + 1` 
if [ $CTR -eq $MAX_TRIES ] 
then 
/bin/echo "WARNING: Cannot attach volume $VOL2 to $DEV2 -- Giving up after $MAX_TRIES attempts" 
exit 1 
fi 
done 
depmod -a
modprobe raid0
mdadm --assemble --verbose /dev/md0 /dev/sdh1 /dev/sdh2
if [ ! -d $MOUNT_POINT ]; then 
mkdir $MOUNT_POINT 
fi 
/bin/mount /dev/md0 $MOUNT_POINT 
} 

stop() { 
/bin/echo "Unmounting Elastic Block Store Volumes." 
rm -f /var/lock/subsys/mountec2vol 
/bin/umount $MOUNT_POINT
mdadm -S /dev/md0
ec2-detach-volume $VOL1
ec2-detach-volume $VOL2
} 


case "$1" in 

start) 
start 
;; 

stop) 
stop 
;; 
restart) 
stop 
sleep 5 
start 
;; 
*) 
echo "Usage: $0 {start|stop|restart}" 
exit 1 

esac 

exit 0 

这是针对 CentOS 的,但我认为它很容易适应大多数其他 Linux。更改 Java 版本并删除 RAID 属性(并更改挂载点),您就可以开始了。然后,这将被设置为在实例启动时运行的初始化脚本。实现此目的的另一种方法是将 EBS 卷 ID 作为实例用户数据传递,这将提供更大的灵活性。

需要注意的是,这当然不适用于根 EBS 卷 - 此设置假定根卷基本固定,数据保存在单独的挂载点上。您始终可以从以下位置设置 EBS 根卷ec2-request-spot-instances使用--block-device-mapping范围。

答案2

您正在寻找的内容可以通过使用来实现他们的 API,我认为不可能使用 Amazon 提供的自动化功能来完成此操作。您必须自己编写。完全可以编写脚本来创建新的 Spot 实例,并将特定的 EBS 卷与其关联。

您无法做的是迁移完整的机器状态,您仍然会遇到停机以启动新的现货实例。

答案3

查看https://github.com/atramos/ec2-spotter

摘自自述文件:

EC2-Spotter 是一款集两全其美于一身的实用工具——竞价型实例定价与按需和预留实例的简单性(持久性 EBS 文件系统)。这听起来像是作弊,但显然亚马逊的服务条款并不禁止。

相关内容