---
title: "Cloud Functionsを使ってCompute Engineを制御するという話 | grasys blog"
url: "https://blog.grasys.io/post/fukushima/functions2gce/"
description: "こんにちはgrasysの福嶌です。 そろそろ競輪祭の時期ですね。それが終わればグランプリなので１年はあっという間だなと言う感じしかしません。 はじめにgrasysでは検証環境があります、ただ気軽に使えるのではなく金額を気にして使わないと怒られてしまいます。 そのためインスタンスタイプを低くして使うことが多いのですが今…"
---

# Cloud Functionsを使ってCompute Engineを制御するという話

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[fukushima](/authors/fukushima/)
-   公開日：2021年11月15日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#Cloud Logging](/tags/cloud-logging/)[#Cloud Monitoring](/tags/cloud-monitoring/)[#Cloud Functions](/tags/cloud-functions/)

![Cloud Functionsを使ってCompute Engineを制御するという話](/_astro/og-image.DDSiu2Ny_XHpDd.webp)

こんにちはgrasysの福嶌です。 そろそろ競輪祭の時期ですね。それが終わればグランプリなので１年はあっという間だなと言う感じしかしません。

はじめにgrasysでは検証環境があります、ただ気軽に使えるのではなく金額を気にして使わないと怒られてしまいます。  
そのためインスタンスタイプを低くして使うことが多いのですが今回は非力ゆえにスペックの低いGCEインスタンスで起きた事象(CPUが100%に張り付いてインスタンスにsshすらできなくなる)の解決策(その場しのぎの対応)について書いていこうかと思います。

## 事象

検証で同僚[1](#user-content-fn-1)のインスタンスを間借りしようとしたらsshができなく確認したらCPUが100%に張り付いている事象が発生していました。

プロセスを確認するとGCEの以下のディレクトリのログが出力されており以下のディレクトリに出力されてました。

Plain textcontent\_copy

```
/.config/gcloud/logs/
```

ドキュメントを見ると以下のような記載

> ログファイルには、gcloud compute ツールを使用して送信されたすべてのリクエストとそのレスポンスに関する情報が含まれています。 [https://cloud.google.com/compute/docs/troubleshooting/general-tips?hl=ja#viewlogs](https://cloud.google.com/compute/docs/troubleshooting/general-tips?hl=ja#viewlogs)

結局インスタンスタイプが低すぎて当該のプロセスが原因でCPUが100%に張り付いてしまいインスタンスのリセットを行うと事象は解決しましたが定期的に発生し都度リセットを行うと言う作業をしていました。

### 解決方法

今回のゴールとして以下を設定しました。 **CPUが100%になり張り付いたらそれをトリガーとしてCloud Functions経由でインスタンスの制御を行う。**

### 構成

今回は以下のような構成で作っていこうと思います。

![Cloud FunctionsからGCEを操作するシステム構成図](/_astro/01-00-5-1024x621-a828a733.DS6dz_id_1EUaEu.webp)

#### Cloud Pub/Sub

アラートを飛ばす先のPub/Subの設定をします。アラート通知にPub/Subを設定は作ったPub/Subトピックにモニタリングに向けて権限設定を設定する必要があります。  
[ドキュメント](https://cloud.google.com/monitoring/support/notification-options#pubsub)を参考に以下のコマンドを実施

Plain textcontent\_copy

```
$ gcloud pubsub topics add-iam-policy-binding projects/{{プロジェクト名}}/topics/{{pub/subトピックID}} --role=roles/pubsub.publisher --member=serviceAccount:xxxxx@gcp-sa-monitoring-notification.iam.gserviceaccount.com
```

#### Cloud Monitoring

アラートは以下のように設定

Plain textcontent\_copy

```
対象インスタンス:自分の検証に利用しているインスタンス
Condition: is above
Threshold: 99.9
For: 5 minutes
```

99.9%以上の高負荷が5分続いた場合アラートを発砲するようにしました。  
通知先は念のためメールとPub/Subにします。

#### Cloud Functions

制御するコードは以下のようなコードを作成しました。今回は[google-auth](https://pypi.org/project/google-auth/)と[google-api-python-client](https://pypi.org/project/google-api-python-client/)を利用してAPIを叩きます。

Plain textcontent\_copy

```
#!/usr/bin/python
#coding:utf-8

import sys
import json
import base64

import google.auth
import googleapiclient.discovery

class Variables:
    name = {{インスタンス名}}
    zone = {{ゾーン名}}}

def reset_instances(compute, project, zone):
    # 対象のVMをリセット
    try:
        compute.instances().reset(project=project, zone=zone, instance=Variables.name).execute()
    except Exception as e:
        print(e)
        sys.exit(1)

    return "success"

def alert2pubsubFunc(event, context):
    if 'data' in event:
        req = base64.b64decode(event['data']).decode('utf-8')
        staus = json.loads(req)['incident']['state']
    else:
        sys.exit(2)

    compute = googleapiclient.discovery.build('compute', 'v1')
    project = google.auth.default()[1]

    # Alert open
    if staus == "open":
        print(reset_instances(compute, project, Variables.zone))
```

また、Cloud FunctionsのランタイムはPython3.9を利用します。デプロイは以下のコマンドで実施

Plain textcontent\_copy

```
$ gcloud functions deploy alert2pubsubFunc --trigger-topic {{pub/subトピックID}} --runtime python39 --region asia-northeast1
```

デプロイエラーが出ると思ったら、Pyparsingが最新で3.0.6ためCloud Functionsでデプロイエラーを起こしてしまうようです。[stackoverflow](https://stackoverflow.com/questions/69936420/google-cloud-platform-app-deploy-failure-due-to-pyparsing)で探したら解決としてはバージョンを2.4.7に指定し解決しました。

#### テスト

そしたら早速テストをしてみましょう！  
発報するためにアラートの閾値を低めに設定しアラートを飛ばしやすく調整を行い。サーバー内で以下のコマンドを実行してCPU負荷を高くしてみます。

Plain textcontent\_copy

```
$ yes > /dev/null
```

アラートが12:50に発報され…

![アラートが12:50に発報され…の画面](/_astro/02-01-8-1024x813-040da67f.BjEMSaQG_Z1czxNL.webp)

モニタリングの方で確認したらインスタンスがリセットされた！

![モニタリングの方で確認したらインスタンスがリセットされたの画面](/_astro/03-02-8-1024x314-8b59dad6.DRnPWERW_Z5nOpg.webp)

うまく動いてますね！

### まとめ

今回はアラートをpub/subに送ってCloud FunctionsのトリガーとしてCompute Engineを制御しました。  
またCloud FunctionsをHTTPリクエストにしてアラートではなくCloud Schedulerなどを応用して使えば自動起動や自動停止なども簡単にできそうですね。[こちらの記事](https://blog.grasys.io/post/tomatsuri/cloud-run-cloud-scheduler-laravel/)とか参考になると思います。  
上記ができれば無駄な稼働時時間をなくすことができるのでお財布に優しいはず！  
現場からは以上です！

* * *

## Footnotes

1.  [指１本でタイピングしていた 「ど素人」が、世界的人気Webメディアのクラウドインフラを支えるエンジニア](https://prtimes.jp/story/detail/vBd18Xc1yQx) [↩](#user-content-fnref-1)
    

## この記事を書いた人

[![](/_astro/noicon.CTHOhNiB_Z24aAgM.webp)](/authors/fukushima/)

### [fukushima](/authors/fukushima/)

fukushimaのプロフィールと執筆記事をご覧いただけます。

[プロフィールと記事一覧](/authors/fukushima/)