使用 IoT Edge 上的 Azure Blob 存储在边缘中存储数据
适用于: IoT Edge 1.5 IoT Edge 1.4
重要
IoT Edge 1.5 LTS 和 IoT Edge 1.4 LTS 是受支持的版本。 IoT Edge 1.4 LTS 的生命周期结束日期为 2024 年 11 月 12 日。 如果你使用的是较低的版本,请参阅更新 IoT Edge。
IoT Edge 上的 Azure Blob 存储在边缘提供了块 blob 和追加 Blob 存储解决方案。 IoT Edge 设备上的 Blob 存储模块的行为类似于 Azure blob 服务,但 Blob 存储在本地 IoT Edge 设备上。 你可以使用相同的 Azure 存储 SDK 方法或已经习惯的 blob API 调用来访问 blob。 本文说明与 IoT Edge 容器中的 Azure Blob 存储相关的概念,该容器在 IoT Edge 设备上运行 Blob 服务。
此模块适用于以下方案:
- 需在本地存储数据,直到可以处理或传输到云中。 这些数据可以是图像、财务数据、医疗数据或者任何其他非结构化数据。
- 当设备位于连接受限的位置时。
- 当你希望在本地高效处理数据以低延迟访问数据时,以便能够尽快响应紧急情况。
- 当你希望降低带宽成本并避免将 TB 级数据传输到云时。 可在本地处理数据,并仅将已处理的数据发送到云中。
此模块附带 deviceToCloudUpload 和 deviceAutoDelete 功能。
deviceToCloudUpload 功能是一项可配置的功能。 此函数可将本地 Blob 存储中的数据自动上传到 Azure,并支持间歇性的 Internet 连接。 该功能允许:
- 启用/禁用 deviceToCloudUpload 功能。
- 选择将数据复制到 Azure 的顺序,例如,NewestFirst 或 OldestFirst。
- 指定要将数据上传到的 Azure 存储帐户。
- 指定要上传到 Azure 的容器。 此模块允许指定源和目标容器名称。
- 选择将内容上传到云存储后立即删除 Blob 的功能
- 执行完整 Blob 上传(使用
Put Blob
操作)和块级上传(使用Put Block
Put Block List
和Append Block
操作)。
如果 Blob 由块构成,则此模块使用块级上传。 下面是一些常见场景:
- 应用程序会更新先前上传的块 blob 的某些块,或向追加 blob 追加新块。 此模块仅上传更新后的块,而不是整个 blob。
- 当模块正在上传 Blob 时,Internet 连接断开;连接恢复后,该模块只上传剩余的块,而不上传整个 Blob。
如果在 Blob 上传期间发生意外的进程终止(例如电源故障),当模块重新联机后,将再次上传需要上传的所有块。
deviceAutoDelete 是一个可配置的功能。 超过指定的持续时间(度量单位为分钟)时,此函数将自动从本地存储中删除 Blob。 该功能允许:
- 启用/禁用 deviceAutoDelete 功能。
- 指定以分钟为单位的时间 (deleteAfterMinutes),该时间过后会自动删除这些 Blob。
- 选择在 deleteAfterMinutes 值到期后保留上传的 Blob 的功能。
先决条件
Azure IoT Edge 设备:
可以按照适用于 Linux 或 Windows 设备的快速入门中的步骤,将开发计算机或虚拟机用作 IoT Edge 设备。
有关支持的操作系统和体系结构的列表,请参阅 Azure IoT Edge 支持的系统。 IoT Edge 模块上的 Azure Blob 存储支持以下体系结构:
- Windows AMD64
- Linux AMD64
- Linux ARM32
- Linux ARM64
云资源:
Azure 中的标准层 IoT 中心。
deviceToCloudUpload 和 deviceAutoDelete 属性
使用模块的所需属性设置 deviceToCloudUploadProperties 和 deviceAutoDeleteProperties。 可以在部署期间设置所需属性,或者,以后可以通过编辑模块孪生来更改这些属性,而无需重新部署。 我们建议检查“模块孪生”中的 reported configuration
和 configurationValidation
,以确保正确传播值。
deviceToCloudUploadProperties
此设置的名称为 deviceToCloudUploadProperties
。 如果使用 IoT Edge 模拟器,请将这些属性的值设置为相关环境变量,可以在说明部分中找到它们。
属性 | 可能值 | 解释 |
---|---|---|
uploadOn | true、false | 默认设置为 false 。 若要启用此功能,请将此字段设置为 true 。 环境变量: deviceToCloudUploadProperties__uploadOn={false,true} |
uploadOrder | NewestFirst、OldestFirst | 用于选择将数据复制到 Azure 的顺序。 默认设置为 OldestFirst 。 顺序由 blob 的上次修改时间确定。 环境变量: deviceToCloudUploadProperties__uploadOrder={NewestFirst,OldestFirst} |
cloudStorageConnectionString | "DefaultEndpointsProtocol=https;AccountName=<your Azure Storage Account Name>;AccountKey=<your Azure Storage Account Key>;EndpointSuffix=<your end point suffix>" 是一个连接字符串,用于指定要将数据上传到的存储帐户。 指定 Azure Storage Account Name 、Azure Storage Account Key 或 End point suffix 。 添加用于上传数据的适当 Azure EndpointSuffix,它在全球 Azure、政府 Azure 和 Azure Stack 中是不同的。 可以选择在此处选择指定 Azure 存储 SAS 连接字符串。 但是,在此属性过期时必须将其更新。 SAS 权限可能包括为容器创建访问权限,以及为 blob 创建、写入和添加访问权限。 环境变量: deviceToCloudUploadProperties__cloudStorageConnectionString=<connection string> |
|
storageContainersForUpload | "<source container name1>": {"target": "<target container name>"} 、"<source container name1>": {"target": "%h-%d-%m-%c"} 、"<source container name1>": {"target": "%d-%c"} |
用于指定要上传到 Azure 的容器名称。 此模块允许指定源和目标容器名称。 如果你未指定目标容器名称,系统会自动分配容器名称,例如 <IoTHubName>-<IotEdgeDeviceID>-<ModuleName>-<SourceContainerName> 。 可以创建目标容器名称的模板字符串,具体请查看“可能的值”列。 * %h -> IoT 中心名称(3 到 50 个字符)。 * %d -> IoT Edge 设备 ID(1 到 129 个字符)。 * %m -> 模块名称(1 到 64 个字符)。 * %c -> 源容器名称(3 到 63 个字符)。 容器名称的最大大小为 63 个字符。 如果容器名称的大小超过 63 个字符,系统将自动分配目标容器名称。 在这种情况下,每个节(IoTHubName、IotEdgeDeviceID、ModuleName、SourceContainerName)中的名称将剪裁为 15 个字符。 环境变量: deviceToCloudUploadProperties__storageContainersForUpload__<sourceName>__target=<targetName> |
deleteAfterUpload | true、false | 默认设置为 false 。 如果设置为 true ,在将数据上传到云存储后会自动删除数据。 注意:如果使用的是追加 Blob,则此设置将在上传成功后从本地存储中删除追加 Blob,并且以后对这些块执行的任何追加块操作都将失败。 请慎用此设置。 如果应用程序不经常执行追加操作或者不支持连续追加操作,请不要启用此设置 环境变量: deviceToCloudUploadProperties__deleteAfterUpload={false,true} 。 |
deviceAutoDeleteProperties
此设置的名称为 deviceAutoDeleteProperties
。 如果使用 IoT Edge 模拟器,请将这些属性的值设置为相关环境变量,可以在说明部分中找到它们。
属性 | 可能值 | 解释 |
---|---|---|
deleteOn | true、false | 默认设置为 false 。 若要启用此功能,请将此字段设置为 true 。 环境变量: deviceAutoDeleteProperties__deleteOn={false,true} |
deleteAfterMinutes | <minutes> |
以分钟为单位指定时间。 达到此值时,模块会自动删除本地存储中的 Blob。 当前允许的最大分钟数为 35791。 环境变量: deviceAutoDeleteProperties__ deleteAfterMinutes=<minutes> |
retainWhileUploading | true、false | 此变量默认设置为 true ,如果 deleteAfterMinutes 时间已过,将在上传到云存储时保留 Blob。 可以将其设置为 false ,这样会在 deleteAfterMinutes 时间过后立即删除数据。 注意:要使此属性生效,应将 uploadOn 设置为 true。 注意:如果使用的是追加 Blob,则此设置将在值过期时从本地存储中删除追加 Blob,并且以后对这些块执行的任何追加块操作都将失败。 确保过期时间值足够大,以满足应用程序执行追加操作的预期频率。 环境变量: deviceAutoDeleteProperties__retainWhileUploading={false,true} |
使用 SMB 共享作为本地存储
在 Windows 主机上部署此模块的 Windows 容器时,可以提供 SMB 共享作为本地存储路径。
确保 SMB 共享和 IoT 设备位于相互信任的域中。
可以运行 New-SmbGlobalMapping
PowerShell 命令来映射运行 Windows 的 IoT 设备本地的 SMB 共享。
配置步骤:
$creds = Get-Credential
New-SmbGlobalMapping -RemotePath <remote SMB path> -Credential $creds -LocalPath <Any available drive letter>
例如:
$creds = Get-Credential
New-SmbGlobalMapping -RemotePath \\contosofileserver\share1 -Credential $creds -LocalPath G:
此命令使用凭据对远程 SMB 服务器进行身份验证。 然后,将远程共享路径映射到 G: 驱动器号(可以是任何其他可用的驱动器号)。 现在,IoT 设备的数据卷已映射到 G: 驱动器上的路径。
确保 IoT 设备中的用户可以读取/写入远程 SMB 共享。
在部署中,<storage mount>
的值可以是 G:/ContainerData:C:/BlobRoot。
对 Linux 上的容器用户授予目录访问权限
如果在 Linux 容器的 create 选项中对存储使用了卷装入点作为存储,则无需执行任何额外的步骤;但如果使用了绑定装入点,则需要执行这些步骤才能正常运行服务。
如果遵循最低特权原则将用户的访问权限限制为他们执行其工作所需的最低权限,则此模块将包含一个用户(名称:absie,ID:11000)和一个用户组(名称:absie,ID:11000)。 如果容器以 root 身份启动(默认用户为 root),则我们的服务将以低特权的 absie 用户身份启动。
由于存在此行为,要使服务正常运行,对主机路径绑定的权限配置至关重要,否则服务将会崩溃并出现拒绝访问错误。 目录绑定中使用的路径需可由容器用户(例如 absie 11000)访问。 可以通过在主机上执行以下命令,来为容器用户授予对目录的访问权限:
sudo chown -R 11000:11000 <blob-dir>
sudo chmod -R 700 <blob-dir>
例如:
sudo chown -R 11000:11000 /srv/containerdata
sudo chmod -R 700 /srv/containerdata
如果需要以非 absie 的用户身份运行服务,可以在部署清单中“User”属性下的 createOptions 中指定自定义用户 ID。 在这种情况下,请使用默认 ID 或 root 组 ID 0
。
"createOptions": {
"User": "<custom user ID>:0"
}
现在,为容器用户授予对目录的访问权限
sudo chown -R <user ID>:<group ID> <blob-dir>
sudo chmod -R 700 <blob-dir>
配置日志文件
默认输出日志级别为“Info”。 若要更改输出日志级别,请在部署清单中为此模块设置 LogLevel
环境变量。 LogLevel
接受以下值:
- 严重
- 错误
- 警告
- 信息
- 调试
若要了解如何为模块配置日志文件,请参阅这些生产最佳做法。
连接到 blob 存储模块
可以使用为模块配置的帐户名和帐户密钥来访问 IoT Edge 设备上的 blob 存储。
将你的 IoT Edge 设备指定为对其进行的任何存储请求的 blob 终结点。 你可以使用 IoT Edge 设备信息和配置的帐户名为显式存储终结点创建连接字符串。
- 对于部署在设备上的模块,如果该设备上运行 IoT Edge 上的 Azure Blob 存储模块,则 Blob 终结点为
http://<module name>:11002/<account name>
。 - 对于在其他设备上运行的模块或应用程序,必须为网络选择正确的终结点。 根据网络设置选择终结点格式,使来自外部模块或应用程序的数据流量可以抵达 IoT Edge 模块上运行 Azure Blob 存储的设备。 此方案的 Blob 终结点是下列其中一项:
http://<device IP >:11002/<account name>
http://<IoT Edge device hostname>:11002/<account name>
http://<fully qualified domain name>:11002/<account name>
重要
调用模块时,Azure IoT Edge 区分大小写,存储 SDK 也默认为小写。 为确保与 IoT Edge 上的 Azure Blob 存储模块建立的连接不会中断,请将名称更改为小写。
Azure Blob 存储快速入门示例
Azure Blob 存储文档包括多种语言的快速入门示例代码。 可以通过将 Blob 终结点更改为连接到本地 Blob 存储模块来运行这些示例,以测试 IoT Edge 上的 Azure Blob 存储。
以下快速入门示例使用 IoT Edge 也同样支持的语言,因此,你可以将它们作为 IoT Edge 模块与 Blob 存储模块一起部署:
- .NET
- IoT Edge 上的 Azure Blob 存储模块 v1.4.0 及更早版本与 WindowsAzure.Storage 9.3.3 SDK 兼容,v1.4.1 还支持 Azure.Storage.Blobs 12.8.0 SDK。
- Python
- Python SDK V2.1 之前的版本存在一个已知问题,即模块不返回 Blob 创建时间。 由于该问题,某些方法(如 list blobs)无法正常工作。 解决方法是,将 blob 客户端上的 API 版本显式设置为“2017-04-17”。 示例:
block_blob_service._X_MS_VERSION = '2017-04-17'
- 追加 Blob 示例
- Python SDK V2.1 之前的版本存在一个已知问题,即模块不返回 Blob 创建时间。 由于该问题,某些方法(如 list blobs)无法正常工作。 解决方法是,将 blob 客户端上的 API 版本显式设置为“2017-04-17”。 示例:
- Node.js
- JS/HTML
- Ruby
- Go
- PHP
通过 Azure 存储资源管理器连接到本地存储
可以使用 Azure 存储资源管理器连接到本地存储帐户。
下载并安装 Azure 存储资源管理器
最新版本的 Azure 存储资源管理器使用 Blob 存储模块不支持的较新存储 API 版本。 启动 Azure 存储资源管理器。 选择“编辑”菜单。 验证是否已选择“目标 Azure Stack Hub API”。 如果未选择,请选择“目标 Azure Stack Hub”。 重启 Azure 存储资源管理器以使更改生效。 此配置是必需的,否则无法与 IoT Edge 环境兼容。
使用连接字符串连接到 Azure 存储
提供连接字符串:
DefaultEndpointsProtocol=http;BlobEndpoint=http://<host device name>:11002/<your local account name>;AccountName=<your local account name>;AccountKey=<your local account key>;
完成用于连接的步骤。
在本地存储帐户中创建容器
开始将文件作为块 Blob 或追加 Blob 上传。
注意
此模块不支持页 Blob。
也可以选择在存储资源管理器中连接 Azure 存储帐户。 此配置提供适用于本地存储帐户和 Azure 存储帐户的单一视图
受支持的存储操作
IoT Edge 上的 Blob 存储模块使用 Microsoft Azure 存储 SDK,并与适用于块 Blob 终结点的 2017-04-17 版 Azure 存储 API 保持一致。
由于并非所有 Azure Blob 存储操作都受 IoT Edge 上的 Azure Blob 存储支持,因此此部分列出了每项操作的状态。
帐户
受支持:
- 列出容器
不受支持:
- 获取和设置 blob 服务属性
- 预检 blob 请求
- 获取 blob 服务统计信息
- 获取帐户信息
容器
受支持:
- 创建和删除容器
- 获取容器属性和元数据
- 列出 Blob
- 获取和设置容器 ACL
- 设置容器元数据
不受支持:
- 租用容器
Blob
受支持:
- 放置、获取和删除 blob
- 获取和设置 blob 属性
- 获取和设置 blob 元数据
不受支持:
- 租用 blob
- 获取 blob 快照
- 复制和中止复制 blob
- 撤销删除 blob
- 设置 blob 层
块 Blob
受支持:
- 放置块
- 放置和获取阻止列表
不受支持:
- 放置来自 URL 的块
追加 Blob
受支持:
- 追加块
不受支持:
- 来自 URL 的追加块
IoT Edge 集成上的事件网格
注意
IoT Edge 与事件网格的集成处于预览阶段
IoT Edge 模块上的 Azure Blob 存储现在提供与 IoT Edge 事件网格的集成。
发行说明
以下是此模块在 Docker 中心的发行说明。 你可以在特定版本的发行说明中找到有关 Bug 修复和修正的详细信息。
后续步骤
了解如何在 IoT Edge 上部署 Azure Blob 存储
关注 IoT Edge 上的Azure Blob 存储博客,随时了解最新的更新和公告