清理未使用的 IP 地址
实验
20 分钟
universal_currency_alt
5 个点数
show_chart
中级
info
此实验可能会提供 AI 工具来支持您学习。
此内容尚未针对移动设备进行优化。
为获得最佳体验,请在桌面设备上访问通过电子邮件发送的链接。
GSP646

概览
在本实验中,您将使用 Cloud Run functions 和 Cloud Scheduler 来识别和清理浪费的云资源。在 Google Cloud 上,附加到负载均衡器或虚拟机 (VM) 实例的静态 IP 地址属于免费资源。如果某个静态 IP 地址被预留,但未被使用,则该地址将按小时收费。在高度依赖静态 IP 地址和大规模动态预配的应用中,这种浪费可能会随时间推移而变得非常严重。
您将执行的操作
- 使用静态外部 IP 地址和未使用的单独静态外部 IP 地址创建 Compute Engine 虚拟机。
- 部署 Cloud Run 函数来识别未使用的 IP 地址
- 创建一项 Cloud Scheduler 作业,以使用 HTTP 触发器安排函数运行
架构
下图描述了本实验第一部分中使用的架构,在该架构中,您安排了一个 Cloud Run 函数来识别和清理未使用的 IP 地址。

设置和要求
在本部分中,您将配置完成本实验所需的基础设施和身份。
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。为此,我们会向您提供新的临时凭据,您可以在该实验的规定时间内通过此凭据登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的互联网浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式(推荐)或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
注意:请仅使用学生账号完成本实验。如果您使用其他 Google Cloud 账号,则可能会向该账号收取费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个对话框供您选择支付方式。左侧是“实验详细信息”窗格,其中包含以下各项:
- “打开 Google Cloud 控制台”按钮
- 剩余时间
- 进行该实验时必须使用的临时凭据
- 帮助您逐步完成本实验所需的其他信息(如果需要)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示“登录”页面。
提示:将这些标签页安排在不同的窗口中,并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在“实验详细信息”窗格中找到“用户名”。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在“实验详细信息”窗格中找到“密码”。
-
点击下一步。
重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭据。
注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
继续在后续页面中点击以完成相应操作:
- 接受条款及条件。
- 由于这是临时账号,请勿添加账号恢复选项或双重验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需访问 Google Cloud 产品和服务,请点击导航菜单,或在搜索字段中输入服务或产品的名称。
激活 Cloud Shell
Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。
-
点击 Google Cloud 控制台顶部的激活 Cloud Shell
。
-
在弹出的窗口中执行以下操作:
- 继续完成 Cloud Shell 信息窗口中的设置。
- 授权 Cloud Shell 使用您的凭据进行 Google Cloud API 调用。
如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 Project_ID 。输出内容中有一行说明了此会话的 Project_ID:
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud 是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
- 点击授权。
输出:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南。
任务 1. 启用 API 并克隆代码库
-
在 Cloud Shell 中,启用 Cloud Scheduler API:
gcloud services enable cloudscheduler.googleapis.com
注意:启用 Cloud Scheduler API 需要一段时间。
点击检查我的进度以验证是否完成了以下目标:
启用 Cloud Scheduler API
-
克隆代码库:
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)
export region={{{project_0.default_region | Region}}}
WORKDIR=$(pwd)
任务 2. 创建 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={{{project_0.default_region | Region}}}
gcloud compute addresses create $UNUSED_IP --project=$PROJECT_ID --region={{{project_0.default_region | Region}}}
本实验使用 区域,但您可以选择其他区域并在本实验的其余部分中始终引用该区域。
-
确认已创建两个地址:
gcloud compute addresses list --filter="region:({{{project_0.default_region | Region}}})"
在输出中,状态 RESERVED 表示 IP 地址未使用:
NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
unused-ip-address 35.232.144.85 EXTERNAL {{{project_0.default_region | Region}}} RESERVED
used-ip-address 104.197.56.87 EXTERNAL {{{project_0.default_region | Region}}} RESERVED
点击检查我的进度以验证是否完成了以下目标:
创建两个静态 IP 地址
-
将已使用的 IP 地址设置为环境变量:
export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP --region={{{project_0.default_region | Region}}} --format=json | jq -r '.address')
任务 3. 创建虚拟机
-
在 Cloud Shell 中,创建一个实例:
gcloud compute instances create static-ip-instance \
--zone={{{project_0.default_zone | Zone}}} \
--machine-type=e2-medium \
--subnet=default \
--address=$USED_IP_ADDRESS
点击检查我的进度以验证是否完成了以下目标:
使用之前创建的静态 IP 地址创建一个实例。
-
确认现在正使用其中一个 IP 地址:
gcloud compute addresses list --filter="region:({{{project_0.default_region | Region}}})"
输出类似于以下内容:
NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
unused-ip-address 35.232.144.85 EXTERNAL {{{project_0.default_region | Region}}} RESERVED
used-ip-address 104.197.56.87 EXTERNAL {{{project_0.default_region | Region}}} IN_USE
任务 4. 查看 Cloud Run 函数代码
输出如下所示:
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:
if (metadata.status=='RESERVED'){
// compute age by converting ISO 8601 timestamps to Date
var creationDate = new Date(metadata.creationTimestamp);
var currDate = new Date();
var addressAge = Math.floor((currDate - creationDate)/86400e3);;
// delete address
item.delete(function(err, operation, apiResponse2){
if (err) {
console.log("could not delete address: " + err);
}
})
}
在前面的代码示例中,以下内容至关重要:
-
compute.getAddresses(function(err, addresses) 使用 getAddresses 方法检索项目中所有区域的 IP 地址。
-
item.getMetadata(function(err, metadata, apiResponse) 获取每个 IP 地址的元数据并检查其 STATUS 字段。
-
if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){ 检查 IP 地址是否已被使用,并使用辅助函数计算其存在时间,然后将其存在时间与常量(在本实验中设置为 0)进行比较。
-
item.delete(function(err, operation, apiResponse2){ 用于删除 IP 地址。
任务 5. 部署 Cloud Run 函数
-
停用 Cloud Functions API:
gcloud services disable cloudfunctions.googleapis.com
-
重新启用 Cloud Functions API:
gcloud services enable cloudfunctions.googleapis.com
-
为您的 appspot 服务账号添加 artifactregistry.reader 权限。将 [PROJECT_ID] 替换为您的 QwikLabs 项目 ID。
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member="serviceAccount:[PROJECT_ID]@appspot.gserviceaccount.com" \
--role="roles/artifactregistry.reader"
-
在 Cloud Shell 中,部署 Cloud Run 函数:
gcloud functions deploy unused_ip_function --gen2 --trigger-http --runtime=nodejs20 --region={{{project_0.default_region | Region}}}
- 如果出现提示,请输入 Y 以允许未经身份验证的调用。
注意:部署 Cloud Run 函数可能需要 2-5 分钟,具体取决于区域。
点击检查我的进度以验证是否完成了以下目标:
部署 Cloud Run 函数
-
将触发器网址设置为环境变量:
export FUNCTION_URL=$(gcloud functions describe unused_ip_function --region={{{project_0.default_region | Region}}} --format=json | jq -r '.url')
任务 6. 安排并测试 Cloud Run 函数
-
在 Cloud Shell 中,创建一个 App Engine 应用,以便使用 Cloud Scheduler:
gcloud app create --region {{{project_0.startup_script.app_region | REGION}}}
-
在 Cloud Shell 中,创建一项 Cloud Scheduler 任务,以在每天凌晨 2 点运行 Cloud Run 函数:
gcloud scheduler jobs create http unused-ip-job \
--schedule="* 2 * * *" \
--uri=$FUNCTION_URL \
--location={{{project_0.default_region | Region}}}
点击检查我的进度以验证是否完成了以下目标:
创建 App Engine 应用
-
通过手动触发来测试该作业:
gcloud scheduler jobs run unused-ip-job \
--location={{{project_0.default_region | Region}}}
您应该不会收到任何输出。
点击检查我的进度以验证是否完成了以下目标:
运行 Cloud Scheduler 作业
-
确认已删除未使用的 IP 地址:
gcloud compute addresses list --filter="region:({{{project_0.default_region | Region}}})"
输出类似于以下内容:
NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
used-ip-address 104.197.56.87 EXTERNAL {{{project_0.default_region | Region}}} IN_USE
点击检查我的进度以验证是否完成了以下目标:
确认已删除未使用的 IP 地址
恭喜!
在本实验中,您完成了以下任务:
- 使用静态外部 IP 地址和未使用的单独静态外部 IP 地址创建了 Compute Engine 虚拟机。
- 部署了 Cloud Run 函数来识别未使用的 IP 地址
- 创建了一项 Cloud Scheduler 作业,以使用 HTTP 触发器安排函数运行
Google Cloud 培训和认证
…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您核实并证明您在 Google Cloud 技术方面的技能与专业知识。
上次更新手册的时间:2025 年 1 月 15 日
上次测试实验的时间:2025 年 1 月 15 日
版权所有 2026 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。