使用 DLP API 和 Cloud Functions 对上传到 Cloud Storage 的数据自动分类

1. 概览

在当今的组织中,来自各种来源的数据量不断增加。这通常需要隔离和分类这些数据,以便有策略地存储和保护它们。如果仍然手动执行此任务,很快就会变得成本高昂且无法完成。

在此 Codelab 中,我们将了解如何自动对上传到 Cloud Storage 的数据进行分类,并将其移至相应的存储分区。我们将使用 Cloud Pub/Sub、Cloud Functions、Cloud Data Loss Prevention 和 Cloud Storage 来实现此目的。

您将执行的操作

  • 创建 Cloud Storage 存储分区,将其用于隔离和分类流水线。
  • 创建一个在上传文件后调用 DLP API 的简单 Cloud Functions 函数。
  • 创建 Pub/Sub 主题和订阅,以在文件处理完成时向您发出通知。
  • 将示例文件上传到隔离区以调用 Cloud Functions 函数
  • 使用 DLP API 对文件进行检查和分类,并将其移动到合适的存储分区。

所需条件

  • 已设置结算功能的 Google Cloud 项目。如果您没有 Google 账号,则必须创建一个

2. 准备工作

在此 Codelab 中,我们将使用 Cloud Shell 通过命令行预配和管理不同的云资源和服务。以下命令将打开 Cloud Shell 和 Cloud Shell 编辑器,并克隆配套项目代码库:

使用 gcloud config set project [PROJECT_ID] 设置项目,确保您使用的是正确的项目

启用 API

在 Google Cloud 项目中启用所需的 API:

  • Cloud Functions API - 管理轻量级用户提供的为响应事件而执行的函数。
  • Cloud Data Loss Prevention (DLP) API - 提供用于对文本、图片及 Google Cloud Platform 存储库中的敏感隐私信息片段进行检测、风险分析和去标识化的方法。
  • Cloud Storage - Google Cloud Storage 是一项 RESTful 服务,用于在 Google 的基础架构上存储和访问数据。

服务账号权限

服务账号是一种特殊类型的账号,应用和虚拟机可以使用此类账号执行已获授权的 API 调用。

App Engine 默认服务账号

App Engine 默认服务账号用于代表在 App Engine 中运行的应用在您的云项目中执行任务。默认情况下,此服务账号存在于您的项目中,并被分配了 Editor 角色。

首先,我们将向服务账号授予管理数据泄露防护作业所需的 DLP 管理员角色:

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member serviceAccount:$GOOGLE_CLOUD_PROJECT@appspot.gserviceaccount.com \
--role roles/dlp.admin

最后,授予 DLP API Service Agent 角色,该角色将允许服务账号拥有 bigquery、存储、数据存储区、pubsub 和密钥管理服务的权限:

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member serviceAccount:$GOOGLE_CLOUD_PROJECT@appspot.gserviceaccount.com \
--role roles/dlp.serviceAgent

DLP 服务账号

除了 App Engine 服务账号之外,我们还将使用 DLP 服务账号。此服务账号是在启用 DLP API 时自动创建的,最初未被授予任何角色。我们来授予该账号查看者角色:

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member serviceAccount:service-`gcloud projects list --filter="PROJECT_ID:$GOOGLE_CLOUD_PROJECT" --format="value(PROJECT_NUMBER)"`@dlp-api.iam.gserviceaccount.com \
--role roles/viewer

3. Cloud Storage 存储分区

现在,我们需要创建 3 个 Cloud Storage 存储分区来存储数据:

  • 隔离区存储分区:我们的数据最初会上传到这里。
  • 敏感数据存储分区:DLP API 确定为敏感数据的数据将移至此处。
  • 非敏感数据桶:DLP API 确定为非敏感的数据将移至此处

我们可以使用 gsutil 命令一次性创建所有三个存储分区:

gsutil mb gs://[YOUR_QUARANTINE_BUCKET] \
gs://[YOUR_SENSITIVE_DATA_BUCKET] \
gs://[YOUR_NON_SENSITIVE_DATA_BUCKET] 

记下您刚刚创建的存储分区的名称,稍后会用到。

4. Pub/Sub 主题和订阅

Cloud Pub/Sub 可在应用之间提供多对多的异步消息传递服务。发布者会创建消息并将其发布到称为主题的消息 Feed 中。订阅者将通过订阅接收这些消息。根据该订阅,在本例中,我们将在 DLP 作业运行后让 Cloud Functions 函数将文件移动到各自的存储分区。

首先,我们来创建一个主题。每次向隔离区存储分区添加文件时,系统都会在此处发布一条消息。我们将其命名为“classify-topic”

gcloud pubsub topics create classify-topic

当主题发布消息时,订阅会收到通知。我们来创建一个名为“classify-sub”的 Pub/Sub 订阅:

gcloud pubsub subscriptions create classify-sub --topic classify-topic

该订阅将触发第二个 Cloud Functions 函数,该函数将启动 DLP 作业,以检查文件并将其移动到相应位置。

5. Cloud Functions

借助 Cloud Functions,我们可以部署基于事件的轻量级异步单一用途函数,而无需管理服务器或运行时环境。我们将使用位于 dlp-cloud-functions-tutorials/gcs-dlp-classification-python/ 中的 main.py 文件部署 2 个 Cloud Functions 函数

替换变量

在创建函数之前,我们需要替换 main.py 文件中的一些变量。

在 Cloud Shell 编辑器中,调整 main.py,将第 28 行到第 34 行的项目 ID 和存储分区变量的值替换为之前创建的相应存储分区:

main.py

PROJECT_ID = '[PROJECT_ID_HOSTING_STAGING_BUCKET]'
"""The bucket the to-be-scanned files are uploaded to."""
STAGING_BUCKET = '[YOUR_QUARANTINE_BUCKET]'
"""The bucket to move "sensitive" files to."""
SENSITIVE_BUCKET = '[YOUR_SENSITIVE_DATA_BUCKET]'
"""The bucket to move "non sensitive" files to."""
NONSENSITIVE_BUCKET = '[YOUR_NON_SENSITIVE_DATA_BUCKET]'

此外,请将 Pub/Sub 主题变量的值替换为上一步中创建的 Pub/Sub 主题:

""" Pub/Sub topic to notify once the  DLP job completes."""
PUB_SUB_TOPIC = 'classify-topic'

部署函数

在 Cloud Shell 中,将目录更改为 gcs-dlp-classification-python(main.py 文件位于该目录中):

cd ~/cloudshell_open/dlp-cloud-functions-tutorials/gcs-dlp-classification-python

现在可以部署一些函数了。

首先,部署 create_DLP_job 函数,并将 [YOUR_QUARANTINE_BUCKET] 替换为正确的存储分区名称。当新文件上传到指定的 Cloud Storage 隔离区存储分区时,此函数会被触发,并会为每个上传的文件创建一个 DLP 作业:

gcloud functions deploy create_DLP_job --runtime python37 \
--trigger-event google.storage.object.finalize \
--trigger-resource [YOUR_QUARANTINE_BUCKET]

接下来,部署 resolve_DLP 函数,并将我们的主题指定为该函数的触发器。此函数会监听由上述函数中的后续 DLP 作业启动的 Pub/Sub 通知。在收到 Pub/Sub 通知后,它会立即从 DLP 作业中提取结果,并相应地将文件移至敏感数据存储分区或非敏感数据存储分区:

gcloud functions deploy resolve_DLP --runtime python37 \
--trigger-topic classify-topic

验证

使用 gcloud functions describe 命令验证两个 Cloud Functions 函数是否已成功部署:

gcloud functions describe create_DLP_job
gcloud functions describe resolve_DLP

成功部署后,输出中的状态将显示为 ACTIVE

6. 使用示例数据进行测试

所有部分都已就位,现在我们可以使用一些示例文件进行测试了。在 Cloud Shell 中,将当前工作目录更改为 sample_data

cd ~/cloudshell_open/dlp-cloud-functions-tutorials/sample_data

我们的示例文件包含 txt 文件和 csv 文件,其中包含各种数据。以“sample_s”为前缀的文件将包含敏感数据,而以“sample_n”为前缀的文件则不会包含敏感数据。例如,sample_s20.csv 包含格式类似于美国社会保障号的内容:

sample_s20.csv

Name,SSN,metric 1,metric 2
Maria Johnson,284-73-5110,5,43
Tyler Parker,284-73-5110,8,17
Maria Johnson,284-73-5110,54,63
Maria Johnson,245-25-8698,53,19
Tyler Parker,475-15-8499,6,67
Maria Johnson,719-12-6560,75,83
Maria Johnson,616-69-3226,91,13
Tzvika Roberts,245-25-8698,94,61

另一方面,sample_n15.csv 中的数据不会被视为敏感数据:

sample_n15.csv

record id,metric 1,metric 2,metric 3
1,59,93,100
2,53,13,17
3,59,67,53
4,52,93,34
5,14,22,88
6,18,88,3
7,32,49,5
8,93,46,14

为了了解我们的设置将如何处理文件,我们先将所有测试文件上传到隔离区

存储分区:

gsutil -m cp * gs://[YOUR_QUARANTINE_BUCKET]

最初,我们的文件将位于我们上传到的隔离存储分区中。如需验证这一点,请在上传文件后立即列出隔离存储分区的内容:

gsutil ls gs://[YOUR_QUARANTINE_BUCKET]

如需查看我们已启动的一系列事件,请先前往 Cloud Functions 页面:

点击 create_DLP_job 函数的“操作”菜单,然后选择“查看日志”:

89211a959bf30392.png

在针对此函数的日志中,我们看到每个文件至少有 4 个条目,分别表示:

  • 函数执行已开始
  • 该函数已针对特定文件触发
  • 已创建作业
  • 函数已完成执行

c864dff5a03c75a9.png

当 create_DLP_job 函数针对每个文件完成时,系统会启动相应的 DLP 作业。前往 DLP 作业页面,查看队列中的 DLP 作业列表:

您会看到一个列表,其中包含处于“待处理”“正在运行”或“已完成”状态的作业。它们分别对应于我们上传的某个文件:

6af34e72ecb83faf.png

您可以点击其中任何作业的 ID 以查看更多详细信息。

如果您返回到 Cloud Functions 页面并查看 resolve_DLP 函数的日志,您会看到每个文件至少有 8 个条目,这些条目表示:

  • 函数执行已开始
  • 收到了 Pub/Sub 通知
  • 相应 DLP 作业的名称
  • 状态代码
  • 敏感数据的实例数(如有)
  • 文件将移至的存储分区
  • DLP 作业已完成文件解析
  • 函数已完成执行

5025bd672cba90a0.png

在对 resolve_DLP 函数的所有调用都运行完毕后,再次查看隔离桶的内容:

gsutil ls gs://[YOUR_QUARANTINE_BUCKET]

这次,它应该完全为空。不过,如果您针对其他存储分区运行上述相同命令,就会发现我们的文件已完美地分离到各自对应的存储分区中!

7. 清理

现在,我们已经了解了如何结合使用 DLP API 和 Cloud Functions 来对数据进行分类,接下来我们来清理项目中创建的所有资源。

删除项目

如果您愿意,可以删除整个项目。 在 GCP Console 中,转到 Cloud Resource Manager 页面:

在项目列表中,选择我们一直使用的项目,然后点击删除。此时,系统会提示您输入项目 ID。输入项目 ID,然后点击关停

此外,您也可以使用 gcloud 直接从 Cloud Shell 中删除整个项目:

gcloud projects delete [PROJECT_ID]

如果您想逐个删除不同的组件,请继续阅读下一部分。

Cloud Functions

使用 gcloud 删除我们的两个 Cloud Functions 函数:

gcloud functions delete -q create_DLP_job && gcloud functions delete -q resolve_DLP

存储分区

使用 gsutil 移除所有已上传的文件并删除相应存储分区:

gsutil rm -r gs://[YOUR_QUARANTINE_BUCKET] \
gs://[YOUR_SENSITIVE_DATA_BUCKET] \
gs://[YOUR_NON_SENSITIVE_DATA_BUCKET] 

Pub/Sub

首先,使用 gcloud 删除 Pub/Sub 订阅:

gcloud pubsub subscriptions delete classify-sub

最后,使用 gcloud 删除 Pub/Sub 主题:

gcloud pubsub topics delete classify-topic

8. 恭喜!

棒棒哒!大功告成!您已了解如何将 DLP API 与 Cloud Functions 搭配使用,以自动对文件进行分类!

所学内容

  • 我们创建了 Cloud Storage 存储分区来存储敏感数据和非敏感数据
  • 我们创建了一个 Pub/Sub 主题和订阅,以触发 Cloud Functions 函数
  • 我们创建了 Cloud Functions,旨在启动 DLP 作业,该作业会根据文件中包含的敏感数据对文件进行分类
  • 我们上传了测试数据,并查看了 Cloud Functions 函数的 Stackdriver 日志,以了解该流程的实际运行情况