💇
Cloud RUNのサービス構成をプログラムから変更する
やりたいこと
Cloud RUNの「環境変数」や「最小・最大インスタンス数」をNodeJSで変更したい。
これにより、スケジュールや特定のアラートで柔軟に構成を変更できる。
進め方
公式のパッケージ
このパッケージを使って、Cloud RUNに新しい構成を送信します。
手順としては以下になります。
- 対象のCloud RUNから、現在の"構成"を取得する
- 取得した"構成"を書き換える
- 対象のCloudRUNに書き換えた"構成"で更新を実行する
パッケージの取得と初期化
ターミナルでパッケージを取得します
// NPMパッケージの取得
npm install @google-cloud/run
プログラムで読み込みと初期化を行います
const {ServicesClient} = require('@google-cloud/run').v2;
const runClient = new ServicesClient();
実行権限は、(ほとんどのCompute EngineやCloud RUNで使っている) 「Compute Engine default service account」で十分です。
記事の下の方に、サンプルコードを載せています。結論を見たい人は読み飛ばしてください。
現在の"構成"を取得する
現在の"構成"の取得を行います。
取得したい、Cloud RUNの名前が必要です。
下のプログラム内の定数を入れてください
- PROJECT_ID = 「プロジェクトID」名
対象のCloud RUNの
- LOCATION = リージョン名(この例だと"us-central1")
- SERVICE_NAME = サービス名(この例だと"cloudrun-update-test")
対象
const {ServicesClient} = require('@google-cloud/run').v2;
const runClient = new ServicesClient();
// 定数
const PROJECT_ID = '';// 「プロジェクトID」
const LOCATION = '';// CloudRUNのリージョン名
const SERVICE_NAME= '';// CloudRUNのサービス名
const request = {
name: `projects/${PROJECT_ID}/locations/${LOCATION}/services/${SERVICE_NAME}`
};
// Run request
const response = await runClient.getService(request);
// 構成を取得
console.log(response);
"構成"を変更して適用する
構成の中身を確認
取得した構成を確認しましょう。
上のプログラムの「response」変数の中は以下のような感じです(見やすいように減らしています)
[
{
labels: {},
annotations: {},
name: 'projects/project-hoge/locations/us-central1/services/cloudrun-update-test',
description: '',
createTime: { seconds: '1714544960', nanos: 97834000 },
updateTime: { seconds: '1714544960', nanos: 97834000 },
template: {// ここが
containers: [Array],//コンテナごとの設定(ここに環境変数もある)
volumes: [],
labels: {},
annotations: {},
revision: '',
scaling: [Object],// リビジョンレベルの最大・最小インスタンス数
maxInstanceRequestConcurrency: 80,
sessionAffinity: false,
healthCheckDisabled: false
},
scaling: { minInstanceCount: 0 }// サービスレベル最小インスタンス数
}
]
環境変数を変更したい場合
環境変数は、「template.containers」の中に(マルチコンテナなのでArray)で格納されています。
コンテナが1つなら、配列=0で取ればよいので
template.containers[0].env
に格納されています。
// response変数から、環境変数へのパス
console.log(response[0].template.containers[0].env)
// この形式で格納
// [ { name: 'ここにキーが入る', value: 'ここに値が入る', values: 'value' } ]
リビジョンレベルの最大・最小インスタンス数
リビジョンレベルの最大・最小インスタンス数は template.scaling
に格納されています。
// response変数から、環境変数へのパス
console.log(response[0].template.scaling);
// この形式で格納
// { minInstanceCount: 0, maxInstanceCount: 100 }
CloudRUNに書き換えた"構成"で更新
const {ServicesClient} = require('@google-cloud/run').v2;
const runClient = new ServicesClient();
const PROJECT_ID = '';// 「プロジェクトID」
const LOCATION = '';// CloudRUNのリージョン名
const SERVICE_NAME= '';// CloudRUNのサービス名
const service_template;// ここに書き換え済みの"template"
const request = {
service: {
name: `projects/${PROJECT_ID}/locations/${LOCATION}/services/${SERVICE_NAME}`
"template": service_template
},
allowMissing : false,// サービス名が存在しない場合サービスを作成するか(false=作成しない)
};
// Run request
const [operation] = await runClient.updateService(request);
await operation.promise();
サンプルコード
サンプルコードは、以下を行います。
- 環境変数を "key1: value1", "env: dev"に書き換える
- リビジョンレベルの最小インスタンス数を "1"
定数のPROJECT_ID(プロジェクトID)、 LOCATION(CloudRUNのリージョン名)、SERVICE_NAME(サービス名)は自身の環境を入れてください。
package.json
{
"dependencies": {
"@google-cloud/run": "^1.2.0"
},
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
index.js
const {ServicesClient} = require('@google-cloud/run').v2;
const runClient = new ServicesClient();
const PROJECT_ID = '';// 「プロジェクトID」
const LOCATION = 'us-central1';// CloudRUNのリージョン名
const SERVICE_NAME= 'cloudrun-update-test';// CloudRUNのサービス名
/**
* 指定したサービスの構成を取得する
*/
const callGetService = async(name) => {
const request = { name };
// Run request
const response = await runClient.getService(request);
return response[0];
}
/**
* 指定したサービスの構成を更新する
*/
const callUpdateService = async(name, service_template) => {
const request = {
service: {
"name": name,
"template": service_template
},//サービスの更新
allowMissing : false,// サービス名が存在しない場合サービスを作成するか(false=作成しない)
};
// Run request
const [operation] = await runClient.updateService(request);
const [response] = await operation.promise();
return response;
}
const main = async() => {
const service_name = `projects/${PROJECT_ID}/locations/${LOCATION}/services/${SERVICE_NAME}`
console.log('Cloud RUNの構成変更の実行開始');
console.log(`変更対象::${service_name}`)
// 構成を取得
const service_configuration = await callGetService(service_name);
console.log('Cloud RUNの構成変更前');
console.log(service_configuration);
////
// 構成の変更
let service_template = service_configuration.template;
delete service_template.revision;// 構成が変更するときに"revision"を自動で割り振るため構成から削除
// 環境変数の変更
service_template.containers[0].env = [ { name: 'key1', value: 'value1', values: 'value' }, { name: 'env', value: 'dev', values: 'value' } ]
// 最大インスタンス数の変更
service_template.scaling.minInstanceCount = 1;
// 構成を更新
const new_service_configuration = await callUpdateService(service_name, service_template);
console.log('Cloud RUNの構成変更済みの構成');
console.log(new_service_configuration);
console.log('Cloud RUNの構成変更の実行完了');
}
main();
実行コマンド
npm start
実行すると、Cloud RUNの構成が変更されます。
おわり。
Discussion