本文档假定您熟悉以下内容:
目标
- 删除未使用的 IP 地址:在 Google Cloud 上,附加到负载均衡器或虚拟机 (VM) 实例的静态 IP 地址属于免费资源。 如果某静态 IP 地址被预留,但未被使用,则该地址将按小时收费。在严重依赖静态 IP 地址和大规模动态预配的应用中,这种浪费可能会随时间推移变得非常显著。
- 删除孤立或未使用的永久性磁盘:如果永久性磁盘在创建时未挂接到虚拟机,或者如果一个机器具有多个磁盘,并且一个或多个磁盘已分离,则这些永久性磁盘就是未使用或孤立的磁盘。
- 迁移到更加经济实惠的存储类别:Google Cloud 提供了多种对象存储类别。 请使用与您的需求最相符的类别。
架构
下图描述了部署的第一部分,在该部分中,安排 Cloud Functions 函数来识别和清理未使用的 IP 地址。
第一个示例演示了以下操作:
- 使用静态外部 IP 地址和单独的未使用的静态外部 IP 地址创建 Compute Engine 虚拟机。
- 部署 Cloud Functions 函数,以标识未使用的地址。
- 创建一个 Cloud Scheduler 作业,以使用 HTTP 触发器计划函数运行。
在下图中,您安排一个 Cloud Functions 函数来识别和清理未挂接和孤立的永久性磁盘。
第二个示例演示了以下操作:
- 创建一个包含两个永久性磁盘和一个单独的未挂接的永久性磁盘的 Compute Engine 虚拟机。其中一个磁盘因与虚拟机分离而成为孤立的磁盘。
- 部署 Cloud Functions 函数,以标识未挂接的和孤立的永久性磁盘。
- 创建一个 Cloud Scheduler 作业,以使用 HTTP 触发器计划 Cloud Functions 函数的执行。
在下图中,您触发一个 Cloud Functions 函数来将存储桶从 Monitoring 提醒政策迁移到更加经济实惠的存储类别。
第三个示例演示了以下操作:
- 创建两个存储桶,将文件添加到服务存储桶,并针对其生成流量。
- 创建一个 Monitoring 信息中心,以直观呈现存储桶利用率。
- 部署 Cloud Functions 函数,以将空闲存储桶迁移到更加经济实惠的存储类别。
- 使用载荷来触发该函数,该载荷用于模拟从 Monitoring 提醒政策接收的通知。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
须知事项
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
启用 Compute Engine, Cloud Functions, and Cloud Storage API。
-
在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
启用 Compute Engine, Cloud Functions, and Cloud Storage API。
-
在 Google Cloud 控制台中,激活 Cloud Shell。
Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。
您可以从 Cloud Shell 运行本文档中的所有命令。
设置您的环境
在本部分中,您将配置此架构所需的基础架构和身份。
在 Cloud Shell 中,克隆代码库并切换到
gcf-automated-resource-cleanup
目录:git clone https://github.com/GoogleCloudPlatform/gcf-automated-resource-cleanup.git && cd gcf-automated-resource-cleanup/
设置环境变量,并将代码库文件夹设为在其中运行所有命令的
$WORKDIR
文件夹:export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) WORKDIR=$(pwd)
安装开源负载生成工具 Apache Bench:
sudo apt-get install apache2-utils
清理未使用的 IP 地址
在本部分中,您将完成以下步骤:
- 创建两个静态 IP 地址。
- 创建一个使用静态 IP 地址的虚拟机。
- 查看 Cloud Functions 函数代码。
- 部署 Cloud Functions 函数。
- 使用 Cloud Scheduler 作业测试 Cloud Functions 函数。
创建 IP 地址
在 Cloud Shell 中,切换到
unused-ip
目录:cd $WORKDIR/unused-ip
将 IP 地址的名称导出为变量:
export USED_IP=used-ip-address export UNUSED_IP=unused-ip-address
创建两个静态 IP 地址:
gcloud compute addresses create $USED_IP \ --project=$PROJECT_ID --region=us-central1 gcloud compute addresses create $UNUSED_IP \ --project=$PROJECT_ID --region=us-central1
本示例使用
us-central1
区域,但您可以选择其他区域并在本文档的其余部分中始终引用该区域。确认已创建两个地址:
gcloud compute addresses list --filter="region:(us-central1)"
在输出中,状态
RESERVED
表示 IP 地址未使用:NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 RESERVED
将已使用的 IP 地址设置为环境变量:
export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP \ --region=us-central1 --format=json | jq -r '.address')
创建一个虚拟机
在 Cloud Shell 中,创建一个实例:
gcloud compute instances create static-ip-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --subnet=default \ --address=$USED_IP_ADDRESS
确认现在正使用其中一个 IP 地址:
gcloud compute addresses list --filter="region:(us-central1)"
输出类似于以下内容:
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
查看 Cloud Functions 函数代码
在 Cloud Shell 中,输出代码的主要部分:
cat $WORKDIR/unused-ip/function.js | grep "const compute" -A 31
输出如下所示:
const compute = new Compute(); compute.getAddresses(function(err, addresses){ // gets all addresses across regions if(err){ console.log("there was an error: " + err); } if (addresses == null) { console.log("no addresses found"); return; } console.log("there are " + addresses.length + " addresses"); // iterate through addresses for (let item of addresses){ // get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used AND if it's at least ageToDelete days old: if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){ // delete address item.delete(function(err, operation, apiResponse2){ if (err) { console.log("could not delete address: " + err); } }) } }) } // return number of addresses evaluated res.send("there are " + addresses.length + " total addresses"); }); }
在前面的代码示例中,请注意以下内容:
compute.getAddresses(function(err, addresses){ // gets all addresses across regions
使用
getAddresses
方法检索项目中所有区域的 IP 地址。// get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used: if (metadata.status=='RESERVED'){
获取每个 IP 地址的元数据并检查其
STATUS
字段。if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){
检查 IP 地址是否正在使用中,使用辅助函数计算其存在时间,并将其存在时间与常量(在本示例中设置为
0
)进行比较。// delete address item.delete(function(err, operation, apiResponse2){
删除 IP 地址。
部署 Cloud Functions 函数
在 Cloud Shell 中,部署 Cloud Functions 函数:
gcloud functions deploy unused_ip_function --trigger-http --runtime=nodejs8
将触发器网址设置为环境变量:
export FUNCTION_URL=$(gcloud functions describe unused_ip_function \ --format=json | jq -r '.httpsTrigger.url')
计划并测试 Cloud Functions 函数
在 Cloud Shell 中,创建一个 Cloud Scheduler 任务,以在每天凌晨 2 点运行 Cloud Functions 函数:
gcloud scheduler jobs create http unused-ip-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
通过手动触发作业来测试该作业:
gcloud scheduler jobs run unused-ip-job
确认已删除未使用的 IP 地址:
gcloud compute addresses list --filter="region:(us-central1)"
输出类似于以下内容:
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
清理未使用和孤立的永久性磁盘
在本部分中,您将完成以下步骤:
- 创建两个永久性磁盘。
- 创建一个使用其中一个磁盘的虚拟机。
- 从虚拟机分离磁盘。
- 查看 Cloud Functions 函数代码。
- 部署 Cloud Functions 函数。
- 使用 Cloud Scheduler 作业测试 Cloud Functions 函数。
创建永久性磁盘
在 Cloud Shell 中,切换到
unattached-pd
目录:cd $WORKDIR/unattached-pd
将磁盘的名称导出为环境变量:
export ORPHANED_DISK=orphaned-disk export UNUSED_DISK=unused-disk
创建两个磁盘:
gcloud beta compute disks create $ORPHANED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a gcloud beta compute disks create $UNUSED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a
确认已创建两个磁盘:
gcloud compute disks list
输出如下所示:
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS orphaned-disk us-central1-a zone 500 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY unused-disk us-central1-a zone 500 pd-standard READY
创建一个虚拟机并检查磁盘
在 Cloud Shell 中,创建实例:
gcloud compute instances create disk-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --disk=name=$ORPHANED_DISK,device-name=$ORPHANED_DISK,mode=rw,boot=no
检查挂接到虚拟机的磁盘:
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
输出类似于以下内容:
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "users": [ "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/instances/disk-instance" ], "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
在前面的代码示例中,请注意以下内容:
users
标识挂接该磁盘的虚拟机。lastAttachTimestamp
标识磁盘上次挂接到虚拟机的时间。
检查未挂接到虚拟机的磁盘:
gcloud compute disks describe $UNUSED_DISK \ --zone=us-central1-a \ --format=json | jq
输出类似于以下内容:
{ "creationTimestamp": "2019-06-12T12:21:30.905-07:00", "id": "1313096191791918677", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "name": "unused-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/unused-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
在前面的代码示例中,以下内容至关重要:
- 该磁盘未列出
users
,因为虚拟机当前未使用该磁盘。 - 该磁盘没有
lastAttachedTimestamp
,因为它从未被使用过。
- 该磁盘未列出
从虚拟机分离孤立的永久性磁盘:
gcloud compute instances detach-disk disk-instance \ --device-name=$ORPHANED_DISK \ --zone=us-central1-a
检查孤立的磁盘:
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
输出类似于以下内容:
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "lastDetachTimestamp": "2019-06-12T12:34:56.040-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
在前面的代码示例中,以下内容至关重要:
- 该磁盘未列出
users
,这表明该磁盘当前未被使用。 - 现在有一个
lastDetachTimestamp
条目,指示该磁盘上次与虚拟机分离的时间以及该磁盘的最后一次使用时间。 lastAttachTimestamp
字段仍然存在。
- 该磁盘未列出
查看 Cloud Functions 函数代码
在 Cloud Shell 中,输出检索项目中所有永久性磁盘的代码部分:
cat $WORKDIR/unattached-pd/main.py | grep "(request)" -A 12
输出如下所示:
def delete_unattached_pds(request): # get list of disks and iterate through it: disksRequest = compute.disks().aggregatedList(project=project) while disksRequest is not None: diskResponse = disksRequest.execute() for name, disks_scoped_list in diskResponse['items'].items(): if disks_scoped_list.get('warning') is None: # got disks for disk in disks_scoped_list['disks']: # iterate through disks diskName = disk['name'] diskZone = str((disk['zone'])).rsplit('/',1)[1] print (diskName) print (diskZone)
函数使用
aggregatedList
方法获取 Google Cloud 项目(函数在该项目中运行,并迭代所有磁盘)中的所有永久性磁盘。输出用于检查
lastAttachTimestamp
字段并在该字段不存在的情况下删除磁盘的代码部分:cat $WORKDIR/unattached-pd/main.py | grep "handle never" -A 11
输出如下所示:
# handle never attached disk - delete it # lastAttachedTimestamp is not present if disk.get("lastAttachTimestamp") is None: print ("disk " + diskName + " was never attached - deleting") deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") Continue
如果
lastAttachTimestamp
不存在(表示该磁盘从未被使用过),此部分将删除磁盘。输出用于计算磁盘存在时间(如果是孤立的磁盘)、创建磁盘快照并删除磁盘的代码部分:
cat $WORKDIR/unattached-pd/main.py | grep "handle detached" -A 32
输出如下所示:
# handle detached disk - snapshot and delete # lastAttachTimestamp is present AND users is not present AND it meets the age criterium if disk.get("users") is None \ and disk.get("lastDetachTimestamp") is not None \ and diskAge(disk['lastDetachTimestamp'])>=deleteAge: print ("disk " + diskName + " has no users and has been detached") print ("disk meets age criteria for deletion") # take a snapshot snapShotName = diskName + str(int(time.time())) print ("taking snapshot: " + snapShotName) snapshotBody = { "name": snapShotName } snapshotRequest = compute.disks().createSnapshot(project=project, zone=diskZone, disk=diskName, body=snapshotBody) snapshotResponse = snapshotRequest.execute() waitForZoneOperation(snapshotResponse, project, diskZone) print ("snapshot completed") # delete the disk print ("deleting disk " + diskName) deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") continue
如果磁盘确实列出了
users
并且存在lastDetachTimestamp
,将使用此代码部分,这意味着磁盘当前未被使用,但在某些时候已被使用过。在此情况下,Cloud Functions 函数将创建磁盘的快照以保留数据,然后删除磁盘。
部署 Cloud Functions 函数
在 Cloud Shell 中,部署 Cloud Functions 函数:
gcloud functions deploy delete_unattached_pds \ --trigger-http --runtime=python37
将 Cloud Functions 函数的触发器网址设置为环境变量:
export FUNCTION_URL=$(gcloud functions describe delete_unattached_pds \ --format=json | jq -r '.httpsTrigger.url')
计划并测试 Cloud Functions 函数
在 Cloud Shell 中,创建一个 Cloud Scheduler 任务,以在每天凌晨 2 点运行 Cloud Functions 函数:
gcloud scheduler jobs create http unattached-pd-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
测试作业:
gcloud scheduler jobs run unattached-pd-job
确认已创建孤立磁盘的快照:
gcloud compute snapshots list
输出类似于以下内容:
NAME DISK_SIZE_GB SRC_DISK STATUS orphaned-disk1560455894 500 us-central1-a/disks/orphaned-disk READY
确认已删除未使用的磁盘和孤立的磁盘:
gcloud compute disks list
输出如下所示:
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS disk-instance us-central1-a zone 10 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY
将存储桶迁移到费用更低的存储类别
Google Cloud 提供了存储对象生命周期规则,您可以使用这些规则根据一组属性(例如创建日期或实时状态)将对象自动移动到不同的存储类别。 但是,这些规则无法确定相关对象是否已被访问过。 有时,如果较新的对象已有一段时间未被访问过,您可能需要将其移动到 Nearline 存储空间。
在本部分中,您将完成以下步骤:
- 创建两个 Cloud Storage 存储桶。
- 将对象添加到其中一个存储桶。
- 配置 Monitoring 以观察存储桶对象访问。
- 查看将对象从 Regional Storage 存储桶迁移到 Nearline Storage 存储桶的 Cloud Functions 函数代码。
- 部署 Cloud Functions 函数。
- 使用 Monitoring 提醒测试 Cloud Functions 函数。
创建 Cloud Storage 存储桶并添加文件
在 Cloud Shell 中,切换到
migrate-storage
目录:cd $WORKDIR/migrate-storage
创建
serving-bucket
Cloud Storage 存储桶,以稍后用于更改存储类别:export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-serving-bucket
公开该存储桶:
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket
将文本文件添加到存储桶:
gsutil cp $WORKDIR/migrate-storage/testfile.txt \ gs://${PROJECT_ID}-serving-bucket
公开文件:
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket/testfile.txt
确认您可以访问该文件:
curl http://storage.googleapis.com/${PROJECT_ID}-serving-bucket/testfile.txt
输出如下所示:
this is a test
再创建一个名为
idle-bucket
的存储桶,该存储桶不提供任何数据:gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-idle-bucket
设置 Cloud Monitoring 工作区
在本部分中,您将配置 Cloud Monitoring 以观察存储桶的使用情况,了解何时不会使用存储桶对象。如果服务存储桶未被使用,则 Cloud Functions 函数会将该存储桶从 Regional Storage 类别迁移到 Nearline Storage 类别。
在 Google Cloud 控制台中,前往 Monitoring。
点击新建工作区 (New Workspace),然后点击添加。
等待初始配置完成。
创建 Cloud Monitoring 信息中心
在 Monitoring 中,转到信息中心,然后点击创建信息中心。
点击添加图表。
在名称字段中,输入
Bucket Access
。要查找 Cloud Storage 存储桶的请求内容指标,请在查找资源和指标 (Find resource and metric) 字段中输入
request
,然后为gcs_bucket
资源选择请求数。要按存储桶名称对指标进行分组,请在分组依据下拉列表中,点击
bucket_name
。要按方法名称进行过滤,请在过滤条件字段中输入 ReadObject,然后点击应用。
点击保存。
在名称字段中,输入
Bucket Usage
。要确认信息中心是否可访问,请将鼠标指针悬停在信息中心上,并验证是否显示存储桶使用情况 (Bucket Usage)。
您已配置 Monitoring 以观察存储桶中的对象访问。该图表不显示任何数据,因为没有到 Cloud Storage 存储桶的流量。
为服务存储桶生成负载
配置 Monitoring 后,请使用 Apache Bench 将流量发送到服务存储桶。
在 Cloud Shell 中,将请求发送到服务存储桶中的对象:
ab -n 10000 \ http://storage.googleapis.com/$PROJECT_ID-serving-bucket/testfile.txt
在 Google Cloud 控制台中,转到 Monitoring。
要选择存储桶使用情况 (Bucket Usage) 信息中心,请将鼠标指针悬停在信息中心上并选择存储桶使用情况 (Bucket Usage)。确认流量仅发送到服务存储桶。
request_count metric
时间序列仅会针对服务存储桶显示,因为空闲存储桶没有任何流量。
查看并部署 Cloud Functions 函数
在 Cloud Shell 中,输出使用 Cloud Functions 函数将存储桶迁移到 Nearline Storage 类别的代码:
cat $WORKDIR/migrate-storage/main.py | grep "migrate_storage(" -A 15
输出如下所示:
def migrate_storage(request): # process incoming request to get the bucket to be migrated: request_json = request.get_json(force=True) # bucket names are globally unique bucket_name = request_json['incident']['resource_name'] # create storage client storage_client = storage.Client() # get bucket bucket = storage_client.get_bucket(bucket_name) # update storage class bucket.storage_class = "NEARLINE" bucket.patch()
Cloud Functions 函数使用在请求中传递的存储桶名称将其存储类别更改为 Nearline Storage。
部署 Cloud Functions 函数:
gcloud functions deploy migrate_storage --trigger-http --runtime=python37
将触发器网址设置为在下一部分中使用的环境变量:
export FUNCTION_URL=$(gcloud functions describe migrate_storage \ --format=json | jq -r '.httpsTrigger.url')
测试并验证提醒自动化
设置空闲存储桶的名称:
export IDLE_BUCKET_NAME=$PROJECT_ID-idle-bucket
使用
incident.json
文件将测试通知发送到您部署的 Cloud Functions 函数:envsubst < $WORKDIR/migrate-storage/incident.json | curl -X POST \ -H "Content-Type: application/json" $FUNCTION_URL -d @-
输出如下所示:
OK
输出不会以换行符终止,因此命令提示符会紧随其后。
确认空闲存储桶已迁移到 Nearline 存储空间:
gsutil defstorageclass get gs://$PROJECT_ID-idle-bucket
输出如下所示:
gs://automating-cost-optimization-idle-bucket: NEARLINE
针对生产环境的注意事项
在您自己的 Google Cloud 环境中自动进行费用优化时,请考虑以下事项:
- 一般注意事项:您应该增强可以修改或删除 Google Cloud 资源的 Cloud Functions 函数的安全性。
- 识别浪费:本文档提供了一些支出浪费示例。
此外,还有许多其他示例,这些示例通常属于以下三种类别中的其中一种:
- 超额预配的资源:预配量超过给定工作负载所需量的资源,例如,其 CPU 性能和内存量超出需要的虚拟机。
- 空闲资源:完全未使用的资源。
- 部分时间空闲资源:仅在工作时间使用的资源。
- 自动执行清理:在本文档中,需要执行一个包含多个异步操作的多步过程,以截取磁盘快照并删除磁盘。 其他 Google Cloud 资源(例如未使用的 IP 地址)可以使用同步操作。
- 大规模部署:在本文档中,Google Cloud 项目 ID 在 Cloud Functions 函数代码中定义。如需大规模部署此类解决方案,请考虑使用 Cloud Billing 或 Cloud Resource Manager API 来获取包含结算账号或组织的项目列表。然后,将这些 Google Cloud 项目 ID 作为变量传递给函数。在此类配置中,您需要将 Cloud Functions 函数的服务账号添加到该函数可以在其中清理或删除资源的项目中。我们建议使用自动化部署框架,例如 Cloud Deployment Manager 或 Terraform。
- 提醒自动化:本文档介绍如何使用 Monitoring 提醒中的模拟载荷来触发存储类别迁移。Monitoring 提醒政策的评估时间最长为 23 小时 59 分钟。在生产环境中,此时间限制可能不足以在迁移存储桶的存储类别之前将存储桶视为空闲。请考虑在 Cloud Storage 存储桶上启用数据访问审核日志,并创建一个使用这些审核日志的流水线,以评估存储桶在过去 30 天内是否被用于提供服务。如需了解详情,请查看了解审核日志,并考虑创建汇总接收器以将日志发送到 Pub/Sub 和 Dataflow 流水线进行处理。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
- 在 Google Cloud 控制台中,进入管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
后续步骤
- 观看有关费用管理的视频。
- 访问“费用管理”主页。
- 查看 Cloud Billing 文档。
- 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud Architecture Center。