如何使用 Amazon 命令行界面配置本地资源访问 - Amazon IoT Greengrass
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon IoT Greengrass Version 1 2023 年 6 月 30 日进入延长寿命阶段。有关更多信息,请参阅 Amazon IoT Greengrass V1 维护策略。在此日期之后,将 Amazon IoT Greengrass V1 不会发布提供功能、增强功能、错误修复或安全补丁的更新。在上面运行的设备 Amazon IoT Greengrass V1 不会中断,将继续运行并连接到云端。我们强烈建议您迁移到 Amazon IoT Greengrass Version 2,这样可以添加重要的新功能支持其他平台

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

如何使用 Amazon 命令行界面配置本地资源访问

此功能适用于 Amazon IoT Greengrass Core v1.3 及更高版本。

要使用本地资源,您必须在部署到 Greengrass 核心设备的组定义中添加资源定义。该组定义还必须包含一个 Lambda 函数定义,以便在其中向 Lambda 函数授予本地资源的访问权限。有关更多信息(包括要求和约束),请参阅使用 Lambda 函数和连接器访问本地资源

本教程介绍了使用 Amazon Command Line Interface (CLI) 创建本地资源并配置其访问权限的过程。要执行本教程中的步骤,您必须已创建一个 Greengrass 组,如开始使用 Amazon IoT Greengrass 中所述。

有关使用 Amazon Web Services Management Console的教程,请参阅如何使用 Amazon Web Services Management Console配置本地资源访问

创建本地资源

首先,您使用 CreateResourceDefinition 命令创建一个资源定义以指定要访问的资源。在此示例中,我们创建两个资源(TestDirectoryTestCamera):

aws greengrass create-resource-definition --cli-input-json '{ "Name": "MyLocalVolumeResource", "InitialVersion": { "Resources": [ { "Id": "data-volume", "Name": "TestDirectory", "ResourceDataContainer": { "LocalVolumeResourceData": { "SourcePath": "/src/LRAtest", "DestinationPath": "/dest/LRAtest", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } }, { "Id": "data-device", "Name": "TestCamera", "ResourceDataContainer": { "LocalDeviceResourceData": { "SourcePath": "/dev/video0", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } } ] } }'

资源:Greengrass 组中的 Resource 对象列表。一个 Greengrass 组最多可包含 50 个资源。

Resource#Id:资源的唯一标识符。该 ID 用于在 Lambda 函数配置中引用资源。最大长度为 128 个字符。模式:[a-zA-Z0-9:_-]+。

Resource#Name:资源的名称。资源名称显示在 Greengrass 控制台中。最大长度为 128 个字符。模式:[a-zA-Z0-9:_-]+。

LocalDeviceResourceData# SourcePath: 设备资源的本地绝对路径。设备资源的源路径只能引用 /dev 中的字符设备或块设备。

LocalVolumeResourceData# SourcePath: Greengrass 核心设备上卷资源的本地绝对路径。此位置位于函数在其中运行的容器之外。卷资源类型的源路径不能以 /sys 开头。

LocalVolumeResourceData# DestinationPath:Lambda 环境中卷资源的绝对路径。此位置位于函数在其中运行的容器之内。

GroupOwnerSetting:允许您为 Lambda 流程配置其他群组权限。该字段是可选的。有关更多信息,请参阅 组所有者文件访问权限

GroupOwnerSetting# AutoAddGroupOwner: 如果为真,Greengrass 会自动将该资源的指定 Linux 操作系统组所有者添加到 Lambda 进程权限中。因此,Lambda 进程具有添加的 Linux 组的文件访问权限。

GroupOwnerSetting# GroupOwner: 指定其权限已添加到 Lambda 进程的 Linux 操作系统组的名称。该字段是可选的。

CreateResourceDefinition 将返回一个资源定义版本 ARN。在更新组定义时,应使用该 ARN。

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373/versions/a4d9b882-d025-4760-9cfe-9d4fada5390d", "Name": "MyLocalVolumeResource", "LastUpdatedTimestamp": "2017-11-15T01:18:42.153Z", "LatestVersion": "a4d9b882-d025-4760-9cfe-9d4fada5390d", "CreationTimestamp": "2017-11-15T01:18:42.153Z", "Id": "ab14d0b5-116e-4951-a322-9cde24a30373", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373" }

创建 Greengrass 函数

在创建资源后,请使用 CreateFunctionDefinition 命令创建 Greengrass 函数,并为该函数授予资源访问权限:

aws greengrass create-function-definition --cli-input-json '{ "Name": "MyFunctionDefinition", "InitialVersion": { "Functions": [ { "Id": "greengrassLraTest", "FunctionArn": "arn:aws:lambda:us-west-2:012345678901:function:lraTest:1", "FunctionConfiguration": { "Pinned": false, "MemorySize": 16384, "Timeout": 30, "Environment": { "ResourceAccessPolicies": [ { "ResourceId": "data-volume", "Permission": "rw" }, { "ResourceId": "data-device", "Permission": "ro" } ], "AccessSysfs": true } } } ] } }'

ResourceAccessPolicies:包含resourceId和,permission它们授予 Lambda 函数访问资源的权限。Lambda 函数最多可以访问 20 个资源。

ResourceAccessPolicy#Permission: 指定 Lambda 函数对资源拥有哪些权限。可用的选项为 rw(读/写)或 ro(只读)。

AccessSysfs: 如果为真,则 Lambda 进程可以对 Greengras /sys s 核心设备上的文件夹具有读取权限。这在 Greengrass Lambda 函数需要从 /sys 读取设备信息的情况下使用。

同样,CreateFunctionDefinition 返回一函数定义版本 ARN。应在组定义版本中使用该 ARN。

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad/versions/37f0d50e-ef50-4faf-b125-ade8ed12336e", "Name": "MyFunctionDefinition", "LastUpdatedTimestamp": "2017-11-22T02:28:02.325Z", "LatestVersion": "37f0d50e-ef50-4faf-b125-ade8ed12336e", "CreationTimestamp": "2017-11-22T02:28:02.325Z", "Id": "3c9b1685-634f-4592-8dfd-7ae1183c28ad", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad" }

将 Lambda 函数添加到组

最后,使用 CreateGroupVersion 将该函数添加到组中。例如:

aws greengrass create-group-version --group-id "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" \ --resource-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/db6bf40b-29d3-4c4e-9574-21ab7d74316c/versions/31d0010f-e19a-4c4c-8098-68b79906fb87" \ --core-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/cores/adbf3475-f6f3-48e1-84d6-502f02729067/versions/297c419a-9deb-46dd-8ccc-341fc670138b" \ --function-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/d1123830-da38-4c4c-a4b7-e92eec7b6d3e/versions/a2e90400-caae-4ffd-b23a-db1892a33c78" \ --subscription-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/subscriptions/7a8ef3d8-1de3-426c-9554-5b55a32fbcb6/versions/470c858c-7eb3-4abd-9d48-230236bfbf6a"
注意

要了解如何获取用于此命令的组 ID,请参阅获取组 ID

返回新组版本:

{ "Arn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/groups/b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5/versions/291917fb-ec54-4895-823e-27b52da25481", "Version": "291917fb-ec54-4895-823e-27b52da25481", "CreationTimestamp": "2017-11-22T01:47:22.487Z", "Id": "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" }

您的 Greengrass 群组现在包含 LRATest Lambda 函数,该函数可以访问两个资源:和。 TestDirectory TestCamera

以下示例 Lambda 函数 (lraTest.py) 是使用 Python 编写的,它写入到本地卷资源:

# Demonstrates a simple use case of local resource access. # This Lambda function writes a file test to a volume mounted inside # the Lambda environment under destLRAtest. Then it reads the file and # publishes the content to the Amazon IoT LRAtest topic. import sys import greengrasssdk import platform import os import logging # Setup logging to stdout logger = logging.getLogger(__name__) logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # Create a Greengrass Core SDK client. client = greengrasssdk.client('iot-data') volumePath = '/dest/LRAtest' def function_handler(event, context): try: client.publish(topic='LRA/test', payload='Sent from Amazon IoT Greengrass Core.') volumeInfo = os.stat(volumePath) client.publish(topic='LRA/test', payload=str(volumeInfo)) with open(volumePath + '/test', 'a') as output: output.write('Successfully write to a file.') with open(volumePath + '/test', 'r') as myfile: data = myfile.read() client.publish(topic='LRA/test', payload=data) except Exception as e: logger.error('Failed to publish message: ' + repr(e)) return

这些命令由 Greengrass API 提供,用于创建和管理资源定义及资源定义版本:

排查问题

  • 问:为什么我的 Greengrass 组部署失败,错误类似于:

    group config is invalid: ggc_user or [ggc_group root tty] don't have ro permission on the file: /dev/tty0

    答:此错误表明该 Lambda 进程没有访问指定资源的权限。解决方案是更改资源的文件权限,以便 Lambda 可以访问该资源。(请参阅组所有者文件访问权限以了解详细信息。)

  • 问:/var/run 配置为卷资源时,为什么 Lambda 函数无法启动,且 runtime.log 中包含错误消息:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/var/run\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/run\\\" caused \\\"invalid argument\\\"\""

    答:Amazon IoT Greengrass 核心当前不支持将 /var/var/run/var/lib 配置为卷资源。一种解决办法是首先在不同的文件夹中挂载 /var/var/run/var/lib,然后将该文件夹配置为卷资源。

  • 问:/dev/shm 配置为具有只读权限的卷资源时,为什么 Lambda 函数无法启动并在 runtime.log 中显示错误:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/dev/shm\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/dev/shm\\\" caused \\\"operation not permitted\\\"\""”

    答:/dev/shm 只能配置为读/写。将资源权限更改为 rw 以解决该问题。