你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
有关监视 Azure Blob 存储的最佳做法
本文介绍一系列常用的存储监视方案,并提供用于实现这些方案的最佳做法指导。
识别不使用的或很少使用的存储帐户
存储见解是基于 Azure 存储指标和日志构建的仪表板。 可以使用存储见解来检查所有帐户的事务量和已用容量。 这些信息可帮助你确定要停用哪些帐户。 若要配置存储见解,请参阅使用 Azure Monitor 存储见解监视存储服务。
分析事务量
通过 Azure Monitor 中的存储见解视图,使用“事务”列将帐户按升序排序。 下图显示了在指定时段内事务量较低的帐户。
单击帐户链接了解有关这些事务的详细信息。 在此示例中,大多数请求都是对 Blob 存储服务发出的。
若要确定发出的请求类型,请深入钻取到“按 API 名称列出的事务”图表。
在此示例中,所有请求都是列出操作或者对帐户属性信息的请求。 没有读取和写入事务。 这可能会让你觉得该帐户未得到有效利用。
分析已用容量
通过 Azure Monitor 中的存储见解视图的“容量”选项卡 ,使用“帐户已用容量”列将帐户按升序排序 。 下图显示某个帐户的容量低于其他帐户。
若要检查与此已用容量关联的 Blob,可以使用存储资源管理器。 如果有大量的 Blob,请考虑使用 Blob 清单策略生成报告。
监视容器的使用
如果按容器将客户数据分区,则可以监视每个客户使用了多少容量。 可以使用 Azure 存储 Blob 清单来创建包含大小信息的 Blob 清单。 然后,可以在容器级别聚合大小和计数。 有关示例,请参阅使用 Azure 存储空间清单计算每个容器的 Blob 计数和总大小。
还可以通过查询日志来计算容器级别的流量。 若要详细了解如何编写 Log Analytics 查询,请参阅 Log Analytics。 若要详细了解存储日志架构,请参阅 Azure Blob 存储监视数据参考。
以下查询获取读取事务数量,以及在每个容器上读取的字节数。
StorageBlobLogs
| where OperationName == "GetBlob"
| extend ContainerName = split(parse_url(Uri).Path, "/")[1]
| summarize ReadSize = sum(ResponseBodySize), ReadCount = count() by tostring(ContainerName)
以下查询使用类似的查询来获取有关写入操作的信息。
StorageBlobLogs
| where OperationName == "PutBlob" or
OperationName == "PutBlock" or
OperationName == "PutBlockList" or
OperationName == "AppendBlock" or
OperationName == "SnapshotBlob" or
OperationName == "CopyBlob" or
OperationName == "SetBlobTier"
| extend ContainerName = split(parse_url(Uri).Path, "/")[1]
| summarize WriteSize = sum(RequestBodySize), WriteCount = count() by tostring(ContainerName)
以上查询引用多个操作的名称,因为有多种类型的操作可以算作写入操作。 若要详细了解哪些操作被视为读取操作和写入操作,请参阅 Azure Blob 存储定价或 Azure Data Lake Storage 定价。
审核帐户活动
在许多情况下,需要审核存储帐户的活动以确保安全性与合规性。 针对存储帐户的操作分为两种类别:控制平面操作和数据平面操作 。
控制平面操作是用于创建存储帐户或更新现有存储帐户的属性的任何 Azure 资源管理器请求。 有关详细信息,请参阅 Azure 资源管理器。
数据平面操作是由于对存储服务终结点发出的请求而针对存储帐户中的数据执行的操作。 例如,在将 Blob 上传到存储帐户或者从存储帐户下载 Blob 时,就会执行数据平面操作。 有关详细信息,请参阅 Azure 存储 API。
本部分介绍如何识别控制平面和数据平面操作的“时间”、“用户”、“内容”和“方式”信息。
审核控制平面操作
资源管理器操作会捕获到 Azure 活动日志中。 若要查看活动日志,请在 Azure 门户中打开你的存储帐户,然后选择“活动日志”。
打开任一日志条目以查看描述该活动的 JSON。 以下 JSON 显示了控制平面操作的“时间”、“内容”和“方式”信息:
是否提供“用户”信息取决于用于执行控制平面操作的身份验证方法。 如果授权是由 Microsoft Entra 安全主体执行的,则该安全主体的对象标识符也会显示在此 JSON 输出中(例如:"http://schemas.microsoft.com/identity/claims/objectidentifier": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
)。 由于你不一定总能看到其他与标识相关的信息(例如电子邮件地址或姓名),因此对象标识符始终是唯一标识安全主体的最佳方式。
可以通过获取对象标识符的值并在 Azure 门户的“Microsoft Entra ID”页中搜索安全主体,找到该安全主体的易记名称。 以下屏幕截图显示了 Microsoft Entra ID 中的搜索结果。
审核数据平面操作
数据平面操作会捕获到适用于存储的 Azure 资源日志中。 你可以配置诊断设置以将日志导出到 Log Analytics 工作区,从而获得本机查询体验。
以下 Log Analytics 查询将检索日志条目列表中的“时间”、“用户”、“内容”和“方式”信息。
StorageBlobLogs
| where TimeGenerated > ago(3d)
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri
对于审核的“时间”部分,TimeGenerated
字段显示日志条目的记录时间。
对于审核的“内容”部分,Uri
字段显示已修改或读取的项。
对于审核的“方式”部分,OperationName
字段显示执行的操作。
提示
例如,如果怀疑某个 Blob 或容器已被错误删除,则添加一个 where
子句,该子句仅返回 OperationName
设置为“删除 blob”或“删除容器”的日志条目。
对于审核的“用户”部分,AuthenticationType
显示用于发出请求的身份验证类型。 此字段可以显示 Azure 存储支持的任何身份验证类型,包括使用帐户密钥、SAS 令牌或 Microsoft Entra 身份验证。
如果请求是使用 Microsoft Entra ID 授权的,则可以使用 RequestObjectId
字段来标识“谁”。 共享密钥和 SAS 身份验证不提供审核单个标识的方式。 在这些情况下,callerIPAddress
和 userAgentHeader
字段可能有助于确定操作的源。 如果使用 SAS 令牌来授权操作,则可以标识该令牌,并且如果已将令牌映射到你方的令牌接收方,则可以确定哪个用户、组织或应用程序执行了该操作。 请参阅标识用于授权请求的 SAS 令牌。
标识用于授权请求的安全主体
如果已使用 Microsoft Entra ID 对请求进行身份验证,则 RequesterObjectId
字段将提供用于标识安全主体的最可靠方式。 可以通过获取 RequesterObjectId
字段的值并在 Azure 门户的“Microsoft Entra ID”页中搜索安全主体,找到该安全主体的易记名称。 以下屏幕截图显示了 Microsoft Entra ID 中的搜索结果。
在某些情况下,用户主体名称 (UPN) 可能会显示在日志中。 例如,如果安全主体是 Microsoft Entra 用户,则可能会显示 UPN。 对于其他类型的安全主体(例如用户分配的托管标识,或某些方案中使用的跨 Microsoft Entra 租户身份验证),UPN 不会显示在日志中。
此查询显示 OAuth 安全主体执行的所有读取操作。
StorageBlobLogs
| where TimeGenerated > ago(3d)
and OperationName == "GetBlob"
and AuthenticationType == "OAuth"
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri
共享密钥和 SAS 身份验证不提供审核单个标识的方式。 因此,如果你要提高基于标识进行审核的能力,我们建议过渡到 Microsoft Entra ID,并阻止共享密钥和 SAS 身份验证。 若要了解如何阻止共享密钥和 SAS 身份验证,请参阅阻止对 Azure 存储帐户进行共享密钥授权。 若要开始使用 Microsoft Entra ID,请参阅使用 Microsoft Entra ID 授权访问 blob。
标识用于授权请求的 SAS 令牌
可以查询使用 SAS 令牌授权的操作。 例如,此查询返回使用 SAS 令牌授权的所有写入操作。
StorageBlobLogs
| where TimeGenerated > ago(3d)
and OperationName == "PutBlob"
and AuthenticationType == "SAS"
| project TimeGenerated, AuthenticationType, AuthenticationHash, OperationName, Uri
出于安全原因,不会在日志中显示 SAS 令牌。 但是,SAS 令牌签名的 SHA-256 哈希将显示在此查询返回的 AuthenticationHash
字段中。
如果分发了多个 SAS 令牌,并且想要了解正在使用的 SAS 令牌,则必须将每个 SAS 令牌的签名部分转换为 SHA-256 哈希,然后将该哈希与日志中显示的哈希值进行比较。
首先解码每个 SAS 令牌字符串。 以下示例使用 PowerShell 解码 SAS 令牌字符串的签名部分。
[uri]::UnescapeDataString("<SAS signature here>")
可以使用任何工具或 SDK 将解码的签名转换为具有该签名的 SHA-256。 例如,在 Linux 系统上,可以使用以下命令:
echo -n "<Decoded SAS signature>" | python3 -c "import sys; from urllib.parse import unquote; print(unquote(sys.stdin.read()), end='');" | sha256sum
转换解码签名的另一种方法是在使用 Azure 数据资源管理器时,将解码的字符串作为查询的一部分传递给 hash_sha256() 函数。
SAS 令牌不包含标识信息。 要跟踪用户或组织的活动,一种方式是保留用户或组织到各种 SAS 令牌哈希的映射。
优化不经常使用的查询的成本
可将日志导出到 Log Analytics 以使用丰富的本机查询功能。 如果存储帐户中有大量的事务,在 Log Analytics 中使用日志所产生的成本可能很高。 有关详细信息,请参阅 Azure Log Analytics 定价。 如果你仅打算偶尔查询日志(例如,出于合规性审核目的查询日志),可以考虑将日志导出到存储帐户,然后基于日志数据使用某种无服务器查询解决方案(例如 Azure Synapse),从而降低总体成本。
借助 Azure Synapse,可以创建无服务器 SQL 池以按需查询日志数据。 这可以大幅节省成本。
将日志导出到存储帐户。 有关详细信息,请参阅创建诊断设置。
创建并配置 Synapse 工作区。 有关详细信息,请参阅快速入门:创建 Synapse 工作区。
查询日志。 有关详细信息,请参阅在 Azure Synapse Analytics 中使用无服务器 SQL 池查询 JSON 文件。
下面是一个示例:
select JSON_VALUE(doc, '$.time') AS time, JSON_VALUE(doc, '$.properties.accountName') AS accountName, JSON_VALUE(doc, '$.identity.type') AS identityType, JSON_VALUE(doc, '$.identity.requester.objectId') AS requesterObjectId, JSON_VALUE(doc, '$.operationName') AS operationName, JSON_VALUE(doc, '$.callerIpAddress') AS callerIpAddress, JSON_VALUE(doc, '$.uri') AS uri doc from openrowset( bulk 'https://demo2uswest4log.blob.core.windows.net/insights-logs-storageread/resourceId=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mytestrp/providers/Microsoft.Storage/storageAccounts/demo2uswest/blobServices/default/y=2021/m=03/d=19/h=*/m=*/PT1H.json', format = 'csv', fieldterminator ='0x0b', fieldquote = '0x0b' ) with (doc nvarchar(max)) as rows order by JSON_VALUE(doc, '$.time') desc