[料理佳餚] C# 使用 Google APIs 來控制 GCE(Google Compute Engine)VM 的開啟跟關閉

  • 3226
  • 0
  • GCP
  • 2019-03-31

如果我們明確地知道我們的服務尖峰及離峰時間,那麼我們可以在離峰時間關閉一些機器來節省一點成本,GCE 沒有提供排程開關機的設定,所以我們只好自己寫,Google APIs 的文件告訴我們可以選擇純 HTTP 方式,或是使用 Google APIs Client Library 來控制 VM 的開關機,底下我就用 Google APIs Client Library for .NET 來撰寫控制 VM 開關機的程式。

建立憑證

首先我們得先取得憑證,用來跟 GCP 認證,GCP 有自動生成一個給 Compute Engine 使用的預設服務帳戶,我們可以使用這個帳戶來建立服務帳戶金鑰,從導覽選單中找到憑證,然後按照下面步驟前進:

  1. 點擊建立憑證
  2. 點選服務帳戶金鑰
  3. 服務帳戶選擇 Compute Engine default service account
  4. 最後點擊建立

金鑰只會建立一次,下載下來的 JSON 檔案記得要妥善保存,萬一遺失了就要重新建立。

載入金鑰

我們至少需要兩個相關套件,可以從 NuGet 下載:

將剛剛下載下來的金鑰 JSON 檔案丟給 GoogleCredential.FromFile() 方法,由於我們這種方式產生出來的憑證是屬於 ServiceAccountCredential 類型,所以需要指定認證範圍,再串接呼叫 CreateScoped() 方法,將 https://www.googleapis.com/auth/cloud-platform 網址丟進去。

private static GoogleCredential GetCredential()
{
    return GoogleCredential.FromFile("xxx.json").CreateScoped("https://www.googleapis.com/auth/cloud-platform");
}

開啟 VM

我們建立一個 ComputeService 物件,並且在建構式裡面丟入一個 BaseClientService.Initializer 物件,將取得的 Credential 指定給 HttpClientInitializer 屬性。

接著我們呼叫 ComputeService.Instances.Start() 方法,產生一個 StartRequest 物件,最後呼叫 StartRequest.Execute() 即可發送開機的要求,那麼在這邊我是使用 StartRequest.ExecuteAsync() 非同步方法。

我們會收到一個型別為 Operation 的回應物件,裡面有一個 Status 的屬性,它有三種狀態:PENDING(工作佇列中)、RUNNING(開機中)、DONE(開機完成)。

private async Operation Start()
{
    var credential = GetCredential();

    var computeService = new ComputeService(
        new BaseClientService.Initializer { HttpClientInitializer = credential, ApplicationName = "自訂(可以使用目前執行的應用程式名稱)" });

    var project = "Project ID";
    var zone = "Zone Name";
    var instance = "Instance Name";

    var request = computeService.Instances.Start(project, zone, instance);
    
    var response = await request.ExecuteAsync();

    return response;
}

關閉 VM

關閉 VM 跟開啟 VM 只差在將 Start() 換成 Stop(),一樣會收到 Operation 物件,Status 也一樣是三種狀態::PENDING(工作佇列中)、RUNNING(關機中)、DONE(關機完成)。

private async Operation Stop()
{
    var credential = GetCredential();

    var computeService = new ComputeService(
        new BaseClientService.Initializer { HttpClientInitializer = credential, ApplicationName = "自訂(可以使用目前執行的應用程式名稱)" });

    var project = "Project ID";
    var zone = "Zone Name";
    var instance = "Instance Name";

    var request = computeService.Instances.Stop(project, zone, instance);
    
    var response = await request.ExecuteAsync();

    return response;
}

最後附上 Compute Enginte 相關的 API 文件連結,每一個 Method 說明頁面的最下面都有範例程式碼,提供給各位朋友參考。

參考資料

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學