sgykfjsm.github.com

Beanstalk管理下のインスタンスを安全に再起動する

現在のBeanstalkでインスタンスが再起動する場合は主に以下の3つがある。

  • アプリケーションをデプロイするとき
  • Configuration(JVMのパラメータとか)をデプロイするとき
  • Management ConsoleなどでRestart Appsを実行した時

しかし、運用の中では特定のインスタンスのみを再起動したい場合がある。また、再起動を行う場合、インスタンスを再起動すると自動的にTerminateしてしまうし、インスタンス内部のアプリケーションサーバを再起動すると、ELBからリクエストが来てしまう。ここではこういった点を考慮した安全な再起動の手順を確認する。

大まかな流れ

  1. Auto ScalingのTerminate処理をSuspendにする。
  2. ELBから対象のインスタンスを切り離す。
  3. 対象のインスタンス、またはインスタンス内部のアプリケーションサーバを再起動する。
  4. ELBへ対象のインスタンスを再登録する。
    • インスタンスの再起動を行った場合、インスタンスの状態(Auto ScalingでのHealth State)はUnhealthyとなってしまうので、事前にAuto ScalingのSetInstanceHealthで対象のインスタンスをHealthyにしておくこと。
  5. Auto ScalingのTerminate処理をResumeにする。

自動化する

上述した大まかな流れを自動化する。

  1. 対象のインスタンスのinstance-idを取得する
  2. 取得したinstance-idを元に、そのインスタンスが所属するAuto Scaling Groupを特定する。
    • aws autoscaling describe-auto-scaling-instances –instance-ids ${instance_id} | jq “.AutoScalingInstances[]|.AutoScalingGroupName” -r
  3. 取得したAuto Scaling GroupをキーにTerminate処理をSuspendにする。
    • aws autoscaling suspend-processes –auto-scaling-group-name ${auto_scaling_group_name} –scaling-processes Terminate
  4. 対象のインスタンスが所属するELBのLoadBalancerNameを特定する。
    • aws autoscaling describe-auto-scaling-groups –auto-scaling-group-name ${auto_scaling_group_name} | jq “.AutoScalingGroups[]|.LoadBalancerNames[]” -r
    • 上記のコマンドの返り値を配列などで受け取って、instance-idでフィルタリングする。
    • aws elb describe-instance-health –load-balancer-name ${load_balancer_name} –instances ${instance_id}
  5. 対象のインスタンスをLBから切り離す。
    • aws elb deregister-instances-from-load-balancer –load-balancer-name ${load_balancer_name} –instances ${instance_id}
  6. 対象のインスタンスにて再起動処理を実行する。
  7. (アプリケーションサーバではなく)インスタンスの再起動を行った場合はHealthyに変更する。
    • aws autoscaling set-instance-health –instance-id ${instance_id} –health-status Healthy
  8. ELBへ対象のインスタンスを再登録する。
    • aws elb register-instances-with-load-balancer –load-balancer-name ${load_balancer_name} –instances ${instance_id}
  9. 取得したAuto Scaling GroupをキーにTerminate処理をResumeにする。
    • aws autoscaling resume-processes –auto-scaling-group-name ${auto_scaling_group_name} –scaling-processes Terminate

その他

今回の手順を整理していく中できづいたこと。

  • ELBからインスタンスを切り離してInService状態のインスタンスがbeanstalk環境に設定している最低稼働台数を下回っても、インスタンスが自動的に追加されることは無い。これはbeanstalkでデフォルトに設定されるAuto ScalingのHealth Check TypeがEC2モードであるためだと思われる。
    • なので、アプリケーションサーバを再起動するだけならAuto ScalingのTerminate処理に対する操作は不要と言える。

余談

てっきりbeanstalkでのインスタンス死活監視はELB管理下のインスタンスがInServiceになっている数で判断されているものと思い込んでた…

参考にした記事

Auto ScalingのSuspend/Resumeを使って、Elastic BeanstalkインスタンスをTerminateしないで停止・再起動する