AutoScaling でスケールインするとき、ライフサイクルフックを試してターミネートを制御してみます。
面倒なので、今回は、SNSやSQSを使用しません。
1.AutoScalingグループを用意する
AWSコンソールで作成し、用意したAutoScalingグループは以下のとおり。
この時点では、EC2インスタンスは 0 にしています。あとは、ほとんどデフォルト設定です。
[root@localhost ~]# aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name WebGroup
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| DescribeAutoScalingGroups |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|| AutoScalingGroups ||
|+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+|
|| AutoScalingGroupARN | arn:aws:autoscaling:us-east-1:xxx:autoScalingGroupName/WebGroup ||
|| AutoScalingGroupName | WebGroup ||
|| CreatedTime | 2016-07-23T23:55:45.798Z ||
|| DefaultCooldown | 300 ||
|| DesiredCapacity | 0 ||
|| HealthCheckGracePeriod | 300 ||
|| HealthCheckType | EC2 ||
|| LaunchConfigurationName | web01-002 ||
|| MaxSize | 1 ||
|| MinSize | 0 ||
|| NewInstancesProtectedFromScaleIn| False ||
|| VPCZoneIdentifier | subnet-f528a2ad ||
|+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+|
||| AvailabilityZones |||
||+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+||
||| us-east-1b |||
||+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+||
||| Tags |||
||+-------------------------------------------------------------------------------+------------------------------------------------------------------------------------+||
||| Key | Name |||
||| PropagateAtLaunch | True |||
||| ResourceId | WebGroup |||
||| ResourceType | auto-scaling-group |||
||| Value | WebGroup |||
||+-------------------------------------------------------------------------------+------------------------------------------------------------------------------------+||
||| TerminationPolicies |||
||+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+||
||| Default |||
||+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+||
2.ライフサイクルフックを作成する
スケールイン用のライフサイクルフックを作成して、パラメータを確認します。
[root@localhost ~]# aws autoscaling put-lifecycle-hook --lifecycle-hook-name terminate-hook --auto-scaling-group-name WebGroup --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING
[root@localhost ~]# aws autoscaling describe-lifecycle-hooks --auto-scaling-group-name WebGroup
-----------------------------------------------------------------------------------------------------------------------------------------------
| DescribeLifecycleHooks |
+---------------------------------------------------------------------------------------------------------------------------------------------+
|| LifecycleHooks ||
|+----------------------+----------------+----------------+-------------------+--------------------+-----------------------------------------+|
|| AutoScalingGroupName | DefaultResult | GlobalTimeout | HeartbeatTimeout | LifecycleHookName | LifecycleTransition ||
|+----------------------+----------------+----------------+-------------------+--------------------+-----------------------------------------+|
|| WebGroup | ABANDON | 172800 | 3600 | terminate-hook | autoscaling:EC2_INSTANCE_TERMINATING ||
|+----------------------+----------------+----------------+-------------------+--------------------+-----------------------------------------+|
ちなみに、ライフサイクルフックを削除したい場合は、以下のコマンドです。
aws autoscaling delete-lifecycle-hook --lifecycle-hook-name terminate-hook --auto-scaling-group-name WebGroup
3.ライフサイクルフックの動作確認
これで、ライフサイクルフックが使えます。
スケールインしたときに、ターミネートが止まるか確認してみます。
まず、スケールアウトしてEC2インスタンスを1台起動します。
[root@localhost ~]# aws autoscaling update-auto-scaling-group --auto-scaling-group-name WebGroup --desired-capacity 1 --min-size 1
アクティビティ履歴で、起動完了を確認します。 "i-15c9ff85" が起動されたEC2インスタンスです。
[root@localhost ~]# aws autoscaling describe-scaling-activities --auto-scaling-group-name WebGroup --query "Activities[].[StartTime,Description,StatusCode]"
----------------------------------------------------------------------------------------
| DescribeScalingActivities |
+---------------------------+--------------------------------------------+-------------+
| 2016-08-06T03:28:36.720Z | Launching a new EC2 instance: i-15c9ff85 | Successful |
| 2016-08-06T02:56:34.931Z | Terminating EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:55:07.365Z | Launching a new EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:38:21.331Z | Terminating EC2 instance: i-e7d4e277 | Successful |
| 2016-08-06T02:33:56.376Z | Launching a new EC2 instance: i-e7d4e277 | Successful |
| 2016-07-24T00:08:09.846Z | Terminating EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:38.938Z | Launching a new EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:06.533Z | Terminating EC2 instance: i-40c5bfd0 | Successful |
| 2016-07-23T23:56:02.592Z | Launching a new EC2 instance: i-40c5bfd0 | Successful |
+---------------------------+--------------------------------------------+-------------+
こんどは、スケールインしてみます。
[root@localhost ~]# aws autoscaling update-auto-scaling-group --auto-scaling-group-name WebGroup --desired-capacity 0 --min-size 0
しばらくして、アクティビティ履歴を確認すると、スケールインしたEC2インスタンスが、"MidTerminatingLifecycleAction" と表示されています。
この表示になったときには、ライフサイクルフックでターミネートが一時停止しています。
[root@localhost ~]# aws autoscaling describe-scaling-activities --auto-scaling-group-name WebGroup --query "Activities[].[StartTime,Description,StatusCode]"
-----------------------------------------------------------------------------------------------------------
| DescribeScalingActivities |
+--------------------------+--------------------------------------------+---------------------------------+
| 2016-08-06T03:36:57.926Z| Terminating EC2 instance: i-15c9ff85 | MidTerminatingLifecycleAction |
| 2016-08-06T03:28:36.720Z| Launching a new EC2 instance: i-15c9ff85 | Successful |
| 2016-08-06T02:56:34.931Z| Terminating EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:55:07.365Z| Launching a new EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:38:21.331Z| Terminating EC2 instance: i-e7d4e277 | Successful |
| 2016-08-06T02:33:56.376Z| Launching a new EC2 instance: i-e7d4e277 | Successful |
| 2016-07-24T00:08:09.846Z| Terminating EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:38.938Z| Launching a new EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:06.533Z| Terminating EC2 instance: i-40c5bfd0 | Successful |
| 2016-07-23T23:56:02.592Z| Launching a new EC2 instance: i-40c5bfd0 | Successful |
+--------------------------+--------------------------------------------+---------------------------------+
このまま放置すると、デフォルトでは60分でタイムアウトして、ターミネートの一時停止が解除されます。
タイムアウトを待たずに、解除したい場合は、インスタンスIDを指定して、以下のコマンドを実行します。
[root@localhost ~]# aws autoscaling complete-lifecycle-action --lifecycle-hook-name terminate-hook --auto-scaling-group-name WebGroup --lifecycle-action-result CONTINUE --instance-id i-15c9ff85
ターミネートの一時停止を解除してから、しばらくして、アクティビティ履歴を確認すると、ターミネートが完了しているのがわかります。
[root@localhost ~]# aws autoscaling describe-scaling-activities --auto-scaling-group-name WebGroup --query "Activities[].[StartTime,Description,StatusCode]"
----------------------------------------------------------------------------------------
| DescribeScalingActivities |
+---------------------------+--------------------------------------------+-------------+
| 2016-08-06T03:36:57.926Z | Terminating EC2 instance: i-15c9ff85 | Successful |
| 2016-08-06T03:28:36.720Z | Launching a new EC2 instance: i-15c9ff85 | Successful |
| 2016-08-06T02:56:34.931Z | Terminating EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:55:07.365Z | Launching a new EC2 instance: i-96dbed06 | Successful |
| 2016-08-06T02:38:21.331Z | Terminating EC2 instance: i-e7d4e277 | Successful |
| 2016-08-06T02:33:56.376Z | Launching a new EC2 instance: i-e7d4e277 | Successful |
| 2016-07-24T00:08:09.846Z | Terminating EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:38.938Z | Launching a new EC2 instance: i-f80d4868 | Successful |
| 2016-07-24T00:04:06.533Z | Terminating EC2 instance: i-40c5bfd0 | Successful |
| 2016-07-23T23:56:02.592Z | Launching a new EC2 instance: i-40c5bfd0 | Successful |
+---------------------------+--------------------------------------------+-------------+
ライフサイクルフックで、ターミネートが一時停止するのは、OSがシャットダウンする前です。
なので、SSHでログインできるし、crontab も動いてます。
小規模環境で、SNS(SQS)をつかわず、手軽にライフサイクルフックを使用したい場合もあります。
crontab で定期的に「アクティビティ履歴」をチェックするスクリプトを、AutoScalingで使用するAMIに仕込んでおけば、スケールイン時にライフサイクルフックの発動を検知して「終了処理」を実行し、「終了処理」が完了してから、ターミネートを続行させることができます。