【How-to Guides】GCP FinOps — 善用 Scheduler 有效降低 CloudSQL 高昂費用

Kellen
11 min readFeb 9, 2024

--

對於所有公司來說,理想的雲端付費模式是按使用量付費,而 Serverless 產品完美地滿足了這個期望。然而,出於技術原因,某些雲端服務無法使用此模型。

簡單划一下 CloudSQL 的費用

Cloud SQL 的基礎架構由 Google 管理,因此,Cloud SQL 算是一種平台即服務(Platform As A Service,PAAS)。

基本便宜款式一個月都不關機的話也會燒個近 500 $USD,若是個人使用開一個月就要去吃土了

若是在 7X24 的營運環境中且這些服務確實為公司帶來價值,那麼付費並不是什麼大問題或被檢視。真正的問題是付費卻沒有實際使用,也就是無意中支付了不需要開銷的費用,這種情況常發生在未妥善管理資源、忘記關閉暫時不需要的服務時或公司還沒有啟動檢視計畫,使用團隊也還未成熟對計價有足夠的理解。

較嘔的是,大部份費用被砸在沒有真正實際使用上面,就很像自己花大筆銀子卻買一堆虛坪或超高公設比的建案。常見的是在測試環境或者是僅在工作日內營運的服務來說,考慮在非工作時間關閉資源以節省成本是非常重要的。對於最近在診斷公司的雲端成本開銷時特別有感,不過正面思考話,這類的案例,都可以透過小小的努力實現大幅度的成本節省。

💰 Cloud SQL FinOps

使用 Cloud Scheduler 實現 CloudSQL 任務管理 Ⅰ

0️⃣ 前置作業

準備一個 CloudSQL instance,並記錄一下 Project-Id, Region, Instance-ID,待會會使用到

1️⃣ Cloud SQL API 設定

Cloud SQL 提供了管理 API ,若我們想要更新現有實例狀態,啟動或關閉時

Google document

2️⃣ Cloud Scheduler 配置

Cloud Scheduler 也是一款無伺服器產品,允許安排 API, PubSub 呼叫,調度模式基於 Linux CRON。要自動啟動和停止 Cloud SQL 資料庫,我們需要制作 2 個 trigger

  • 每天下午 3:30 關閉資料庫,假定所有的開發人員或是 workload 會於 3 點前結束工作,這裡的 CRON 表達式將是30 15 * * *
  • 類型選擇 HTTP,讓 Scheduler 以 request 至 CloudSQL Admin API,API url, body 參考 GCP 文檔所述,http method 選定 PATCH
  • 設定 OAuth 認證並給予服務帳號權限,至少具有roles/cloudsql.editor的角色授予,至少該角色擁有更新 Cloud SQL 實例的權限
設定最終配置

為了進行測試,我們可以透過點擊 … 按鈕手動啟動 Cloud Scheduler 作業,可達立即測試,這也是滿不錯的功能

直接使用 Cloud Scheduler 這是簡單、易用的方案,無需太多的 engineering,以時間為出發點進行啟動和停止實例!

使用 Cloud Scheduler 實現 CloudSQL 任務管理 Ⅱ

如果上述方案無法滿足需求,或者老闆認為單純使用 Cloud Scheduler 不足以達到理想效果,那麼或許可以考慮進一步探索 Cloud Function、Pub/Sub、Cloud Scheduler 這三個無伺服器的免費產品。這些產品組合的不同使用方式可以應對各種不同的場景和需求,進行自定義組裝以滿足特定的業務要求。

此次要運作的機制如下

這次組裝 Cloud Scheduler, PubSub, Cloud Function 三個 serverless 功能
  • Cloud Scheduler 作業:根據內部計畫將 SQL 實例的啟動和停止訊息傳送至 Pub/Sub
  • Pub/Sub 訊息:從 Cloud Scheduler 接收實例啟動/停止訊息並將訊息傳遞給 Cloud Functions
  • 從 Cloud Function 執行 Cloud SQL 啟動/停止指令
  • Cloud SQL 將啟動/停止

1️⃣ 建立 Cloud Function 作為啟動或停止 Cloud SQL 實例

建立 Cloud SQL 執行個體後,先從架構圖最右邊的 Cloud Function 長出來,主要是作為啟動或停止執行個體的功用。

輸入以下資訊:

  • 指定函數名稱與選擇函數將運行的區域
  • 觸發器類型,選擇 Cloud Pub/Sub,並建立一個「InstanceMgmt」的新 Pub/Sub Topic,用於 Cloud SQL 執行個體管理
  • 服務帳號至少授予具有roles/cloudsql.editor的角色
  • Cloud Function main.py 實作參考上碼(覺得太囉嗦就自行修改)
import json
import base64
import logging
from google.auth import compute_engine
from google.cloud import pubsub_v1
from googleapiclient import discovery


def process_pubsub(event, context):
if 'data' not in event:
logging.error("No data found in the Pub/Sub message.")
return

try:
pubsub_message = json.loads(base64.b64decode(event['data']).decode('utf-8'))
except Exception as e:
logging.error(f"Error parsing Pub/Sub message data: {e}")
return

instance = pubsub_message.get('Instance')
project = pubsub_message.get('Project')
action = pubsub_message.get('Action')

if not all([instance, project, action]):
logging.error("Missing required fields in Pub/Sub message data.")
return

logging.info(f"Request received for Cloud SQL instance {instance}, action: {action}, project: {project}")
credentials = compute_engine.Credentials()

compute = discovery.build('sqladmin', 'v1beta4', credentials=credentials)

action_policy = 'UNDEFINED'
if action == 'start':
action_policy = 'ALWAYS'
elif action == 'stop':
action_policy = 'NEVER'
else:
logging.error("Invalid action provided.")
return

settings = {
'settings': {
'activationPolicy': action_policy
}
}

request = compute.instances().patch(project=project, instance=instance, body=settings)
response = request.execute()

logging.info(response)
  • Cloud Function requirements.py
# Function dependencies, for example:
# package>=version
google-auth==2.3.0
google-api-python-client==2.33.0
google-cloud-pubsub==2.19.1

2️⃣ 驗證雲端函數是否如預期運行

我們現在準備好測試我們的 Cloud Function,並制定了 startstop 參數。現在透過向 Pub/Sub Topics 發布一條訊息來實現!前往 Cloud Console 的 Pub/Sub 部分,然後選擇「InstanceMgmt」Topic,並貼上以下 JSON 訊息後發佈,之後應該會看到您原先被關掉的 Cloud SQL 實例差不多會在 2–3 分鐘後重新啟動成功。

{
"Instance": "psql-server-dev",
"Project": "project-id",
"Action": "start"
}

3️⃣ 建立 Cloud Scheduler 作業以觸發 Cloud Function

已經確認 Cloud Function 正常運作,最後一步是建立將自動啟動和停止實例的 Cloud Scheduler 可以照需求設定。

  • 場景:作業運行時間的 “頻率” 打算定在早上 8:30 至下午的 18:00 運作
  • 目標類型選擇為 Pub/Sub,並為 Topic 指定 InstanceMgmt
  • 訊息內文則分為 start 和 stop(後續由 PubSub 帶入至 Cloud Function)

4️⃣ 驗證時間

最後找個時間觀察或是到 log 查看剛剛的運作步驟,以確保您的資料庫僅在需要時運行,然後將省下的 CloudSQL 經費買杯咖啡 ☕☕☕ 作為下一個 FinOps 的動力之一。

Summary

當您使用 Cloud SQL 執行個體作為開發伺服器或是處理批次性的需求時,可能不需要讓它持續運作。如果是這樣,您可以透過上述的手法,讓 CloudSQL 實例在每天早上工作日開始時啟動並在不需要的時候進行關機,而 CloudSQL 也可以實際抽換成 GKE, Compute Engine 等。

託管式的 CloudSQL 提供了一個簡單而高效的解決方案,使開發團隊能夠專注於應用程式的開發,而不必花費大量時間和資源在資料庫的管理和維護,特別是在需要快速迭代和部署應用程式的情況下。不過對於具託管式的工具需要仔細權衡,長期下來會帶來一定的成本壓力,尤其是在資源需求較高或需求規模較大時,成本可能會快速增加,因此應該在便利性和成本之間找到平衡,以確保組織的利益最大化。

--

--

Kellen

Backend(Python)/K8s and Container eco-system/Technical&Product Manager/host Developer Experience/早期投入資料創新與 ETL 工作,近期堆疊 Cloud☁️ 解決方案並記錄實作與一些雲端概念💡