あけおめなので、ジャブから入ります。左を制するものは世界を制すです。
EC2 のインスタンス・リソース制限が、起動数からvCPU数に変わって結構経つのですが、その監視を気分転換に追加しようと思って放置しておいたアレというか、新年ブーストのためにワザととっておいた、そんなアレです。
参考ページ
- Amazon EC2 で vCPU ベースのオンデマンドインスタンス制限が利用可能になりました | Amazon Web Services ブログ
- よくある質問 > EC2 オンデマンドインスタンス制限 – Amazon EC2 | AWS
- AWS Limit Monitor が vCPU ベースのオンデマンドインスタンス制限モニタリングのサポートを開始
- EC2 の起動制限がサーバー台数から vCPU での制限へ変更されます – サーバーワークスエンジニアブログ
- vCPUの上限をチェックするLambdaを作成しました – 挫折から何かしら学んでいきたい
vCPU制限値を確認する方法
いくつかあるので、まとめておきます。画像での丁寧な説明はありましぇん。EC2
Service:EC2 > 制限 > 検索でvCPUで出てくるもののうち、「All Standard (A, C, D, H, I, M, R, T, Z) instances のオンデマンドを実行中」とでも書いてあるやつが一般的に利用されるインスタンスタイプです。監視するのも普通はこれだけでいいでしょう。
Trusted Advisor
Service:Trusted Advisor > サービスの制限 > EC2 オンデマンドインスタンスで見れますが、1台も起動していないと出ないっぽいです。あと、API でここから取れるかちゃんと見てないですが、サポートがビジネス以上じゃないと利用制限されるところなので、基本的にはここから値を取ろうとはしません。
Service Quotas
Service:Service Quotas > ダッシュボード > Amazon Elastic Compute Cloud (Amazon EC2)の Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances です。このリンクを進むと、モニタリングのところに制限値に対する使用%が表示されます。
CloudWatch
直接的なメトリックは一応、メトリクス > すべて > 使用 > AWSリソース > EC2, vCPU, Resource, Standard/OnDemand, ResourceCount
にあるのですが、それよりも
上記の Service Quotas で出したグラフにて、グラフにオンマウスすると、グラフ右上に『︙』マークで「ウィジェットのアクション」が出るので、そのメニューから「メトリクスで表示」に飛んだ方がそれらしいものを確認できます。
タブ「グラフ化したメトリクス (1/2)」に、m1 = 使用vCPU と e1 = 使用率 が一覧されますが、それよりもタブ「発信元」を見たほうが早いです。こんな感じになってます。
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "metrics": [ [ { "expression": "100 * m1 / SERVICE_QUOTA(m1)", "label": "Utilization %", "id": "e1", "region": "ap-northeast-1" } ], [ "AWS/Usage", "ResourceCount", "Resource", "vCPU", "Service", "EC2", "Type", "Resource", "Class", "Standard/OnDemand", { "id": "m1", "visible": false } ] ], "period": 300, "stat": "Maximum", "view": "timeSeries", "stacked": false, "title": "Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances - (Utilization %)", "region": "ap-northeast-1" } |
expression をゴニョゴニョ用いて、使用率を出しているのがわかります。
Lambda Python3 で制限値と使用値を取得する
シンプルな運用ならば、AWS Limit Monitor を使うのがいいかもですが、ウチはいくつかの任意の監視サービスにメトリクスを送信してるので、監視関連はもりっとLambdaでやっています。なので、Python3 boto3 で書いて、CloudWatch Event で定期的に送っています。コードの一部
エセフレームワークくさくしてるので、これだけで動くコードではないですが、雰囲気だけでもということで部分的にコピペしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
def getQuotaValue(self, service_code, quota_code): sq = self.getServiceQuotas() cloudwatch = self.getCloudWatch() result = { 'quota' : None, 'used' : None, } quota = sq.get_service_quota( ServiceCode = service_code, QuotaCode = quota_code, )['Quota'] if 'Value' not in quota: return result result['quota'] = quota['Value'] dimensions = [] for k, v in list(quota['UsageMetric']['MetricDimensions'].items()): dimensions.append({'Name': k, 'Value': v}) usage_metric = quota['UsageMetric'] result['used'] = self.getCloudWatchStats(usage_metric['MetricNamespace'], usage_metric['MetricName'], dimensions) return result def getCloudWatchStats(self, namespace, metric_name, dimensions, statistics="Maximum"): cloudwatch = self.getCloudWatch() res = cloudwatch.get_metric_statistics( Namespace = namespace, MetricName = metric_name, Dimensions = dimensions, StartTime = self.start_time, EndTime = self.end_time, Period = self.period, Statistics = [statistics], ) value = 0 if res["Datapoints"]: value = res["Datapoints"][0][statistics] return value |
注意点
ほとんどのメトリクスは、100秒以上前にすると値を取得できるのですが、Service Quotas は 300秒以上前にしないと取得できませんでした。最初は dimensions が複雑だから、なんかミスって Datapoints がとれないのかと思いましたが、他より反映が遅いというだけのことでした。
取得データ
制限値と使用数
上記のコードで取得した制限値と使用数を、監視サービスに送って、そのものをグラフにするのと、使用%を計算して 80% なりなんなりで Warning | Critical などのアラートを出すようにします。使用率を使いたい場合
CloudWatch で見た「発信元」のように、取得時点で使用率を出してしまいたい場合、get_metric_statistics ではなく get_metric_data を使えばよいです。というか、最近はそもそもこちらの使用を推奨をしているようですが・・・Expression を使えるので、まぁ使用率を出すことはできるのですが、任意のグラフサービスで出すことを考えると、使用率だけ出しても半分くらいしか役に立たないので、制限値と使用数を出しつつプラスで必要ならついでに Expression しちゃう☆感じになるでしょう。
そんなこんなで、今年もよろしくお願い申し上げます:-)