无需任何杀戮任务的纵向广告工作者

时间:2017-06-09 14:14:55

标签: amazon-web-services continuous-integration autoscaling continuous-delivery concourse

每个工作人员都会执行多项任务。如果我们有很多任务,我们就需要多个工人。为了节省资源,我们希望根据供应(备用容量)和需求(待定任务)对工人进行弹性扩展。

扩展很容易:添加更多节点,他们使用TSA注册并开​​始工作。

缩放比较棘手:在杀死工作人员的实例之前,需要等待其任务完成。否则他们将不得不重新开始另一个工人。这对于小型任务来说很好,但对于较长的那些可能是不可接受的。

AWS上的一个可能的解决方案是使用Autoscaling Lifecycle Hooks同步告诉工作人员不接受任何更多任务并在完成所有任务后返回,然后将其终止。 Concourse Worker API虽然没有任何此类操作。

有没有办法在Concourse工作人员中实现安全扩展?

如果答案是"不要担心,波什会照顾它"我想知道那些机制是什么,因为我可能不会使用它。

2 个答案:

答案 0 :(得分:1)

您必须在运行ATC的主机(即广告调度程序和Web界面)上使用命令行中的concourse二进制文件:

concourse --help
Usage:
  concourse [OPTIONS] <command>

Application Options:
  -v, --version  Print the version of Concourse and exit [$CONCOURSE_VERSION]

Help Options:
  -h, --help     Show this help message

Available commands:
  land-worker    Safely drain a worker's assignments for temporary downtime.
  retire-worker  Safely remove a worker from the cluster permanently.
  web            Run the web UI and build scheduler.
  worker         Run and register a worker.

所以看起来你可以挂钩Autoscaling Lifecycle服务,一旦你找出哪个工人,就会调用land-worker然后调用retire-worker(不确定retire-worker是否足够)你想减速......

当你把同一个工人旋转回来时,你可能不得不小心工人的名字,我似乎记得有时ATC会感到困惑,你将不得不试验(无论你是否可以保持相同的名字或改变它)。

答案 1 :(得分:1)

您可以在Concourse工作人员ASG上创建Lifecyle挂钩:

    Type: AWS::AutoScaling::LifecycleHook
    Properties:
      AutoScalingGroupName: !Ref ConcourseWorkerASG
      DefaultResult: CONTINUE / ABANDON
      HeartbeatTimeout: 900 # 15 minutes for example
      LifecycleHookName: lchname
      LifecycleTransition: "autoscaling:EC2_INSTANCE_TERMINATING"

使用脚本退休工人,类似

lch.sh

#!/bin/bash

TYPE=$(cat /opt/concourse/type)
tsa_host=zz
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id/)
lifecycleState=$(aws autoscaling describe-auto-scaling-instances --instance-ids $instance_id --query 'AutoScalingInstances[0].LifecycleState' --output text --region eu-west-1)

if [ "$TYPE" == "worker" ]; then
  if [ "$lifecycleState" == "Terminating:Wait" ]; then
    asg=$(aws autoscaling describe-auto-scaling-instances --instance-ids $instance_id --query 'AutoScalingInstances[0].AutoScalingGroupName' --output text --region eu-west-1)

    /opt/concourse/concourse/bin/concourse retire-worker \
        --name $HOSTNAME \  
        --tsa-host ${tsa_host}:2222 \
        --tsa-public-key some_tsa_host_key.pub \
        --tsa-worker-private-key some_worker_key

    sleep 5m

    systemctl stop your_concourse_service

    aws autoscaling complete-lifecycle-action \
      --instance-id $instance_id \
      --auto-scaling-group-name $asg \
      --lifecycle-hook-name "lchname" \
      --lifecycle-action-result "CONTINUE" \
      --region eu-west-1
  fi
fi

然后安排一次cronjob,例如通过Ansible:

- name: List lch.sh as cronjob
  cron:
    name: "check asg lch for retiring the worker"
    minute: "*/5" # run every 5 minutes
    job: "/opt/concourse/lch.sh"