對於所有公司來說,理想的雲端付費模式是按使用量付費,而 Serverless 產品完美地滿足了這個期望。然而,出於技術原因,某些雲端服務無法使用此模型。
簡單划一下 CloudSQL 的費用
Cloud SQL 的基礎架構由 Google 管理,因此,Cloud SQL 算是一種平台即服務(Platform As A Service,PAAS)。
若是在 7X24 的營運環境中且這些服務確實為公司帶來價值,那麼付費並不是什麼大問題或被檢視。真正的問題是付費卻沒有實際使用,也就是無意中支付了不需要開銷的費用,這種情況常發生在未妥善管理資源、忘記關閉暫時不需要的服務時或公司還沒有啟動檢視計畫,使用團隊也還未成熟對計價有足夠的理解。
較嘔的是,大部份費用被砸在沒有真正實際使用上面,就很像自己花大筆銀子卻買一堆虛坪或超高公設比的建案。常見的是在測試環境或者是僅在工作日內營運的服務來說,考慮在非工作時間關閉資源以節省成本是非常重要的。對於最近在診斷公司的雲端成本開銷時特別有感,不過正面思考話,這類的案例,都可以透過小小的努力實現大幅度的成本節省。
💰 Cloud SQL FinOps
使用 Cloud Scheduler 實現 CloudSQL 任務管理 Ⅰ
0️⃣ 前置作業
準備一個 CloudSQL instance,並記錄一下 Project-Id, Region, Instance-ID,待會會使用到
1️⃣ Cloud SQL API 設定
Cloud SQL 提供了管理 API ,若我們想要更新現有實例狀態,啟動或關閉時
- 使用 管理 API 項下的 Instance 類別的 PATCH endpoint
- 設定
activationPolicy
設定為NEVER
或ALWAYS
(啟動或停止資料庫)
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 作業:根據內部計畫將 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,並制定了 start
和 stop
參數。現在透過向 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 提供了一個簡單而高效的解決方案,使開發團隊能夠專注於應用程式的開發,而不必花費大量時間和資源在資料庫的管理和維護,特別是在需要快速迭代和部署應用程式的情況下。不過對於具託管式的工具需要仔細權衡,長期下來會帶來一定的成本壓力,尤其是在資源需求較高或需求規模較大時,成本可能會快速增加,因此應該在便利性和成本之間找到平衡,以確保組織的利益最大化。
Reference
- 【GCP Doc】Start, stop, and restart instances
- 【GCP Blog】Lower development costs: schedule Cloud SQL instances to start and stop
- Lower your development costs by scheduling Cloud SQL instances to start and stop
- Running a serverless batch workload on GCP with Cloud Scheduler, Cloud Functions, and Compute Engine
- Scheduled VM start-stop with Cloud Scheduler + PubSub + Cloud Function