はじめに
最近とあるAWS上のシステムのRDSをSingle-AZからMulti-AZに変更する作業が必要になった。
このシステムではIoTデバイスから取得したデータをEC2のWebサーバで受信し、受信したデータをそのままSQSに転送している。
このSQSのキューはElasticBeansTalk(以下EB)で作成したもので、キューの後ろにはそのデータを処理するWorkerノードを構成している。
Multi-AZ構成に変更する際にWorkerノードが起動した状態のままだと、DBへの登録が失敗し、データがDeadLetterQueueに転送される可能性があった。
そのため、Multi-AZへの構成変更の間、SQSからのメッセージ取得を一時的に止める必要があった。
EBのCLI(ebコマンド)やAWSコンソールから一時的にWorkerの動作を停止することはできないことが分かったため、代替手順を実施した。
この記事はその備忘録である。
手順
手順は以下の流れで行う。
- WorkerのAutoScale機能を停止
- WorkerのEC2インスタンスを停止
- RDSの構成変更
- WorkerのEC2インスタンスを起動
- WorkerのAutoScalingGroupの状態を手動でHealthyに変更
- WorkerのAutoScale機能を開始
システムの構成情報を以下に示す。
- WorkerのAutoScalingGroup名: awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX
{
"AutoScalingGroups": [
{
"AutoScalingGroupName": "awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX",
"LaunchConfigurationName": "awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingLaunchConfiguration-YYYYYYYYYYYYY"",
"MinSize": 1,
"MaxSize": 4,
"DesiredCapacity": 1,
"DefaultCooldown": 360,
"AvailabilityZones": [
"ap-northeast-1b",
"ap-northeast-1c"
],
"LoadBalancerNames": [],
"TargetGroupARNs": [],
"HealthCheckType": "EC2",
"HealthCheckGracePeriod": 0,
…
MinSizeが1なので、低負荷時はインスタンスが1つしか存在していない。
1. WorkerのAutoScale機能を停止
SuspendProcessesの設定に「Terminate」を追加する。
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].SuspendedProcesses
[]
% aws autoscaling suspend-processes --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX --scaling-processes Terminate
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].SuspendedProcesses
[
{
"ProcessName": "Terminate",
"SuspensionReason": "User suspended at 2018-02-22T11:11:24Z"
}
]
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].Instances
[
{
"InstanceId": "i-1234567abcdefghij",
"AvailabilityZone": "ap-northeast-1c",
"LifecycleState": "InService",
"HealthStatus": "Healthy",
"LaunchConfigurationName": "awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingLaunchConfiguration-YYYYYYYYYYYYY",
"ProtectedFromScaleIn": false
}
]
2. WorkerのEC2インスタンスを停止
- EC2のコンソールから当該インスタンスを停止
- ElasticBeansTalk上でも重大エラーになる
AutoScale状態確認
インスタンスを停止するとHealthStatusが「Unhealty」になることが確認できる。
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].Instances
[
{
"InstanceId": "i-1234567abcdefghij",
"AvailabilityZone": "ap-northeast-1c",
"LifecycleState": "InService",
"HealthStatus": "Unhealthy",
"LaunchConfigurationName": "awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingLaunchConfiguration-YYYYYYYYYYYYY",
"ProtectedFromScaleIn": false
}
]
この時点でSQSのキューを確認すると、メッセージが処理されずキューに蓄積されて行くことが確認できる。
メッセージの可視性が保たれる期間内にWorkerを復旧する。
3. RDSの構成変更
詳細手順は割愛。
4. WorkerのEC2インスタンスを起動
- EC2のコンソールから当該インスタンスを起動
- ElasticBeansTalk上ではエラー解消になる
インスタンスを起動してもHealthStatusは自動的に「Healty」にはならないため次の手順で手動で「Healthy」へ状態を遷移させる。
5. WorkerのEC2インスタンスの状態を手動でHealthyに変更
※この手順を省くと、次の手順を実施した際に当該インスタンスは削除され、新規のインスタンスが生成される。
% aws autoscaling set-instance-health --instance-id i-1234567abcdefghij --health-status Healthy
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].Instances
[
{
"InstanceId": "i-1234567abcdefghij",
"AvailabilityZone": "ap-northeast-1c",
"LifecycleState": "InService",
"HealthStatus": "Healthy",
"LaunchConfigurationName": "awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingLaunchConfiguration-YYYYYYYYYYYYY",
"ProtectedFromScaleIn": false
}
]
6. WorkerのAutoScale機能を開始
SuspendProcessesの設定から「Terminate」を削除する。
% aws autoscaling resume-processes --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX --scaling-processes Terminate
% aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name awseb-e-xxxxxxxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXXX | jq .AutoScalingGroups[0].SuspendedProcesses
[]