0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Cloud において認証が必要な Compute プロダクトの死活監視をする方法

Last updated at Posted at 2023-12-05

本記事は GCP(Google Cloud Platform) Advent Calendar 2023 の 11 日目の記事です.

昨年までは,機械学習で研究をしている大学 4 年生でしたが,2023 年 4 月からは新卒でエンジニアとして働いています.
現在は,MLOps エンジニア1をしています.

昨年は 『数独・ナンプレを画像から解く AI を作る』という記事を書いたので,興味があればぜひご覧ください.

1. 結論

Google Cloud の機能である Synthetic Monitoring(合成モニタリング)を使うことで認証付きの Cloud Run に対して死活監視2をすることができました.
Synthecic Monitoring は Cloud Monitoring と JavaScript で動かす Cloud Functions の計 2 つを使用します.

2023/12 現在,Synthetic Monitoring に用いる Cloud Functions には JavaScript のみ対応です.

実際に,上記アーキテクチャをもとに Terraform3を用いて実装してみたので,ぜひご覧ください.
再現コマンドも記載しています↓

1.1. Synthetic Monitoring とは

合成モニターを使用すると、テスト内容と一連のテストを定義できます。たとえば、アプリケーションのログインページ、e コマースストアのチェックアウト プロセス、アプリケーションがサードパーティ サービスに対して行う API 呼び出しをテストできます。

Synthetic Monitoring は合成モニタリングと訳すようです.
上記ドキュメントによると,Synthetic Monitoring とは,テスト内容をカスタムした Google Cloud の Uptime Check(死活監視2)をできるということです.

2. 導入

Google Cloud が提供している Compute プロダクト4は以下の 5 種類存在します.

  • Compute Engine
  • Google Kubernetes Engine
  • Cloud Run ← 本記事ではこのプロダクトに焦点を当てて死活監視2をします
  • App Engine
  • Cloud Functions

2.1. 要件を満たさなかったアーキテクチャ

実務において,認証が必要な Cloud Run に対して死活監視2が求められました.
しかし,以下は認証がない Cloud Run に対しての死活監視2アーキテクチャの例です.

認証が必要な Cloud Run に対する死活監視2のベストプラクティスに関する情報がドキュメントに明示されていないため,本記事ではその手法を紹介します.

上図は認証が必要ない Cloud Run のヘルスチェック時に用いるアーキテクチャで,認証が必要な Cloud Run のヘルスチェックができません.

3. 実装

以下の公式ドキュメントを参考に,実装をしていきます.
Synthetic Monitoring を実装する上で,Cloud Functions に対応しているのはNode.js, TypeScript, Mochaの 3 種類ありますが,今回はNode.jsを使って実装していきます.

3.1. 方針

先に図示した,上図アーキテクチャを作成するにあたり,以下の技術を使って認証が必要な Cloud Run に対して死活監視2を実装します.

  • Terraform3
    • Cloud Run
    • Cloud Functions
    • Cloud Monitoring
      • Uptime Check (Synthetic Monitoring)
  • JavaScript

3.2. 階層構造

Terraform3のベストプラクティスに則って,以下の様なenvironments, modulesに階層を分ける構成にして実装していきます.

上記のリポジトリにおける,treeコマンドの出力を下記に示します.

.
├── environments
│   └── dev
│       ├── backend.tf
│       ├── main.tf
│       ├── provider.tf
│       ├── variables.tf
│       └── versions.tf
└── modules
    ├── main.tf
    ├── monitoring
    │   ├── bucket.tf
    │   ├── dashboard.tf
    │   ├── fuctions.tf
    │   ├── healthcheck.tf
    │   ├── policy.tf
    │   ├── src
    │   │   ├── index.js
    │   │   └── package.json
    │   └── variables.tf
    ├── run.tf
    ├── sa.tf
    └── variables.tf

3.3. ソースコード

以下に主なソースコードを説明付きで,上記サンプルリポジトリから抜粋します.

index.js
const functions = require('@google-cloud/functions-framework');
const fetch = require('node-fetch');
const { runSyntheticHandler } = require('@google-cloud/synthetics-sdk-api');
const assert = require('node:assert');
const { GoogleAuth } = require('google-auth-library');
const dotenv = require('dotenv').config();

// エントリーポイント
functions.http('SyntheticFunction', runSyntheticHandler(async () => {
  const auth = new GoogleAuth();

  // 環境変数から死活監視をする URL を受け取る
  const cloudRunUrl = process.env.BASE_URL;
  const reqUrl = new URL("/api/v1/healthz", cloudRunUrl);
  
  const client = await auth.getIdTokenClient(reqUrl);
  const resp = client.request({url: reqUrl});
  const status = (await resp).status

  // status が 200 の時のみ healthy とする
  return await assert.equal(status, 200);
}));
modules/monitoring/fuctions.tf
resource "google_cloudfunctions2_function" "synthetic_monitoring" {
  name     = var.synthetic_settings.functions.name

  location = var.location
  project  = var.project_id

  build_config {
    runtime     = "nodejs20"

    # エントリーポイント
    entry_point = "SyntheticFunction"

    # Cloud Functions のソースコード置き場を定義する
    source {
      storage_source {
        bucket = google_storage_bucket_object.main.bucket
        object = google_storage_bucket_object.main.name
      }
    }
  }

  service_config {
    max_instance_count    = var.synthetic_settings.functions.max_instance_count
    available_memory      = var.synthetic_settings.functions.memory
    timeout_seconds       = var.synthetic_settings.functions.timeout
    service_account_email = var.run_info.invoker

    # 環境変数に死活監視対象の URI を渡す
    environment_variables = {
      BASE_URL = var.run_info.uri
    }
  }
}
modules/monitoring/healthcheck.tf
resource "google_monitoring_uptime_check_config" "synthetic_monitoring" {
  display_name = var.synthetic_settings.monitoring.name

  # どのくらいの頻度で死活監視をするか
  period  = var.synthetic_settings.monitoring.period

  # タイムアウトの時間を指定
  timeout = var.synthetic_settings.monitoring.timeout

  synthetic_monitor {
    cloud_function_v2 {
      # Clodu Run にアクセスする Cloud Functions の ID
      name = google_cloudfunctions2_function.synthetic_monitoring.id
    }
  }
}

4. 結果

以下に,構築したリソースをコンソールで表示して期待の動作をしているか確認してみます.

4.1. Cloud Run

Authentication が Require authentication となっており,API の使用には認証が必要であることがわかります.

4.2. Cloud Monitoring

Cloud Monitoring でアラートを出すためのしきい値を決めることができます.
今回は 1 分間に 1 回でもアラートがあれば Slack に通知を出すように設定をしています.

4.3. Synthetic Monitoring

ヘルスチェックが通っており,全てのリソースが想定通りに動いていることが確認できました.

  1. ML(Machine Learning)を活用したプロダクトを世に送り出すために必要となる,モデル開発以外のすべてのエンジニアリングを行うエンジニアを指す

  2. サーバーやその上で実行されているソフトウェアの稼働状況を継続的にチェックすることを指す 2 3 4 5 6 7

  3. Infrastructure as Code(IaC)と呼ばれるツールの一種でインフラの構成をソースコードとして管理できる 2 3

  4. 長谷部 光治. アプリケーションはどこで動かすべきか - 2022 春

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?