如何在AWS自动缩放组的一台机器上执行bash脚本任务?

如何在AWS自动缩放组的一台机器上执行bash脚本任务?,bash,amazon-web-services,amazon-ec2,autoscaling,Bash,Amazon Web Services,Amazon Ec2,Autoscaling,我最近遇到了一个场景,在这个场景中,我需要确保自动缩放组中只有一台机器在所有机器频繁运行的bash脚本中执行给定的任务 简言之,我需要某种领导人选举,避免两台机器执行相同的任务,以适应新机器的启动和停止。我最终实现了两件事: 使用AWS CLI()查找属于自动缩放组的所有计算机,并选择ID最小的计算机 使用EC2实例元数据()获取当前实例ID 比较两者以确定是否运行该任务 #!/bin/bash AUTOSCALING_GROUP="mygroup" die() { status=$1;

我最近遇到了一个场景,在这个场景中,我需要确保自动缩放组中只有一台机器在所有机器频繁运行的bash脚本中执行给定的任务


简言之,我需要某种领导人选举,避免两台机器执行相同的任务,以适应新机器的启动和停止。

我最终实现了两件事:

  • 使用AWS CLI()查找属于自动缩放组的所有计算机,并选择ID最小的计算机
  • 使用EC2实例元数据()获取当前实例ID
  • 比较两者以确定是否运行该任务

    #!/bin/bash
    
    AUTOSCALING_GROUP="mygroup"
    
    die() { status=$1; shift; echo "FATAL: $*"; exit $status; }
    THIS_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
    LEADER_INSTANCE_ID="`aws --region us-east-1 ec2 describe-instances --filters "Name=tag:aws:autoscaling:groupName,Values=$AUTOSCALING_GROUP" "Name=instance-state-name,Values=running" | grep -o '\"i-[0-9a-f]\\+\"' | grep -o '[^\"]\\+' | sort | head -n 1 || die \"could not list autoscaling group instances: $?\"`"
    
    if [ "$THIS_INSTANCE_ID" == "$LEADER_INSTANCE_ID" ]
    then
       echo "I'm it!"
    else
       echo "I'm not it!"
    fi
    

这是非常简单的,因为脚本是在cron上定期运行的,并且错过几次执行或最终多次执行任务并不是灾难性的(只会产生不必要的成本)。如果您确实需要同步以确保只有一台计算机同时执行任务,那么您将需要比这更复杂的东西。

如果终止了一个“更高”(非权限)的实例,并生成了一个“新的最低”(新权限)的实例来替换它,该怎么办?这在cron定期调用的脚本中使用,对于一项任务来说,如果少执行几次,就不会导致灾难性的失败。如果机器启动和停止,脚本的下一次执行仍将仅选择当时ID最低的正在运行的机器。添加注释以更清楚地说明此方法的限制。