【How-to Guides】GCP FinOps — 閒置資源清理任務 Part2

Kellen
10 min readFeb 18, 2024

--

延續上篇繼續補齊閒置資源清理任務
【How-to Guides】GCP FinOps — 閒置資源清理任務 Part1

2️⃣ Clean up unattached and orphaned persistent disksd

前置作業:額外建立兩個永久性磁碟,其中一個為單獨的未掛接的永久性磁碟的,其中一個磁碟為與虛擬機器分離而成為孤立的磁碟。

  • 部署 Cloud Functions 函數:作為識別未掛接的和孤立的永久性磁碟
  • 建立一個 Cloud Scheduler 作業:使用 HTTP 觸發器讓 Cloud Functions 函數執行並丟至通訊軟體上
  • (選項)⚠️依需求選擇,若發現有未使用的 Disk 調用刪除函數直接刪除閒置資源或是進行快照(更便宜的儲存選項)

檢查磁碟

gcloud compute disks list

先認識 Disk API 資料長相

檢查有掛接到虛擬機器的磁碟及未掛接過的孤立磁碟

export ORPHANED_DISK=orphaned-disk
export UNUSED_DISK=unused-disk

# 有掛接到虛擬機器的磁碟(左圖)
gcloud compute disks describe $ORPHANED_DISK \
--zone=us-central1-a \
--format=json | jq

# 曾未掛接過的孤立磁碟(右圖)
gcloud compute disks describe $UNUSED_DISK \
--zone=us-central1-a \
--format=json | jq

留意的是

  • users標識掛接該磁碟的虛擬機器,只有正在掛接的 Disk 才有此值
  • lastAttachTimestamp標識磁碟上次掛接到虛擬機器的時間
有掛接到虛擬機器的磁碟(左);曾未掛接過的孤立磁碟(右)

再從虛擬機器分離永久性磁碟,並檢查此顆孤立磁碟的資訊變動

gcloud compute disks describe $ORPHANED_DISK \
--zone=us-central1-a \
--format=json | jq
(圖β)從虛擬機器分離 orphaned-disk 永久性磁碟後發現 user 資訊被移除了,attach時間依舊但多了 detach 的時間

圖β

  • 該磁碟未列出 users,這表示該磁碟目前未被使用
  • 現在有一個 lastDetachTimestamp條目,指示該磁碟上次與虛擬機器分離的時間以及該磁碟的最後一次使用時間
  • lastAttachTimestamp 字段仍然存在

認識資料長相很重要,基本上就是資料處理的工作跟呼叫 GCP API 作事情! 光是一個 GCE 就會扯出一脫拉庫的資料。

實作

程式碼可以參考 ☁GCP 釋出的範例檔︎ GCP GitHub repo

單一專案 Cloud Function
由於實務中無法直接砍掉其他專案 Disk,因此僅作資訊揭露的方式來實作。

使用 Google API Python Client Package(google-api-python-client

  • e.g., from googleapiclient import discovery
  • 用途:這個 Client Package 提供了一個通用的方式與 GCP 上的各種服務進行交互操作,包括 Compute Engine、Cloud Storage、BigQuery 等
  • 功能:它提供了對 Google API 的低階抽象,使用者需要直接處理原生的 Google API 請求和回應,較為靈活但也較為複雜
https://github.com/KellenJohn/gcp/blob/develop/finops/list-disk-cloud-function.py
diskResponse 資料長相

資料處理說明 Python 🐍

  • .items() 是 Python 字典(Dictionary)物件的方法之一,用於返回一個包含字典鍵值對的可迭代物件,接著使用 for 迴圈迭代 items,印出每個鍵值對的鍵和值
  • 這邊將每個區域用 diskInfo dictionary 資訊作收納,最後把全部的資訊彙整到 orphaned_disks list
  • if disks_scoped_list.get(‘warning’) is Nonedisks_scoped_list 字典中是否存在名為 'warning' 的鍵。如果找到該鍵,則返回相應的值,如果沒有找到該鍵,則返回 None,而有 'warning' 的鍵不是我們要找尋的對象
  • 要抓取 Disk orphaned 孤兒 if disk.get(‘users’) is None
  • disk['zone']長相如 "https://xxx../xxx/zones/us-central1-a",使用 rsplit('/',1)將 URL 字串從右側開始切割,並以 / 為分隔符,切割後的結果是分成 ["https://xxx../xxx/zones", "us-central1-a"] 兩部分。取索引 [1] 的元素將獲得 "us-central1-a" ,代表磁碟區域的實際值

結果輸出查看

  • 開發關係,可以把 logging.getLogger().setLevel(logging.INFO) 層級設定以方便排障,開發完後再記得移除

之後就可以外掛一些通知面的機制來處理!

跨專案 Batch Job 實作

https://github.com/KellenJohn/gcp/blob/develop/finops/list-unused-disk-batch.py
查看輸出,沒問題再依需求轉成 .csv, into BigQuery, Sheet, 傳訊至聊天軟體等

最後的健檢成果則是發現有 3T 的閒置 Disk 的數字,約莫一個月 3,000 x 0.1 USD / per month 的不必要開銷!

或是可以選擇以「快照」方式備份 Disk,一般來說價格會便宜許多,程式碼使用 createSnapshot 連接作為處理的一環,快照完畢再自動化刪除 Disk。

快照處理 Demo
類型分為

  • 快照:用於標準備份與災難復原,儲存位置與磁碟不同
  • 即時快照:用於快速還原,儲存位置與磁碟相同
  • 封存快照:用於低存取頻率資料的長期儲存空間,儲存位置與磁碟不同
1. 建立快照或是在 VM 本身可以設定快照排程
2.建立完後可以找得到不同類型的快照資訊
3.依照快照掛載流程去處理

還原是開一個 Disk 再掛載快照來處理,然後再使用 VM 把 Disk 掛上去即可

3️⃣ 遷移到更經濟實惠的儲存類別

實作與架構設計

  • 將檔案新增至服務儲存桶,並針對其產生流量
  • 建立一個 Monitoring 資訊中心,以直覺呈現儲存桶利用率
  • 部署 Cloud Functions,以將空閒儲存桶遷移到更經濟實惠的儲存類別
  • 模擬並使用 payload 來觸發該函數,該 payload 用於模擬從 Monitoring 提醒政策接收的通知使用來觸發函數

當您在 Google Cloud Storage(GCS)中儲存大量的物件(例如文件、圖像、影片等),這些物件的存儲成本可能會成為一個考慮因素。Google Cloud 提供了一項功能,稱為「儲存物件生命週期規則」,這讓您可以自動管理這些物件的存儲位置,以最大程度地節省成本。

這些生命週期規則允許您根據一組條件(例如物件的建立日期或即時狀態)將物件自動移動到不同的儲存類別中。舉例來說,您可以設置規則,讓 GCS 自動將一段時間未被存取的物件從標準存儲類別(例如 Regional Storage)移動到較低成本的存儲類別(例如 Nearline Storage 或 Coldline Storage),以節省成本。

然而,這些生命週期規則僅根據物件的屬性來進行操作,但是,這些規則無法確定相關物件是否已被存取過並不直接考慮物件是否已被存取。有時您可能會希望手動處理某些物件,即使它們仍符合生命週期規則的條件。例如,即使某些較新的物件已有一段時間未被存取,但基於特定需求,您仍希望將它們移至 Nearline 儲存空間以節省成本。很多情況及需求難以掌握下,需要手動操作或使用其他自動化方案來處理這些物件的移動。

建立監控儀表板

在 Cloud Console 中,點選導覽選單(≡)>監控

  1. 在左側面板中,按一下儀表板> +建立儀表板
  2. 命名儀表板Bucket Usage
  3. 點選+新增小工具,折線圖
  4. 若要為資源選擇指標 > 指標類型 gcs_bucket請選擇 GCS Bucket > Api > Request count,然後按一下Apply
  5. 按一下“+ 新增篩選器”,依方法名稱過濾:
  • 對於指標標籤,選擇 method
  • 對於運算子,選擇 =(equals)
  • 對於,選擇 ReadObject
已將 Cloud Monitoring 配置為觀察儲存桶中的物件存取情況。圖表中沒有數據,因為 Cloud Storage 儲存桶沒有流量

之後就可以測試將流量傳送到 Bucket 中,Cloud Function 作法可以直接參考官方文件提供的

之後再模擬一些事件帶入 incidentresource_name 進一步驅動 Cloud Function 將 Bucket 遷移到更經濟實惠的儲存類別

# 範例
data = {
"incident": {
"resource_name": "your_bucket_name_here"
}
}

--

--

Kellen

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