使用组特定的配置控制 Greengrass Lambda 函数的执行 - AWS IoT Greengrass

AWS IoT Greengrass Version 1 于 2023 年 6 月 30 日进入延长使用寿命阶段。有关更多信息,请参阅 AWS IoT Greengrass V1维护策略。在此日期之后,AWS IoT Greengrass V1 不再发布更新来提供新功能、功能增强、错误修复或安全补丁。在 AWS IoT Greengrass V1 上运行的设备不会受到干扰,并且将继续运行并连接到云。我们强烈建议您迁移到 AWS IoT Greengrass Version 2,从而添加重要的新功能支持更多平台

使用组特定的配置控制 Greengrass Lambda 函数的执行

AWS IoT Greengrass 提供了基于云的 Greengrass Lambda 函数管理。尽管使用 AWS Lambda 来管理 Lambda 函数的代码和依赖项,但您可以配置 Lambda 函数在 Greengrass 组中运行时的行为方式。

组特定的配置设置

AWS IoT Greengrass 为 Greengrass Lambda 函数提供以下组特定的配置设置。

系统用户和组

用于运行 Lambda 函数的访问身份。默认情况下,Lambda 函数以该组的默认访问身份运行。通常情况下,这是标准 AWS IoT Greengrass 系统账户(ggc_user 和 ggc_group)。您可以更改设置,并选择具有运行 Lambda 函数所需权限的用户 ID 和组 ID。您可以覆盖 UID 和 GID 或只覆盖一个(如果将另一个字段留空)。通过此设置可以更精细地控制设备资源访问。建议使用适当的资源限制、文件权限和磁盘配额为使用其权限运行 Lambda 函数的用户和组配置 Greengrass 硬件。

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

重要

除非绝对有必要,否则建议避免以根用户身份运行 Lambda 函数。以 root 身份运行会增加以下风险:

  • 意外更改的风险,如意外删除关键文件。

  • 恶意个人对您的数据和设备造成的风险。

  • 当 Docker 容器使用 --net=hostUID=EUID=0 运行时,就可以规避容器的风险

如果需要以根用户身份运行,必须更新 AWS IoT Greengrass 配置以启用它。有关更多信息,请参阅 以根用户身份运行 Lambda 函数

系统用户 ID(数字)

具有运行 Lambda 函数所需权限的用户的用户 ID。仅当选择 以另一个用户 ID/组 ID 身份运行时,此设置才可用。通过对 AWS IoT Greengrass 核心设备使用 getent passwd 命令,可以查找要用于运行 Lambda 函数的用户 ID。

如果您使用相同的 UID 在 Greengrass 核心设备上运行进程和 Lambda 函数,则您的 Greengrass 组角色可以授予进程临时凭据。这些进程可以在整个 Greengrass 核心部署中使用临时证书。

系统组 ID(数字)

具有运行 Lambda 函数所需权限的组的组 ID。仅当选择 以另一个用户 ID/组 ID 身份运行时,此设置才可用。通过对 AWS IoT Greengrass 核心设备使用 getent group 命令,可以查找要用于运行 Lambda 函数的组 ID。

Lambda 函数容器化

选择 Lambda 函数是否对组使用默认容器化运行,或者指定应始终对此 Lambda 函数使用的容器化。

Lambda 函数的容器化模式决定其隔离级别。

  • 容器化 Lambda 函数在 Greengrass 容器模式下运行。Lambda 函数在 AWS IoT Greengrass 容器内的隔离运行时环境(或命名空间)中运行。

  • 非容器化 Lambda 函数在 无容器 模式下运行。这些 Lambda 函数作为常规 Linux 进程运行,没有任何隔离。

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

建议在 Greengrass 容器中运行 Lambda 函数,除非您的使用案例要求它们在不进行容器化的情况下运行。当 Lambda 函数在 Greengrass 容器中运行时,可以使用附加的本地和设备资源并获得隔离和安全性提高的优势。在更改容器化之前,请参阅选择 Lambda 函数容器化时的注意事项

注意

要在不启用设备内核命名空间和组的情况下运行,所有 Lambda 函数都必须在不进行容器化的情况下运行。通过为组设置默认容器化可以轻松完成此操作。有关信息,请参阅在组中设置 Lambda 函数的默认容器化

内存限制

为函数分配的内存。默认值为 16 MB。

注意

当您将 Lambda 函数更改为在无容器化的情况下运行时,内存限制设置将不可用。在没有容器化的情况下运行的 Lambda 函数没有内存限制。在将 Lambda 函数或组默认容器化设置更改为在不执行容器化的情况下运行时,将丢弃内存限制设置。

超时

在终止函数或请求之前经过的时间。默认值为 3 秒。

Pinned

Lambda 函数生命周期可以是按需长时间生存。默认为“按需”。

在调用时,将在新的或重复使用的容器中启动按需 Lambda 函数。函数请求可以由任何可用的容器进行处理。长时间生存的或固定的 Lambda 函数在 AWS IoT Greengrass 启动后自动启动,并在自己的容器 (或沙盒) 中保持运行。函数的所有请求是由相同的容器处理的。有关更多信息,请参阅 Greengrass Lambda 函数的生命周期配置

对 /sys 目录的只读访问权限

函数是否可以访问主机的 /sys 文件夹。当函数必须从 /sys 中读取设备信息时,请使用此设置。默认值为 false。

注意

在不进行容器化的情况下运行 Lambda 函数时,此设置不可用。将 Lambda 函数更改为在不进行容器化的情况下运行时,将丢弃此设置的值。

编码类型

函数输入负载的预期编码类型:JSON 或二进制。默认值为 JSON。

从 AWS IoT Greengrass 核心软件 v1.5.0 和 AWS IoT Greengrass 核心开发工具包 v1.1.0 开始,将提供二进制编码类型支持。对于与设备数据交互的函数,接受二进制输入数据可能是非常有用的,因为设备的受限硬件功能通常导致很难或无法构造 JSON 数据类型。

注意

Lambda 可执行文件仅支持二进制编码类型,不支持 JSON。

进程参数

在 Lambda 函数运行时要传递给该函数的命令行参数。

环境变量

可动态将设置传递到函数代码和库的键值对。本地环境变量的工作方式与 AWS Lambda 函数环境变量相同,但可以在核心环境中使用。

资源访问策略

允许 Lambda 函数访问的最多 10 个本地资源密钥资源机器学习资源的列表,以及相应的 read-onlyread-write 权限。在控制台中,这些关联资源列在资源选项卡的组配置页面上。

容器化模式会影响 Lambda 函数访问本地设备和卷资源以及机器学习资源的方式。

  • 非容器化 Lambda 函数必须直接通过核心设备上的文件系统访问本地设备和卷资源。

  • 要允许非容器化 Lambda 函数访问 Greengrass 组中的机器学习资源,必须在机器学习资源上设置资源所有者和访问权限属性。有关更多信息,请参阅 从 Lambda 函数访问机器学习资源

有关使用 AWS IoT Greengrass API 为用户定义的 Lambda 函数设置特定于组的配置设置的信息,请参阅《AWS IoT Greengrass Version 1 API 参考》中的 CreateFunctionDefinition《AWS CLI 命令参考》中的 create-function-definition。要将 Lambda 函数部署到 Greengrass 核心,请创建包含函数的函数定义版本,创建引用函数定义版本和其他组组件的组版本,然后部署组

以根用户身份运行 Lambda 函数

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

必须先更新 AWS IoT Greengrass 配置以启用支持,然后才能以根用户身份运行一个或多个 Lambda 函数。默认情况下,不支持以根用户身份运行 Lambda 函数。如果尝试部署 Lambda 函数并以根用户身份运行它(UID 和 GID 为 0),并且没有更新 AWS IoT Greengrass 配置,部署将失败。运行时日志 (greengrass_root/ggc/var/log/system/runtime.log) 中会显示类似下面的错误:

lambda(s) [list of function arns] are configured to run as root while Greengrass is not configured to run lambdas with root permissions
重要

除非绝对有必要,否则建议避免以根用户身份运行 Lambda 函数。以 root 身份运行会增加以下风险:

  • 意外更改的风险,如意外删除关键文件。

  • 恶意个人对您的数据和设备造成的风险。

  • 当 Docker 容器使用 --net=hostUID=EUID=0 运行时,就可以规避容器的风险

允许 Lambda 函数以根用户身份运行
  1. 在 AWS IoT Greengrass 设备上,导航到 greengrass-root/config 文件夹。

    注意

    默认情况下,greengrass-root 是 /greengrass 目录。

  2. 编辑 config.json 文件以向 runtime 字段添加 "allowFunctionsToRunAsRoot" : "yes"。例如:

    { "coreThing" : { ... }, "runtime" : { ... "allowFunctionsToRunAsRoot" : "yes" }, ... }
  3. 使用以下命令重启 AWS IoT Greengrass:

    cd /greengrass/ggc/core sudo ./greengrassd restart

    现在,可以将 Lambda 函数的用户 ID 和组 ID (UID/GID) 设置为 0,从而以根用户身份运行 Lambda 函数。

如果要禁止以根用户身份运行 Lambda 函数,可以将 "allowFunctionsToRunAsRoot" 的值更改为 "no" 并重启 AWS IoT Greengrass。

选择 Lambda 函数容器化时的注意事项

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

默认情况下,Lambda 函数在 AWS IoT Greengrass 容器内运行。容器在函数和主机之间提供隔离,从而为主机和容器内的函数提供更高的安全性。

建议在 Greengrass 容器中运行 Lambda 函数,除非您的使用案例要求它们在不进行容器化的情况下运行。通过在 Greengrass 容器内运行 Lambda 函数,可以更好地控制资源访问限制。

下面是在不进行容器化的情况下运行的一些示例使用案例:

  • 您想要在不支持容器模式的设备上运行 AWS IoT Greengrass(例如,因为您使用的是特殊的 Linux 发行版或内核版本太旧)。

  • 您需要在另一个有自己的 OverlayFS 的容器环境中运行 Lambda 函数,但在 Greengrass 容器中运行时遇到了 OverlayFS 冲突。

  • 您需要访问的本地资源的路径在部署时无法确定,或者其路径在部署后可能更改,如可插拔设备。

  • 您有一个编写为进程的旧应用程序,在作为容器化的 Lambda 函数运行它时遇到了问题。

容器化差异
容器化 注意

Greengrass 容器

  • 在 Greengrass 容器中运行 Lambda 函数时,所有 AWS IoT Greengrass 功能均可用。

  • 即使以相同的组 ID 运行,在 Greengrass 容器中运行的 Lambda 函数也无权访问其他 Lambda 函数的部署代码。也就是说,Lambda 函数之间以更强的隔离运行。

  • 由于在 AWS IoT Greengrass 容器中运行的 Lambda 函数的所有子进程都在与 Lambda 函数相同的容器中运行,当 Lambda 函数终止时,子进程也会终止。

无容器

  • 以下功能不适用于非容器化的 Lambda 函数:

    • Lambda 函数内存限制。

    • 本地设备和卷资源。您必须直接访问核心设备上的这些资源,而不是将其作为 Greengrass 组的一部分进行访问。

  • 如果您的非容器化 Lambda 函数访问机器学习资源,则必须标识资源所有者并设置对资源(而不是 Lambda 函数)的访问权限。这需要 AWS IoT Greengrass Core 软件 v1.10 或更高版本。有关更多信息,请参阅 从 Lambda 函数访问机器学习资源

  • Lambda 函数对使用相同组 ID 运行的其他 Lambda 函数的部署代码具有只读访问权限。

  • 在父 Lambda 函数终止时,在不同进程会话中生成子进程或使用重写的 SIGHUP(信号挂断)处理程序(例如使用 nohup 实用程序)的 Lambda 函数不会自动被 AWS IoT Greengrass 终止。

注意

Greengrass 组的默认容器化设置不适用于连接器

更改 Lambda 函数的容器化会在部署时导致问题。如果为 Lambda 函数分配的本地资源在新容器化设置下不再可用,部署将失败。

  • 将 Lambda 函数从在 Greengrass 容器中运行更改为在不进行容器化的情况下运行时,将丢弃该函数的内存限制。您必须直接访问文件系统,而不是使用附加的本地资源。必须在部署前删除所有附加的资源。

  • 将 Lambda 函数从在不进行容器化的情况下运行更改为在容器中运行时,Lambda 函数将失去对文件系统的直接访问权限。您必须为每个函数定义内存限制或接受默认设置 (16MB)。您必须在部署前为每个 Lambda 函数配置这些设置。

更改 Lambda 函数的容器化设置
  1. 在 AWS IoT 控制台导航窗格的管理下,展开 Greengrass 设备,然后选择组 (V1)

  2. 选择包含要更改设置的 Lambda 函数的组。

  3. 选择 Lambda 函数选项卡。

  4. 在要更改的 Lambda 函数上,选择省略号 (),然后选择编辑配置

  5. 更改容器化设置。如果要将 Lambda 函数配置为在 Greengrass 容器中运行,还必须设置内存限制对 /sys 目录的只读访问权限

  6. 选择保存,然后选择确认,保存对您的 Lambda 函数所做的更改。

这些更改将在部署组时生效。

还可以使用《AWS IoT Greengrass API 参考》中的 CreateFunctionDefinitionCreateFunctionDefinitionVersion。更改容器化设置时还请务必更新其他参数。例如,从在 Greengrass 容器中运行 Lambda 函数更改为在不进行容器化的情况下运行时,请务必清除 MemorySize 参数。

确定 Greengrass 设备支持的隔离模式

可以使用 AWS IoT Greengrass 依赖项检查程序确定 Greengrass 设备支持哪些隔离模式(Greengrass 容器/无容器)。

运行 AWS IoT Greengrass 依赖项检查程序
  1. GitHub 存储库下载并运行 AWS IoT Greengrass 依赖项检查器。

    wget https://github.com/aws-samples/aws-greengrass-samples/raw/master/greengrass-dependency-checker-GGCv1.11.x.zip unzip greengrass-dependency-checker-GGCv1.11.x.zip cd greengrass-dependency-checker-GGCv1.11.x sudo modprobe configs sudo ./check_ggc_dependencies | more
  2. more 出现处,按 Spacebar 键以显示另一页文本。

要获得有关 modprobe 命令的信息,请在终端中运行 man modprobe

为组中的 Lambda 函数设置默认访问身份

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

要更多地控制对设备资源的访问权限,您可以配置用于运行组中的 Lambda 函数的默认访问身份。此设置确定了在核心设备上运行 Lambda 函数时提供给这些函数的默认权限。要覆盖组中各个函数的设置,您可以使用该函数的 Run as (运行身份) 属性。有关更多信息,请参阅运行身份

此组级别设置也用于运行底层 AWS IoT Greengrass 核心软件。这由负责管理操作(如消息路由、本地影子同步和自动 IP 检测)的系统 Lambda 函数组成。

默认访问身份可配置为以标准 AWS IoT Greengrass 系统账户身份(ggc_user 和 ggc_group)运行,或者使用另一个用户或组的权限。建议使用适当的资源限制、文件权限和磁盘配额,为使用其权限运行用户定义的或系统 Lambda 函数的任何用户和组配置 Greengrass 硬件。

修改 AWS IoT Greengrass 组的默认访问身份
  1. 在 AWS IoT 控制台导航窗格的管理下,展开 Greengrass 设备,然后选择组 (V1)

  2. 选择要更改其设置的组。

  3. 选择 Lambda 函数选项卡,然后在默认 Lambda 函数运行时环境部分下选择编辑

  4. 编辑默认 Lambda 函数运行时环境)页面的默认系统用户和组下,选择其他用户 ID/组 ID

    当您选择此选项时,系统用户 ID (数字)系统组 ID (数字) 字段会显示。

  5. 输入用户 ID 和/或组 ID。如果将字段留空,将使用相应的 Greengrass 系统账户(ggc_user 或 ggc_group)。

    • 对于 系统用户 ID (数字),输入某个用户的用户 ID,该用户具有您在默认情况下要用来运行组中 Lambda 函数的权限。您可以在您的 AWS IoT Greengrass 设备上使用 getent passwd 命令查找用户 ID。

    • 对于 系统组 ID (数字),输入某个组的组 ID,该组具有您在默认情况下要用来运行组中 Lambda 函数的权限。您可以在您的 AWS IoT Greengrass 设备上使用 getent group 命令查找组 ID。

    重要

    以根用户身份运行会给您的数据和设备增加风险。请勿以根用户身份(UID/GID=0)运行,除非您的业务案例需要这样。有关更多信息,请参阅 以根用户身份运行 Lambda 函数

这些更改将在部署组时生效。

在组中设置 Lambda 函数的默认容器化

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

Greengrass 组的容器化设置决定了 Lambda 函数在组中的默认容器化。

  • Greengrass 容器模式下,默认情况下,Lambda 函数在 AWS IoT Greengrass 容器内的独立运行时环境中运行。

  • 无容器模式下,默认情况下,Lambda 函数将作为常规 Linux 进程运行。

您可以修改组设置以指定 Lambda 函数在组中的默认容器化。如果需要 Lambda 函数以不同于组默认设置的容器化方式运行,可以覆盖组中一个或多个 Lambda 函数的此设置。在更改容器化设置之前,请参阅选择 Lambda 函数容器化时的注意事项

重要

如果要更改组的默认容器化设置,但有一个或多个函数使用不同的容器化,请先更改这些 Lambda 函数的设置,然后再更改组设置。如果先更改组容器化设置,将丢弃内存限制对 /sys 目录的只读访问权限设置的值。

修改 AWS IoT Greengrass 组的容器化设置
  1. 在 AWS IoT 控制台导航窗格的管理下,展开 Greengrass 设备,然后选择组 (V1)

  2. 选择要更改其设置的组。

  3. 选择 Lambda 函数选项卡。

  4. 默认 Lambda 函数运行时环境下,选择编辑

  5. 编辑默认 Lambda 函数运行时环境页面的默认 Lambda 函数容器化下面,更改容器化设置。

  6. 选择保存

这些更改将在部署组时生效。