EC2 のキャパシティ不足 (InsufficientInstanceCapacity) の傾向と対策

## InsufficientInstanceCapacity エラーとは

対象の EC2 のインスタンスタイプを起動するためのキャパシティ (サーバー容量) を一時的に AWS 側で確保できない場合に発生するエラーです。インスタンス作成時や起動時に以下のようなメッセージが表示されます。

```
We currently do not have sufficient t3.micro capacity in the Availability Zone you requested (ap-northeast-1a). 
Our system will be working on provisioning additional capacity. You can currently get t3.micro capacity by
not specifying an Availability Zone in your request or choosing ap-northeast-1c, ap-northeast-1d.
```

構築時にはエラー解消まで待てばよいのですが、運用時に発生するとクリティカルな影響が出るケースがあります。InsufficientInstanceCapacity に対する対策をいくつか記載します。

## 停止→起動ではなく、再起動を利用する

InsufficientInstanceCapacity は新しいインスタンスを起動しようとしたり、停止したインスタンスを起動しようとする際に発生します。

**参考:**

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/troubleshooting-launch.html#troubleshooting-launch-capacity

稼働中のインスタンスの再起動操作 (RebootInstances API) を行った場合には、InsufficientInstanceCapacity は発生しません。EC2 の再起動操作は OS の再起動に相当します。OS の再起動が目的であれば EC2 の再起動操作でキャパシティ不足を回避できます。

EC2 のリタイアメント通知等で稼働ホストの変更が必要な場合は、再起動では対応できません。必ず停止→起動の手順を踏む必要があります。キャパシティ不足の発生を避けたい場合にはキャパシティ予約の利用を検討ください。

## キャパシティ予約を利用する

### オンデマンドキャパシティ予約

オンデマンドキャパシティー予約 を使用すると、特定のアベイラビリティーゾーンで任意の時間だけ、EC2 インスタンスのキャパシティを予約できます。予約が作成されると EC2 の起動有無に関わらず確保したコンピューティング料金分の課金が開始されますが、その間は対象のインスタンスタイプの起動が保証されます。メンテナンス等の対応後はキャパシティーの予約をキャンセルすれば料金は発生しなくなります。

オンデマンドキャパシティ予約を作成するには、インスタンスタイプ、OS プラットフォーム、AZ、テナンシー、数量を指定する必要があります。

![image-20210614232456122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/689b9edc-ac6f-f2b8-0f43-a8f2aa8d695f.png)


オンデマンドキャパシティ予約のオプションとして Instance eligibility (インスタンスの利用資格) があり、以下の2種類から選択できます。

![image-20210614232150161.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/04250ad7-8ba0-783a-c595-085b6fc95b9c.png)

* open  (一致する詳細を持つ任意のインスタンス) 
  
一致する属性を持つインスタンスに対し、キャパシティの予約が自動的に適用されます。すでに稼働中のインスタンスにも自動で適用されますが、インスタンス ID の指定などはできません。特定の AZ に m5.large が 4 台あったとして 2 台 をオンデマンドキャパシティ予約したとしても、どのインスタンスに適用されるかは予測できません。

* targeted (この予約を指定するインスタンスのみを受け入れます)
 
targated で作成されたキャパシティー予約は EC2 作成時または起動時に明示的に使用する必要があります。自動適用はされません。起動中のインスタンスに適用するには一度停止を行い、インスタンスの設定でキャパシティ予約の設定を変更して使用を明示する必要があります。
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/05a12841-ffd9-eac1-c867-993a417a6f9a.png)

目的のインスタンスにキャパシティ予約が適用されているか確認するには EC2 ダッシュボードの詳細から確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/7926e292-4e52-0f6d-27ac-4d26fc27b97a.png)


オンデマンドキャパシティ予約時にもインスタンスの供給状況によっては InsufficientInstanceCapacity が発生する可能性があります。目的の作業直前で実施する場合、確保できない可能性もありますのでご注意ください。

その他の詳細はドキュメントもご参照ください。

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-reservations.html

###リザーブドインスタンスによるキャパシティ予約

AZ をスコープとしたリザーブドインスタンスを購入している場合には購入台数分のキャパシティが予約されています。リージョンをスコープとしたリザーブドインスタンスまたは Savings Plan を使用している場合はキャパシティ予約は適用されませんので、必要に応じてオンデマンドキャパシティ予約をご使用ください。

**参考:**

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/reserved-instances-scope.html

オンデマンドキャパシティ予約、リザーブドインスタンス、Savings Plans の比較は以下のとおりです。

|                  | オンデマンドキャパシティ予約           | ゾーン リザーブドインスタンス      | リージョナルリザーブドインスタンス | Savings Plans                      |
| ---------------- | -------------------------------------- | ---------------------------------- | ---------------------------------- | ---------------------------------- |
| コミットメント   | 不要、必要に応じて作成・キャンセル可能 | 1年または3年のコミットメントが必要 | 1年または3年のコミットメントが必要 | 1年または3年のコミットメントが必要 |
| キャパシティ予約 | あり                                   | あり                               | なし                               | なし                               |
| 請求割引         | なし                                   | あり                               | あり                               | あり                               |


## その他の対策 

その他一時的な回避策をあげます。AZ やインスタンスタイプを変更した場合、システムによっては後日もとの状態に戻さなければならないケースもあるかと思います。

### インスタンスタイプの変更

InsufficientInstanceCapacity は特定の AZ のインスタンスタイプにおける供給状況により発生するため、インスタンスタイプを変更することで回避できる可能性があります。
e.g., t3.medium → t3.large, m5.large → c5.large など

### 別のアベイラビリティゾーンで起動
InsufficientInstanceCapacity は特定の AZ のインスタンスタイプにおける供給状況により発生するため、エラーが発生した AZ とは異なる AZ を指定することで回避できる可能性があります。EC2 インスタンスは AZ の移動ができないため、バックアップや AMI から新しいインスタンスを作成する必要があります。プライベート IP アドレスも変更されます。

### 数分待ってからリトライ
キャパシティは頻繁に変動する可能性があるため、何度かリトライすることで起動に成功する場合があります。許容できるダウンタイムが短い場合にはリスクがあるため、キャパシティ予約を検討してください。

## フリート機能の活用

アプリケーションとして Auto Scaling  を使用している、 AZ やインスタンスタイプの違いを許容できるといった特性があれば、各サービスにおけるフリート機能を活用することで InsufficientInstanceCapacity に対し耐久性を持たせることが可能です。これらの機能を活用すると複数のインスタンスタイプを事前に指定できるため、ある AZ のインスタンスタイプで容量不足が発生した場合でも別のインスタンスタイプで起動させることができます。

### EC2 Fleet
EC2 フリートは、インスタンスのフリート  (グループ) を起動するための設定情報です。複数のインスタンスタイプ、購入オプション (オンデマンド、スポット、リザーブド) を指定し、 指定した容量のコンピューティングリソースを確保することができます。EC2 Fleet は API または AWS CLI からのみ利用できます。

**参考:**

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet.html

### Auto Scaling Geroup
2018 年のアップデートにより、EC2 Fleet の機能が EC2 Auto Scaling にも拡張されました。1つの Auto Scaling Group 内で、複数のインスタンスタイプや購入オプション (オンデマンド、スポット、リザーブド) を組み合わせて利用できるようになりました。

**参考:**

https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-purchase-options.html

### インスタンスフリート (Amazon EMR)

Amazon EMR でクラスターを作成する際にインスタンスフリートを選択できます。マスターノード、コアノード、およびタスクノードの構成オプションとして複数のインスタンスタイプと購入オプション (オンデマンド、スポット) を指定することができます。

**参考:**

https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-instance-group-configuration.html

以上です。
参考になれば幸いです。