本文最后更新于 2024-05-25,

若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益, 请联系我 删除。

本站只有Telegram群组为唯一交流群组, 点击加入

文章内容有误?申请成为本站文章修订者或作者? 向站长提出申请

使用阿里云脚本自动重建抢占式实例

为什么使用抢占式实例,如何使用及创建抢占式实例,你可以参考这篇文章https://poiblog.com/archives/ZMDTDA1c

如果抢占式实例被回收删除,没有绑定的空IP在持续收费的解决方法

https://poiblog.com/archives/KMhtbgEh

以下是实现思路

首先

1716485652397.webp1716485588116.webp

阿里云的快照在使用5G内是不收费的,超过5G一个月是1毛左右。然后创建完快照后参考以下参数使用Aliyun-Cli写好脚本并且设置定时任务。

如果系统自带的镜像太大了,你可以在本站内搜索dd系统相关文章,我是dd到了debian12系统,占用空间仅为1G左右。

1716485656082.webp1716485660013.webp

优惠筛选

抢占式实例每小时价格超过2分钱就不要了,通过判断条件进行下单。

1716485573545.webp

实例创建参数

1716485640370.webp

    # 创建新的实例
    instance_id=$(aliyun ecs RunInstances \
        --RegionId $regionId \
        --VSwitchId $vswitchId \
        --ZoneId $zoneId \
        --InstanceType $instanceType \
        --SpotDuration 0 \
        --SpotStrategy SpotAsPriceGo \
        --ImageId $imageId \
        --SystemDisk.Size 20 \
        --SecurityGroupId $securityGroupId \
        --KeyPairName public)

脚本写完,设置定时任务监控阿里云状态即可

脚本

#!/bin/bash

# 定义区域列表
zones=("cn-hongkong-b" "cn-hongkong-c" "cn-hongkong-d")
regionId="cn-hongkong"
instanceType="ecs.n1.tiny"
imageId=""
securityGroupId=""
eipId=""
VSwitchId=""
keyPairName=""

# 初始化变量
selectedZone=""
lowestPrice=0.02
instanceId=""
bVSwitch=""
cVSwitch=""
dVSwitch=""


# 安装阿里云cli
installAliyun() {
    if ! command -v aliyun &>/dev/null; then
        echo "aliyun-cli 未安装,正在安装..."
        if which yum &>/dev/null; then
            yum install -y wget unzip
        elif which apt-get &>/dev/null; then
            apt-get update && apt-get install -y wget unzip
        else
            echo "不支持的操作系统,程序退出。"
            exit 1
        fi

        wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz -O /tmp/aliyun-cli.tgz
        tar xvzf /tmp/aliyun-cli.tgz -C /tmp/
        mv /tmp/aliyun /usr/local/bin/
        rm /tmp/aliyun-cli.tgz
    fi
    echo "aliyun-cli 已安装。"
}

# 配置Aliyun
configureAliyun() {
    read -p "请输入阿里云 Access Key ID: " access_key_id
    read -p "请输入阿里云 Access Key Secret: " access_key_secret
    read -p "请输入快照编号(m-j6chafxxxxfxpji): " imageId
    read -p "请输入已有安全组(sg-j6cixxxxt2523): " securityGroupId
    read -p "请输入EIP编号(eip-j6cutxxxxxxhxex): " eipId
    read -p "请输入B区虚拟交换机编号(vsw-j6xxxxusx): " bVSwitch
    read -p "请输入C区虚拟交换机编号(vsw-j6xxxxusx): " cVSwitch
    read -p "请输入D区虚拟交换机编号(vsw-j6xxxxusx): " dVSwitch
    read -p "请输入密钥名称: " keyPairName
    aliyun configure set --profile default \
        --access-key-id "$access_key_id" \
        --access-key-secret "$access_key_secret" \
        --region "$regionId"
}

# 计算B C D三个区域的抢占实例的价格,并获取低于0.02的区域,并且根据区域赋值VSwitchId
getLowestPrice() {
    for zoneId in "${zones[@]}"; do
        echo "查询区域: $zoneId"

        # 运行 DescribePrice 命令
        response=$(aliyun ecs DescribePrice --RegionId $regionId --ImageId $imageId --InstanceType $instanceType --SystemDisk.Size 20 --SpotStrategy SpotAsPriceGo --SpotDuration 0 --ZoneId $zoneId)

        # 解析 TradePrice
        tradePrice=$(echo $response | jq -r '.PriceInfo.Price.TradePrice')

        echo "TradePrice: $tradePrice"

        # 判断 TradePrice 是否低于 0.02
        if (($(echo "$tradePrice < 0.02" | bc -l))); then
            selectedZone=$zoneId
            lowestPrice=$tradePrice
            echo "找到低于0.02的区域: $zoneId, TradePrice: $tradePrice"
            break
        fi
    done

    # 输出结果
    if [ -n "$selectedZone" ]; then
        echo "选择的区域是: $selectedZone, TradePrice: $lowestPrice"
    else
        echo "没有找到TradePrice低于0.02的区域"
    fi
}

# 根据区域设置VSwitchId
setVSwitchId() {
    # 根据zoneid决定VSwitchId的值
    if [ "$selectedZone" = "cn-hongkong-b" ]; then
        VSwitchId=$bVSwitch
    elif [ "$selectedZone" = "cn-hongkong-c" ]; then
        VSwitchId=$cVSwitch
    elif [ "$selectedZone" = "cn-hongkong-d" ]; then
        VSwitchId=$dVSwitch
    else
        echo "未知的区域: $selectedZone"
        exit 1
    fi
}

# 根据最低价区域创建抢占式实例
createInstance() {
    # 计算出低于0.02的区域
    getLowestPrice
    # 设置VSwitchId
    setVSwitchId
    resultJson=$(aliyun ecs RunInstances \
        --RegionId $regionId \
        --VSwitchId $VSwitchId \
        --ZoneId $selectedZone \
        --InstanceType $instanceType \
        --SpotDuration 0 \
        --SpotStrategy SpotAsPriceGo \
        --ImageId $imageId \
        --SystemDisk.Size 20 \
        --SecurityGroupId $securityGroupId \
        --KeyPairName $keyPairName)

    # 使用 jq 提取 resultJson 并赋值给 shell 变量 instanceId
    instanceId=$(echo "$resultJson" | jq -r '.InstanceIdSets.InstanceIdSet[0]')

    if [ -z "$instanceId" ]; then
        echo "实例创建失败。"
        exit 1
    fi
    echo "实例创建成功,实例ID:$instanceId"
}

# 绑定Eip到实例上
bindEipAddress() {
    createInstance
    aliyun ecs AssociateEipAddress \
        --RegionId $regionId \
        --InstanceId $instanceId \
        --AllocationId $eipId
}

# 检查实例是否存在
checkInstanceAlive() {
    while true; do
        # 查询实例状态
        response=$(aliyun ecs DescribeInstances --RegionId cn-hongkong)

        # 检查TotalCount是否为0
        if [ "$(echo "$response" | jq '.TotalCount')" -eq 0 ]; then
            # 如果TotalCount为0,则调用重建脚本
            echo "实例已被删除,开始重建..."
            bindEipAddress
        else
            echo "实例存在,无需重建"
        fi
        # 等待30秒
        sleep 30
    done
}

# 主函数
echo "欢迎使用Sm1rkBoy's Aliyun删鸡重建脚本"
echo "请选择操作:"
echo "  1) 安装阿里云Cli"
echo "  2) 配置阿里云Cli"
echo "  3) 创建抢占实例"
echo "  4) 检查实例是否存在(死循环可以使用screen)"
echo "  0) 退出"
read -p "请选择操作 [0-4]: " choice

case $choice in
    1) installAliyun ;;
    2) configureAliyun ;;
    3) bindEipAddress ;;
    4) checkInstanceAlive ;;
    0) echo "退出。"; exit 0 ;;
    *) echo "错误"; exit 1 ;; # 在默认情况下添加退出语句
esac