

终止支持通知：2026 年 10 月 7 日， AWS 将停止对的支持。 AWS IoT Greengrass Version 1 2026 年 10 月 7 日之后，您将无法再访问这些 AWS IoT Greengrass V1 资源。如需了解更多信息，请访问[迁移自 AWS IoT Greengrass Version 1](https://docs.aws.amazon.com/greengrass/v2/developerguide/migrate-from-v1.html)。

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

# 在核心上运行 Lambda 函数 AWS IoT Greengrass
<a name="lambda-functions"></a>

AWS IoT Greengrass 为您在其中创作的用户定义代码提供了容器化的 Lambda 运行时环境。 AWS Lambda部署到 AWS IoT Greengrass 核心的 Lambda 函数在内核的本地 Lambda 运行时中运行。本地事件、云中的消息和其他来源可能会触发本地 Lambda 函数，这会为客户端设备提供本地计算功能。例如，您可以使用 Greengrass Lambda 函数筛选设备数据，然后再将数据传输到云。

要将 Lambda 函数部署到核心，您需要将该函数添加到一个 Greengrass 组（通过引用现有的 Lambda 函数），为该函数配置组特定的设置，然后部署该组。如果该函数访问 AWS 服务，则还必须向 Gre [engrass](group-role.md) 组角色添加所有必需的权限。

您可以配置确定 Lambda 函数运行方式的参数，包括权限、隔离、内存限制等。有关更多信息，请参阅 [使用组特定的配置控制 Greengrass Lambda 函数的执行](lambda-group-config.md)。

**注意**  
这些设置还可以在 Docker 容器 AWS IoT Greengrass 中运行。有关更多信息，请参阅 [AWS IoT Greengrass 在 Docker 容器中运行](run-gg-in-docker-container.md)。

下表列出了支持的[AWS Lambda 运行时](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)及其可以运行的 AWS IoT Greengrass Core 软件版本。


****  

| 语言或平台 | GGC 版本 | 
| --- | --- | 
| Python 3.8 | 1.11 | 
| Python 3.7 | 1.9 或更高版本 | 
| Python 2.7 \$1 | 1.0 或更高版本 | 
| Java 8 | 1.1 或更高版本 | 
| Node.js 12.x \$1 | 1.10 或更高版本 | 
| Node.js 8.10 \$1 | 1.9 或更高版本 | 
| Node.js 6.10 \$1 | 1.1 或更高版本 | 
| C、C\$1\$1 | 1.6 或更高版本 | 

\$1 您可以在支持的版本上运行使用这些运行时的 Lambda 函数 AWS IoT Greengrass，但不能在中创建它们。 AWS Lambda如果设备上的运行时与为该函数指定的 AWS Lambda 运行时不同，则可以使用 `FunctionDefintionVersion` 中 `FunctionRuntimeOverride` 来选择自己的运行时。有关更多信息，请参阅 [CreateFunctionDefinition](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html)。有关支持的运行时的更多信息，请参阅*AWS Lambda 开发人员指南*中的[运行时支持策略](https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html)。

## SDKs 用于 Greengrass Lambda 函数
<a name="lambda-sdks"></a>

AWS 提供了三个可在内 SDKs 核上运行的 Greengrass Lambda 函数使用的函数。 AWS IoT Greengrass SDKs 它们包含在不同的包中，因此函数可以同时使用它们。要在 Greengrass Lambda 函数中使用开发工具包，请将其包含在您上传到 AWS Lambda的 Lambda 函数部署包中。

**AWS IoT Greengrass 核心软件开发工具包**  <a name="lambda-sdks-core"></a>
允许本地 Lambda 函数与核心交互以执行：  <a name="gg-core-sdk-functionality"></a>
+ 与交换 MQTT 消息。 AWS IoT Core
+ 与 Greengrass 组中的连接器、客户端设备及其他 Lambda 函数交换 MQTT 消息。
+ 与本地影子服务交互。
+ 调用其他的本地 Lambda 函数。
+ 访问[密钥资源](secrets.md)。
+ 与[流管理器](stream-manager.md)交互。
AWS IoT Greengrass 在上提供以下语言和平台的 AWS IoT Greengrass Core SDK GitHub。  <a name="gg-core-sdk-download-list"></a>
+ [AWS IoT Greengrass 适用于 Java 的核心 SDK](https://github.com/aws/aws-greengrass-core-sdk-java/)
+ [AWS IoT Greengrass Node.js 的核心 SDK](https://github.com/aws/aws-greengrass-core-sdk-js/)
+ [AWS IoT Greengrass Python 核心软件开发工具包](https://github.com/aws/aws-greengrass-core-sdk-python/)
+ [AWS IoT Greengrass 适用于 C 的核心 SDK](https://github.com/aws/aws-greengrass-core-sdk-c/)
要在 Lambda 函数部署包中包含 AWS IoT Greengrass 核心 SDK 依赖项，请执行以下操作：  

1. 下载与您的 Lambda 函数运行时相匹配的 AWS IoT Greengrass Core SDK 包的语言或平台。

1. 解压缩下载的程序包以获取软件开发工具包。软件开发工具包是 `greengrasssdk` 文件夹。

1. 将 `greengrasssdk` 包含在包含函数代码的 Lambda 函数部署程序包中。这是您在创建 Lambda 函数 AWS Lambda 时上传到的包。
   
 **StreamManagerClient**  
只有以下 AWS IoT Greengrass Core SDKs 可以用于[直播管理器](stream-manager.md)操作：  <a name="streammanagerclient-sdk-versions"></a>
+ Java SDK（v1.4.0 或更高版本）
+ Python SDK（v1.5.0 或更高版本）
+ Node.js SDK（v1.6.0 或更高版本）
要使用适用于 Python 的 AWS IoT Greengrass 核心 SDK 与直播管理器进行交互，必须安装 Python 3.7 或更高版本。您还必须安装依赖项以包含在 Python Lambda 函数部署程序包中：  <a name="python-sdk-dependencies-stream-manager"></a>

1. 导航到包含该 `requirements.txt` 文件的开发工具包目录。此文件列出了依赖项。

1. 安装开发工具包依赖项。例如，运行以下 `pip` 命令将它们安装在当前目录中：

   ```
   pip install --target . -r requirements.txt
   ```
   
**在 AWS IoT Greengrass 核心设备上安装适用于 Python 的核心开发工具包**  
如果你正在运行 Python Lambda 函数，也可以使用[https://pypi.org/project/pip/](https://pypi.org/project/pip/)在核心设备上安装适用于 Python 的 AWS IoT Greengrass 核心开发工具包。然后，您可以在 Lambda 函数部署包中部署您的函数而不包括开发工具包。有关更多信息，请参阅 [greengrasssdk](https://pypi.org/project/greengrasssdk/)。  
此支持适用于具有大小限制的核心。我们建议您尽可能将开发工具包包含在 Lambda 函数部署程序包中。  
 

**AWS IoT Greengrass Machine Learning**  <a name="lambda-sdks-ml"></a>
允许本地 Lambda 函数使用作为 ML 资源部署到 Greengrass 核心的机器学习 (ML) 模型。对于作为连接器部署到核心的本地推理服务，Lambda 函数可以使用 SDK 来调用并与之交互。Lambda 函数和 ML 连接器也可以使用软件开发工具包将数据发送到 ML 反馈连接器进行上传和发布。有关更多信息，包括使用此开发工具包的代码示例，请参阅[ML 图像分类连接器](image-classification-connector.md)、[ML 对象检测连接器](obj-detection-connector.md)和[ML 反馈连接器](ml-feedback-connector.md)。  
下表列出了 SDK 版本支持的语言或平台以及它们可以运行的 AWS IoT Greengrass 核心软件版本。    
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/lambda-functions.html)
有关下载信息，请参阅[AWS IoT Greengrass 机器学习 SDK 软件](what-is-gg.md#gg-ml-sdk-download)。

**AWS SDKs**  <a name="lambda-sdks-aws"></a>
允许本地 Lambda 函数直接调用 AWS 服务，例如 Amazon S3、DynamoDB 和。 AWS IoT AWS IoT Greengrass要在 Greengrass Lambda 函数中使用 AWS 开发工具包，必须将其包含在部署软件包中。当您在与 AWS IoT Greengrass 核心软件 AWS 开发工具包相同的软件包中使用软件开发工具包时，请确保您的 Lambda 函数使用正确的命名空间。在核心处于脱机状态时，Greengrass Lambda 函数无法与云服务进行通信。  
 AWS SDKs 从入[门资源中心](https://aws.amazon.com/getting-started/tools-sdks/)下载。

有关创建部署程序包的更多信息，请参阅入门教程中的 [创建并打包 Lambda 函数](create-lambda.md) 或 *AWS Lambda 开发人员指南*中的[创建部署程序包](https://docs.aws.amazon.com/lambda/latest/dg/deployment-package-v2.html)。

### 迁移基于云的 Lambda 函数
<a name="lambda-migrate-sdks"></a>

 AWS IoT Greengrass 核心软件开发工具包遵循 AWS 软件开发工具包编程模型，可以轻松地将为云开发的 Lambda 函数移植到在核心上运行的 Lambda 函数。 AWS IoT Greengrass 

例如，以下 Python Lambda 函数使用`some/topic`在云端向主题发布消息： 适用于 Python (Boto3) 的 AWS SDK 

```
import boto3

iot_client = boto3.client("iot-data")
response = iot_client.publish(
    topic="some/topic", qos=0, payload="Some payload".encode()
)
```

要将函数移植到 AWS IoT Greengrass 内核，请在`import`语句和`client`初始化中，将`boto3`模块名称更改为`greengrasssdk`，如以下示例所示：

```
import greengrasssdk

iot_client = greengrasssdk.client("iot-data")
iot_client.publish(topic="some/topic", qos=0, payload="Some payload".encode())
```

**注意**  
 AWS IoT Greengrass 核心软件开发工具包仅支持发送 QoS = 0 的 MQTT 消息。有关更多信息，请参阅 [消息服务质量](gg-core.md#message-quality-of-service)。

编程模型之间的相似性还使您能够在云中开发 Lambda 函数，然后以最少的努力将其 AWS IoT Greengrass 迁移到云中。[Lambda 可执行文件](#lambda-executables)不在云端运行，因此在部署之前，您无法使用 AWS SDK 在云中开发它们。

## 按别名或版本引用 Lambda 函数
<a name="lambda-versions-aliases"></a>

Greengrass 组可以按别名（推荐）或版本引用 Lambda 函数。使用别名，您可以更轻松地管理代码更新，因为您在更新函数代码时，不必更改订阅表或组定义。相反，您只需将别名指向新的函数版本。 在组部署期间，别名将解析为版本号。在使用别名时，解析的版本将在部署时更新为别名指向的版本。

AWS IoT Greengrass **不支持 \$1LATEST 版本的 Lambda 别名。****\$1LATEST** 版本未绑定到发布的不可变函数版本，可以随时对其进行更改，这与 AWS IoT Greengrass 版本不可变原则相反。

使用代码更改更新 Greengrass Lambda 函数的常见做法是，在 Greengrass 组和订阅中使用名为 **PRODUCTION** 的别名。在将 Lambda 函数的新版本提升到生产环境时，请将别名指向最新的稳定版本，然后重新部署组。您也可以使用这种方法回滚到以前的版本。

# 使用组特定的配置控制 Greengrass Lambda 函数的执行
<a name="lambda-group-config"></a>

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

## 组特定的配置设置
<a name="lambda-group-config-properties"></a>

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

**系统用户和组**  <a name="lambda-access-identity"></a>
用于运行 Lambda 函数的访问身份。默认情况下，Lambda 函数以该组的[默认访问身份](#lambda-access-identity-groupsettings)运行。通常情况下，这是标准 AWS IoT Greengrass 系统账户（ggc\$1user 和 ggc\$1group）。您可以更改设置，并选择具有运行 Lambda 函数所需权限的用户 ID 和组 ID。您可以覆盖 UID 和 GID 或只覆盖一个（如果将另一个字段留空）。通过此设置可以更精细地控制设备资源访问。建议使用适当的资源限制、文件权限和磁盘配额为使用其权限运行 Lambda 函数的用户和组配置 Greengrass 硬件。  
此功能适用于 AWS IoT Greengrass 酷睿 v1.7 及更高版本。  
除非绝对有必要，否则建议避免以根用户身份运行 Lambda 函数。以 root 身份运行会增加以下风险：  
+ 意外更改的风险，如意外删除关键文件。
+ 恶意个人对您的数据和设备造成的风险。
+ 当 Docker 容器使用 `--net=host` 和 `UID=EUID=0` 运行时，就可以规避容器的风险
如果您确实需要以 root 身份运行，则必须更新 AWS IoT Greengrass 配置才能将其启用。有关更多信息，请参阅 [以根用户身份运行 Lambda 函数](#lambda-running-as-root)。  
**系统用户 ID（数字）**  
具有运行 Lambda 函数所需权限的用户的用户 ID。仅当选择 **以另一个用户 ID/组 ID 身份**运行时，此设置才可用。您可以在 AWS IoT Greengrass 核心设备上使用**getent passwd**命令来查找要用于运行 Lambda 函数的用户 ID。  
如果您使用相同的 UID 在 Greengrass 核心设备上运行进程和 Lambda 函数，则您的 Greengrass 组角色可以授予进程临时凭据。这些进程可以在整个 Greengrass 核心部署中使用临时证书。  
**系统组 ID（数字）**  
具有运行 Lambda 函数所需权限的组的组 ID。只有当您选择以**其他用户 ID/group ID** 的身份运行时，此设置才可用。您可以在 AWS IoT Greengrass 核心设备上使用**getent group**命令来查找要用于运行 Lambda 函数的组 ID。

**Lambda 函数容器化**  <a name="lambda-function-containerization"></a>
选择 Lambda 函数是否对组使用默认容器化运行，或者指定应始终对此 Lambda 函数使用的容器化。  
Lambda 函数的容器化模式决定其隔离级别。  
+ 容器化 Lambda 函数在 **Greengrass 容器**模式下运行。Lambda 函数在容器内的隔离运行时环境（或命名空间）中 AWS IoT Greengrass 运行。
+ 非容器化 Lambda 函数在 **无容器** 模式下运行。这些 Lambda 函数作为常规 Linux 进程运行，没有任何隔离。
此功能适用于 AWS IoT Greengrass 酷睿 v1.7 及更高版本。  
建议在 Greengrass 容器中运行 Lambda 函数，除非您的使用案例要求它们在不进行容器化的情况下运行。当 Lambda 函数在 Greengrass 容器中运行时，可以使用附加的本地和设备资源并获得隔离和安全性提高的优势。在更改容器化之前，请参阅[选择 Lambda 函数容器化时的注意事项](#lambda-containerization-considerations)。  
要在不启用设备内核命名空间和组的情况下运行，所有 Lambda 函数都必须在不进行容器化的情况下运行。通过为组设置默认容器化可以轻松完成此操作。有关信息，请参阅[在组中设置 Lambda 函数的默认容器化](#lambda-containerization-groupsettings)。

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

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

**Pinned**  
Lambda 函数生命周期可以是*按需*或*长时间生存*。默认为“按需”。  
在调用时，将在新的或重复使用的容器中启动按需 Lambda 函数。函数请求可以由任何可用的容器进行处理。长寿命或*固定*的 Lambda 函数在启动后会自动启动，并继续在自己的容 AWS IoT Greengrass 器（或沙箱）中运行。函数的所有请求是由相同的容器处理的。有关更多信息，请参阅 [Greengrass Lambda 函数的生命周期配置](lambda-functions.md#lambda-lifecycle)。

**对 /sys 目录的只读访问权限**  
函数是否可以访问主机的 /sys 文件夹。当函数必须从 /sys 中读取设备信息时，请使用此设置。默认值为 false。  
在不进行容器化的情况下运行 Lambda 函数时，此设置不可用。将 Lambda 函数更改为在不进行容器化的情况下运行时，将丢弃此设置的值。

**编码类型**  
函数输入负载的预期编码类型：JSON 或二进制。默认值为 JSON。  
从 AWS IoT Greengrass 核心软件 v1.5.0 和 AWS IoT Greengrass Core SDK v1.1.0 开始支持二进制编码类型。对于与设备数据交互的函数，接受二进制输入数据可能是非常有用的，因为设备的受限硬件功能通常导致很难或无法构造 JSON 数据类型。  
[Lambda 可执行文件](lambda-functions.md#lambda-executables)仅支持二进制编码类型，不支持 JSON。

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

**环境变量**  
可动态将设置传递到函数代码和库的键值对。本地环境变量的工作方式与 [AWS Lambda 函数环境变量](https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html)相同，但可以在核心环境中使用。

**资源访问策略**  
允许 Lambda 函数访问的最多 10 个[本地资源](access-local-resources.md)、[密钥资源](secrets.md)和[机器学习资源](ml-inference.md)的列表，以及相应的 `read-only` 或 `read-write` 权限。在控制台中，这些*关联*资源列在**资源**选项卡的组配置页面上。  
[容器化模式](#lambda-function-containerization)会影响 Lambda 函数访问本地设备和卷资源以及机器学习资源的方式。  
+ 非容器化 Lambda 函数必须直接通过核心设备上的文件系统访问本地设备和卷资源。
+ 要允许非容器化 Lambda 函数访问 Greengrass 组中的机器学习资源，必须在机器学习资源上设置资源所有者和访问权限属性。有关更多信息，请参阅 [从 Lambda 函数访问机器学习资源](access-ml-resources.md)。

*有关使用 AWS IoT Greengrass API 为用户定义的 Lambda 函数设置特定于组的配置设置的信息，请参阅 [CreateFunctionDefinition AWS IoT Greengrass Version 1](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html)*API 参考或命令参考[create-function-definition](https://docs.aws.amazon.com/cli/latest/reference/greengrass/create-function-definition.html)*中的。AWS CLI *要将 Lambda 函数部署到 Greengrass 核心，请创建包含函数的函数定义版本，创建引用函数定义版本和其他组组件的组版本，然后[部署组](deployments.md)。

## 以根用户身份运行 Lambda 函数
<a name="lambda-running-as-root"></a>

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

必须先更新 AWS IoT Greengrass 配置以启用支持，然后才能以 root 身份运行一个或多个 Lambda 函数。默认情况下，不支持以根用户身份运行 Lambda 函数。如果您尝试部署 Lambda 函数并以根用户身份运行该函数（UID 和 GID 为 0），但尚未更新配置，则部署将失败。 AWS IoT Greengrass 运行时日志 (*greengrass\$1root*/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=host` 和 `UID=EUID=0` 运行时，就可以规避容器的风险

**允许 Lambda 函数以根用户身份运行**

1. 在您的 AWS IoT Greengrass 设备上，导航到 *greengrass-root* /config 文件夹。
**注意**  
默认情况下，*greengrass-root*是 /greengrass 目录。

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

   ```
   {
     "coreThing" : {
       ...
     },
     "runtime" : {
       ...
       "allowFunctionsToRunAsRoot" : "yes"
     },
     ...
   }
   ```

1. 使用以下命令重新启动 AWS IoT Greengrass：

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

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

 AWS IoT Greengrass 如果您想不允许 Lambda 函数以 root 身份运行，则可以将的值更改为并重新启动。`"allowFunctionsToRunAsRoot"` `"no"`

## 选择 Lambda 函数容器化时的注意事项
<a name="lambda-containerization-considerations"></a>

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

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

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

下面是在不进行容器化的情况下运行的一些示例使用案例：
+ 你想在不支持容器模式的设备 AWS IoT Greengrass 上运行（例如，因为你使用的是特殊的 Linux 发行版或者内核版本太旧）。
+ 您需要在另一个有自己的 OverlayFS 的容器环境中运行 Lambda 函数，但在 Greengrass 容器中运行时遇到了 OverlayFS 冲突。
+ 您需要访问的本地资源的路径在部署时无法确定，或者其路径在部署后可能更改，如可插拔设备。
+ 您有一个编写为进程的旧应用程序，在作为容器化的 Lambda 函数运行它时遇到了问题。


**容器化差异**  

| 容器化 | 注意 | 
| --- | --- | 
| Greengrass 容器 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/lambda-group-config.html) | 
| 无容器 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v1/developerguide/lambda-group-config.html) | 

**注意**  
Greengrass 组的默认容器化设置不适用于[连接器](connectors.md)。

更改 Lambda 函数的容器化会在部署时导致问题。如果为 Lambda 函数分配的本地资源在新容器化设置下不再可用，部署将失败。
+ 将 Lambda 函数从在 Greengrass 容器中运行更改为在不进行容器化的情况下运行时，将丢弃该函数的内存限制。您必须直接访问文件系统，而不是使用附加的本地资源。必须在部署前删除所有附加的资源。
+ 将 Lambda 函数从在不进行容器化的情况下运行更改为在容器中运行时，Lambda 函数将失去对文件系统的直接访问权限。您必须为每个函数定义内存限制或接受默认设置 (16MB)。您必须在部署前为每个 Lambda 函数配置这些设置。<a name="change-containerization-lambda"></a>

**更改 Lambda 函数的容器化设置**

1. <a name="console-gg-groups"></a>**在 AWS IoT 控制台导航窗格的**管理**下，展开 **Greengrass** 设备，然后选择群组 (V1)。**

1. <a name="lambda-choose-group"></a>选择包含要更改设置的 Lambda 函数的组。

1. <a name="lambda-choose-lambdas"></a>选择 **Lambda 函数**选项卡。

1. <a name="lambda-edit-lambda"></a>在要更改的 Lambda 函数上，选择省略号 (**…**)，然后选择**编辑配置**。

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

1. <a name="lambda-save-changes"></a>选择**保存**，然后选择**确认**，保存对您的 Lambda 函数所做的更改。

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

您也可以在 *AWS IoT Greengrass API 参考[CreateFunctionDefinitionVersion](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinitionversion-post.html)*中使用[CreateFunctionDefinition](https://docs.aws.amazon.com/greengrass/v1/apireference/createfunctiondefinition-post.html)和。更改容器化设置时还请务必更新其他参数。例如，从在 Greengrass 容器中运行 Lambda 函数更改为在不进行容器化的情况下运行时，请务必清除 `MemorySize` 参数。

### 确定 Greengrass 设备支持的隔离模式
<a name="dependency-checker-tests-isolation"></a>

您可以使用 AWS IoT Greengrass 依赖关系检查器来确定您的 Greengrass 设备支持哪些隔离模式（ container/no Greengrass 容器）。

**运行 AWS IoT Greengrass 依赖关系检查器**

1. 从[GitHub存储库](https://github.com/aws-samples/aws-greengrass-samples)下载并运行 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
   ```

1. 在 `more` 出现处，按 Spacebar 键以显示另一页文本。

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

## 为组中的 Lambda 函数设置默认访问身份
<a name="lambda-access-identity-groupsettings"></a>

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

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

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

可以将默认访问身份配置为以标准 AWS IoT Greengrass 系统帐户（ggc\$1user 和 ggc\$1group）的身份运行，也可以使用其他用户或组的权限运行。建议使用适当的资源限制、文件权限和磁盘配额，为使用其权限运行用户定义的或系统 Lambda 函数的任何用户和组配置 Greengrass 硬件。

**修改 AWS IoT Greengrass 群组的默认访问身份**

1. <a name="console-gg-groups"></a>**在 AWS IoT 控制台导航窗格的**管理**下，展开 **Greengrass** 设备，然后选择群组 (V1)。**

1. <a name="group-choose-group"></a>选择要更改其设置的组。

1. 选择 **Lambda 函数**选项卡，然后在**默认 Lambda 函数运行时环境**部分下选择**编辑**。

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

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

1. 输入用户 ID 和/或组 ID。如果将字段留空，将使用相应的 Greengrass 系统账户（ggc\$1user 或 ggc\$1group）。
   + 对于 **系统用户 ID (数字)**，输入某个用户的用户 ID，该用户具有您在默认情况下要用来运行组中 Lambda 函数的权限。您可以在您的 AWS IoT Greengrass 设备上使用 **getent passwd** 命令查找用户 ID。
   + 对于 **系统组 ID (数字)**，输入某个组的组 ID，该组具有您在默认情况下要用来运行组中 Lambda 函数的权限。您可以在您的 AWS IoT Greengrass 设备上使用 **getent group** 命令查找组 ID。
**重要**  
以根用户身份运行会给您的数据和设备增加风险。请勿以根用户身份（UID/GID=0）运行，除非您的业务案例需要这样。有关更多信息，请参阅 [以根用户身份运行 Lambda 函数](#lambda-running-as-root)。

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

## 在组中设置 Lambda 函数的默认容器化
<a name="lambda-containerization-groupsettings"></a>

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

Greengrass 组的容器化设置决定了 Lambda 函数在组中的默认容器化。
+ 在 **Greengrass** 容器模式下，默认情况下，Lambda 函数在容器内的隔离运行时环境中运行。 AWS IoT Greengrass 
+ 在**无容器**模式下，默认情况下，Lambda 函数将作为常规 Linux 进程运行。

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

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

**修改群组的容器化设置 AWS IoT Greengrass**

1. <a name="console-gg-groups"></a>**在 AWS IoT 控制台导航窗格的**管理**下，展开 **Greengrass** 设备，然后选择群组 (V1)。**

1. <a name="group-choose-group"></a>选择要更改其设置的组。

1. 选择 **Lambda 函数**选项卡。

1. 在**默认 Lambda 函数运行时环境**下，选择**编辑**。

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

1. 选择**保存**。

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

## Greengrass Lambda 函数的通信流
<a name="lambda-communication"></a>

Greengrass Lambda 函数支持多种与群组其他成员、本地服务和云服务（包括服务）进行通信的方法。 AWS IoT Greengrass AWS 

### 使用 MQTT 消息进行通信
<a name="lambda-messages"></a>

Lambda 函数可以使用由订阅控制的发布-订阅模式发送和接收 MQTT 消息。

此通信流能让 Lambda 函数与以下实体交换消息：
+ 组中的客户端设备。
+ 组中的连接器。
+ 组中的其他 Lambda 函数。
+ AWS IoT.
+ 本地设备影子服务。

订阅会定义消息源、消息目标以及用于将消息从源路由到目标的主题。发布到 Lambda 函数的消息将传递到为该函数注册的处理程序。订阅实现了更高的安全性并提供可预测的交互。有关更多信息，请参阅 [MQTT 消息传递工作流中的托管订阅](gg-sec.md#gg-msg-workflow)。

**注意**  
在核心处于脱机状态时，Greengrass Lambda 函数可以与客户端设备、连接器、其他函数和本地影子交换消息，但将到 AWS IoT 的消息排入队列。有关更多信息，请参阅 [云目标的 MQTT 消息队列](gg-core.md#mqtt-message-queue)。

### 其他通信流
<a name="lambda-other-communication"></a>
+ 为了与核心设备上的本地设备和卷资源以及机器学习模型进行交互，Greengrass Lambda 函数使用平台特定的操作系统接口。例如，您可以在 Python 函数中使用 `open`os[ 模块中的 ](https://docs.python.org/2/library/os.html) 方法。要允许函数访问某个资源，函数必须与该资源*关联*，或者为其授予了 `read-only` 或 `read-write` 权限。有关更多信息，包括 AWS IoT Greengrass 核心版本的可用性，请参阅[使用 Lambda 函数和连接器访问本地资源](access-local-resources.md)和[从 Lambda 函数代码访问机器学习资源](access-ml-resources.md#access-resource-function-code)。
**注意**  
如果您在不进行容器化的情况下运行 Lambda 函数，则无法使用附加的本地设备和卷资源，并且必须直接访问这些资源。
+ Lambda 函数可以使用 AWS IoT Greengrass 核心软件开发工具包中的`Lambda`客户端来调用 Greengrass 组中的其他 Lambda 函数。
+ Lambda 函数可以使用 AWS 软件开发工具包与 AWS 服务进行通信。有关更多信息，请参阅 [AWS 软件开发工具包](#aws-sdk)。
+ Lambda 函数可以使用第三方接口与外部云服务进行通信，类似于基于云的 Lambda 函数。

**注意**  
当核心处于离线状态时，Greengrass Lambda 函数无法 AWS 与云服务或其他云服务通信。

## 检索输入 MQTT 主题（或主旨）
<a name="lambda-get-mqtt-topic"></a>

AWS IoT Greengrass 使用订阅来控制客户端设备、Lambda 函数和群组中的连接器之间以及 AWS IoT 与本地影子服务之间的 MQTT 消息交换。订阅定义消息源、消息目标以及用于路由消息的 MQTT 主题。当目标是一个 Lambda 函数时，当源发布消息时将调用该函数的处理程序。有关更多信息，请参阅 [使用 MQTT 消息进行通信](#lambda-messages)。

以下示例显示 Lambda 函数如何可以从传递给处理程序的 `context` 获取输入主题。具体方法是通过从上下文层次结构 (`context.client_context.custom['subject']`) 访问 `subject` 密钥。该示例还会解析输入 JSON 消息，然后发布解析的主题和消息。

**注意**  
在 AWS IoT Greengrass API 中，[订阅](https://docs.aws.amazon.com/greengrass/v1/apireference/definitions-subscription.html)的主题由`subject`属性表示。

```
import greengrasssdk
import logging

client = greengrasssdk.client('iot-data')

OUTPUT_TOPIC = 'test/topic_results'

def get_input_topic(context):
    try:
        topic = context.client_context.custom['subject']
    except Exception as e:
        logging.error('Topic could not be parsed. ' + repr(e))
    return topic
    
def get_input_message(event):
    try:
        message = event['test-key']
    except Exception as e:
        logging.error('Message could not be parsed. ' + repr(e))
    return message

def function_handler(event, context):
    try:
        input_topic = get_input_topic(context)
        input_message = get_input_message(event)
        response = 'Invoked on topic "%s" with message "%s"' % (input_topic, input_message)
        logging.info(response)
    except Exception as e:
        logging.error(e)

    client.publish(topic=OUTPUT_TOPIC, payload=response)

    return
```

要测试函数，请使用默认配置设置将其添加到组中。然后，添加以下订阅并部署该组。有关说明，请参阅[模块 3（第 1 部分）：开启 Lambda 函数 AWS IoT Greengrass](module3-I.md)。


****  

| 来源 | Target | 主题筛选条件 | 
| --- | --- | --- | 
| IoT 云 | 此函数 | test/input\$1message | 
| 此函数 | IoT 云 | test/topic\$1results | 

部署完成后，调用该函数。

1. 在 AWS IoT 控制台中，打开 **MQTT 测试客户端**页面。

1. 要订阅 `test/topic_results` 主题，可选择**订阅主题**选项卡。

1. 要向 `test/input_message` 主题发布消息，可选择**发布到主题**选项卡。对于此示例，您必须在 JSON 消息中包含 `test-key` 属性。

   ```
   {
     "test-key": "Some string value"
   }
   ```

   如果成功，此函数会将输入主题和消息字符串发布到 `test/topic_results` 主题。

## Greengrass Lambda 函数的生命周期配置
<a name="lambda-lifecycle"></a>

Greengrass Lambda 函数生命周期确定函数何时启动以及它如何创建和使用容器。生命周期还确定如何保留位于函数处理程序外部的变量和预处理逻辑。

AWS IoT Greengrass 支持按需（默认）或长寿命生命周期：
+ **按需**函数在调用时启动，并在没有要执行的任务时停止。除非具有可重复使用的现有容器，否则，函数调用将创建单独的容器（或沙盒）以处理调用。发送到函数的数据可以由任何容器提取。

  按需 函数的多次调用可以并行运行。

  在创建新的容器时，不会保留在函数处理程序外部定义的变量和预处理逻辑。
+ 当 AWS IoT Greengrass 核心启动并在单个容器中运行时，**长寿**命（或*固定*）函数会自动启动。发送到函数的所有数据由相同的容器提取。

  多个调用将排入队列，直到执行了以前的调用。

  将为处理程序的每次调用保留在函数处理程序外部定义的变量和预处理逻辑。

  如果需要在没有任何初始输入的情况下开始工作，长时间生存的 Lambda 函数是非常有用的。例如，在长时间存在的函数开始接收设备数据时，该函数可以加载并开始处理 ML 模型以使其准备就绪。
**注意**  
请记住，长时间生存的函数具有与其处理程序调用关联的超时。如果要执行无限期运行的代码，您必须在处理程序外部启动该代码。确保在处理程序外部没有阻止代码而导致函数可能无法完成初始化。  
 这些函数将运行，除非核心停止（例如，在组部署或设备重启期间）或函数进入错误状态（例如，处理程序超时、未捕获的异常或者当它超过其内存限制时）。

有关容器重用的更多信息，请参阅 AWS Compute 博客[AWS Lambda中的了解容器重用](https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/)。

## Lambda 可执行文件
<a name="lambda-executables"></a>

此功能适用于 AWS IoT Greengrass 酷睿 v1.6 及更高版本。

Lambda 可执行文件是一种 Greengrass Lambda 函数，可用于在核心环境中运行二进制代码。这样，您就可以在本地执行设备特定的功能，并从较小的编译代码占用空间中受益。Lambda 可执行文件可以由事件调用，它调用其他函数以及访问本地资源。

Lambda 可执行文件仅支持二进制编码类型（不支持 JSON），但您可以像其他 Greengrass Lambda 函数一样在 Greengrass 组中管理这些函数并进行部署。不过，创建 Lambda 可执行文件的过程与创建 Python、Java 和 Node.js Lambda 函数不同：
+ 您不能使用 AWS Lambda 控制台创建（或管理）Lambda 可执行文件。您只能使用 API 创建 Lambda 可执行文件。 AWS Lambda 
+ 您可以将函数代码 AWS Lambda 作为已编译的可执行文件上传到，其中包含[适用于 C 的 C AWS IoT Greengrass ore SDK](https://github.com/aws/aws-greengrass-core-sdk-c)。
+ 您将可执行文件名称指定为函数处理程序。

Lambda 可执行文件必须在其函数代码中实施某些调用和编程模式。例如，`main` 方法必须：
+ 调用 `gg_global_init` 以初始化 Greengrass 内部全局变量。必须在创建任何线程之前以及调用任何其他 C AWS IoT Greengrass ore SDK 函数之前调用此函数。
+ 调用 `gg_runtime_start` 以在 Greengrass Lambda 运行时环境中注册函数处理程序。必须在初始化时调用该函数。调用该函数将导致运行时环境使用当前线程。可选的 `GG_RT_OPT_ASYNC` 参数指示该函数不要阻止，而是为运行时环境创建新的线程。该函数使用 `SIGTERM` 处理程序。

以下片段是 [simple\$1handler.c 代码示例](https://github.com/aws/aws-greengrass-core-sdk-c/blob/master/aws-greengrass-core-sdk-c-example/simple_handler.c)中的`main`方法。 GitHub

```
int main() {
    gg_error err = GGE_SUCCESS;

    err = gg_global_init(0);
    if(err) {
        gg_log(GG_LOG_ERROR, "gg_global_init failed %d", err);
        goto cleanup;
    }

    gg_runtime_start(handler, 0);

cleanup:
    return -1;
}
```

有关要求、限制和其他实施细节的更多信息，请参阅[适用于 C 的AWS IoT Greengrass Core 软件开发工具包](https://github.com/aws/aws-greengrass-core-sdk-c)。

### 创建 Lambda 可执行文件
<a name="create-lambda-executable"></a>

在编译代码和软件开发工具包后，使用 AWS Lambda API 创建 Lambda 函数并上传编译后的可执行文件。

**注意**  
必须使用与 C89 兼容的编译器编译您的函数。

以下示例使用 [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) CLI 命令创建 Lambda 可执行文件。该命令指定：
+ 处理程序的可执行文件名称。它必须是编译的可执行文件的确切名称。
+ 包含编译的可执行文件的 `.zip` 文件的路径。
+ 运行时环境的 `arn:aws:greengrass:::runtime/function/executable`。这是所有 Lambda 可执行文件的运行时环境。

**注意**  
对于 `role`，您可以指定任何 Lambda 执行角色的 ARN。 AWS IoT Greengrass 不使用该角色，但需要使用该参数以创建函数。有关 Lambda 执行角色的更多信息，请参阅 *AWS Lambda 开发人员指南*中的 [AWS Lambda 许可模型](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html)。

```
aws lambda create-function \
--region aws-region \
--function-name function-name \
--handler executable-name \
--role role-arn \
--zip-file fileb://file-name.zip \
--runtime arn:aws:greengrass:::runtime/function/executable
```

接下来，使用 AWS Lambda API 发布版本并创建别名。
+ 使用 [publish-version](https://docs.aws.amazon.com/cli/latest/reference/lambda/publish-version.html) 发布一个函数版本。

  ```
  aws lambda publish-version \
  --function-name function-name \
  --region aws-region
  ```
+ 使用 [create-alias](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-alias.html) 创建指向刚发布的版本的别名。在将 Lambda 函数添加到 Greengrass 组时，我们建议您按别名引用这些函数。

  ```
  aws lambda create-alias \
  --function-name function-name \
  --name alias-name \
  --function-version version-number \
  --region aws-region
  ```

**注意**  
 AWS Lambda 控制台不显示 Lambda 可执行文件。要更新函数代码，必须使用 AWS Lambda API。

接下来，将 Lambda 可执行文件添加到一个 Greengrass 组，在组特定的设置中将其配置为接受二进制输入数据，然后部署该组。您可以在 AWS IoT Greengrass 控制台中或使用 AWS IoT Greengrass API 执行此操作。

# AWS IoT Greengrass 在 Docker 容器中运行
<a name="run-gg-in-docker-container"></a>

AWS IoT Greengrass 可以配置为在 [Docker](https://www.docker.com/) 容器中运行。

您可以通过[亚马逊](what-is-gg.md#gg-docker-download)下载安装了 AWS IoT Greengrass 核心软件和依赖项 CloudFront的 Dockerfile。要修改 Docker 镜像以便在不同平台架构上运行或减少 Docker 镜像的大小，请参阅 Docker 程序包下载中的 `README` 文件。

为了帮助您开始试验 AWS IoT Greengrass， AWS 还提供了安装了 C AWS IoT Greengrass ore 软件和依赖项的预构建 Docker 镜像。您可以从 [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) 或 [Amazon Elastic Container Registry](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) (Amazon ECR) 下载映像。这些预先构建的映像使用亚马逊 Linux 2 (x86\$164) 和 Alpine Linux（x86\$164、armv7L 或）基础映像。 AArch64

**重要**  
<a name="docker-images-end-of-maintenance"></a>2022 年 6 月 30 日，我 AWS IoT Greengrass 结束了对发布到亚马逊弹性容器注册表 (Amazon ECR) 和 Docker Hub 的 AWS IoT Greengrass 核心软件 v1.x Docker 镜像的维护。您可以继续从 Amazon ECR 和 Docker Hub 下载这些 Docker 映像，直至 2023 年 6 月 30（即维护结束 1 年后）为止。但是，在 2022 年 6 月 30 日维护结束后， AWS IoT Greengrass 核心软件 v1.x Docker 镜像不再收到安全补丁或错误修复。如果您运行的生产工作负载依赖于这些 Docker 镜像，我们建议您使用提供的 Dockerfiles 构建自己的 Docker 镜像。 AWS IoT Greengrass 有关更多信息，请参阅 [AWS IoT Greengrass Docker 软件](what-is-gg.md#gg-docker-download)。

本主题介绍如何从亚马逊 ECR 下载 AWS IoT Greengrass Docker 镜像并在 Windows、macOS 或 Linux (x86\$164) 平台上运行该镜像。本主题包含以下步骤：

1. [从 Amazon ECR 获取 AWS IoT Greengrass 容器镜像](#docker-pull-image)

1. [创建和配置 Greengrass 组和核心](#docker-config-gg)

1. [在 AWS IoT Greengrass 本地运行](#docker-run-gg)

1. [为组配置“No container (无容器)”容器化](#docker-no-container)

1. [将 Lambda 函数部署到 Docker 容器](#docker-add-lambdas)

1. [（可选）部署与 Docker 容器中的 Greengrass 交互的客户端设备](#docker-add-devices)

在 Docker 容器 AWS IoT Greengrass 中运行时，不支持以下功能：<a name="docker-image-unsupported-features"></a>
+ 在 **Greengrass 容器模式**下运行的[连接器](connectors.md)。要在 Docker 容器中运行连接器，该连接器必须在**无容器**模式下运行。要查找支持**无容器**模式的连接器，请参阅[AWS提供的 Greengrass 连接器](connectors-list.md)。其中一些连接器具有隔离模式参数，您必须将此参数设为**无容器**。
+ [本地设备和卷资源](access-local-resources.md)。在 Docker 容器中运行的用户定义 Lambda 函数必须直接访问核心上的设备和卷。

当 Greengrass 组的 Lambda 运行时环境设置为 “无容器”（在 Docker [容器中运行是必需的）时，不](lambda-group-config.md#no-container-mode)支持这些功能。 AWS IoT Greengrass 

## 先决条件
<a name="docker-image-prerequisites"></a>

在开始本教程之前，必须执行以下操作。<a name="docker-image-prereq-list"></a>
+ 您必须根据所选的 AWS Command Line Interface (AWS CLI) 版本在主机上安装以下软件和版本。

------
#### [ AWS CLI version 2 ]
  + [Docker](https://docs.docker.com/install/) 版本 18.09 或更高版本。早期版本也可能有效，但我们建议使用 18.09 或更高版本。
  + AWS CLI 版本 2.0.0 或更高版本。
    + 要安装 AWS CLI 版本 2，请参阅[安装 AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)。
    + 要配置 AWS CLI，请参阅[配置 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。
**注意**  
要在 Windows 计算机上升级到更高 AWS CLI 版本 2，必须重复 [MSI 安装](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-windows.html)过程。

------
#### [ AWS CLI version 1 ]
  + [Docker](https://docs.docker.com/install/) 版本 18.09 或更高版本。早期版本也可能有效，但我们建议使用 18.09 或更高版本。
  + [Python](https://www.python.org/downloads/) 版本 3.6 或更高版本。
  + [pip](https://pip.pypa.io/en/stable/installing) 版本 18.1 或更高版本。
  + AWS CLI 版本 1.17.10 或更高版本
    + 要安装 AWS CLI 版本 1，请参阅[安装 AWS CLI 版本 1](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)。
    + 要配置 AWS CLI，请参阅[配置 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。
    + 要升级到版本 1 的最新 AWS CLI 版本，请运行以下命令。

      ```
      pip install awscli --upgrade --user
      ```
**注意**  
如果你在 Windows 上使用 [MSI 安装](https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html#msi-on-windows) AWS CLI 版本 1，请注意以下几点：  
如果 AWS CLI 版本 1 安装无法安装 botocore，请尝试使用 Pyth [on 和 pip](https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-windows.html#awscli-install-windows-pip) 安装。
要升级到更高 AWS CLI 版本 1，必须重复 MSI 安装过程。

------
+ 要访问 Amazon Elastic Container Registry (Amazon ECR) 资源，您必须授予以下权限。
  + Amazon ECR 要求用户通过 AWS Identity and Access Management (IAM) 策略授予`ecr:GetAuthorizationToken`权限，然后才能向注册表进行身份验证以及从 Amazon ECR 存储库推送或拉取映像。有关更多信息，请参阅 *Amazon Elastic Container Registry 用户指南*中的 [Amazon ECR 存储库策略示例](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html)和[访问一个 Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-one-bucket)。

## 第 1 步：从 Amazon ECR 获取 AWS IoT Greengrass 容器镜像
<a name="docker-pull-image"></a>

AWS 提供安装了 AWS IoT Greengrass 核心软件的 Docker 镜像。

**警告**  <a name="docker-images-python-2.7-removal"></a>
从 AWS IoT Greengrass 核心软件的 v1.11.6 开始，Greengrass Docker 镜像不再包含 Python 2.7，因为 Python 2.7 已于 2020 年推出，不再接收安全更新。 end-of-life如果您选择更新这些 Docker 映像，我们建议您在将更新部署到生产设备之前，先验证应用程序是否可以使用新的 Docker 映像。如果使用 Greengrass Docker 映像的应用程序需要 Python 2.7，您可以修改 Greengrass Dockerfile，为您的应用程序包含 Python 2.7。

有关演示如何从 Amazon ECR 拉取 `latest` 映像的步骤，请选择您的操作系统：

### 拉取容器镜像 (Linux)
<a name="docker-pull-image-linux"></a>

在计算机终端中运行以下命令。

1. <a name="docker-get-login"></a>在 Amazon ECR 中登录 AWS IoT Greengrass 注册表。

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   如果成功，输出将打印 `Login Succeeded`。

1. <a name="docker-docker-pull"></a>检索 AWS IoT Greengrass 容器镜像。

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**注意**  
该`latest`镜像包含安装在 Amazon Linux 2 基础映像上的 AWS IoT Greengrass 核心软件的最新稳定版本。您还可以从存储库中拉取其他版本。要查找所有可用映像的标签，请查看 [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) 上的 **标签**页面或使用 **aws ecr list-images** 命令。例如：  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

1. 启用符号链接和硬链接保护。如果您正在尝试在容器 AWS IoT Greengrass 中运行，则只能启用当前启动的设置。
**注意**  
您可能需要使用 **sudo** 才能运行这些命令。
   + 要仅启用当前引导的设置，请执行以下操作：

     ```
     echo 1 > /proc/sys/fs/protected_hardlinks
     echo 1 > /proc/sys/fs/protected_symlinks
     ```
   + 要使设置在重新启动后保持不变，请执行以下操作：

     ```
     echo '# AWS IoT Greengrass' >> /etc/sysctl.conf 
     echo 'fs.protected_hardlinks = 1' >> /etc/sysctl.conf 
     echo 'fs.protected_symlinks = 1' >> /etc/sysctl.conf
     
     sysctl -p
     ```

1. <a name="docker-linux-enable-ipv4"></a>启用 IPv4 网络转发，这是在 Linux 上 AWS IoT Greengrass 运行云部署和 MQTT 通信所必需的。在 `/etc/sysctl.conf` 文件中，将 `net.ipv4.ip_forward` 设置为 1，然后重新加载 `sysctls`。

   ```
   sudo nano /etc/sysctl.conf
   # set this net.ipv4.ip_forward = 1
   sudo sysctl -p
   ```
**注意**  
您可以使用您选择的编辑器而不是 nano。

### 拉取容器镜像 (macOS)
<a name="docker-pull-image-mac"></a>

在计算机终端中运行以下命令。

1. <a name="docker-get-login"></a>在 Amazon ECR 中登录 AWS IoT Greengrass 注册表。

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   如果成功，输出将打印 `Login Succeeded`。

1. <a name="docker-docker-pull"></a>检索 AWS IoT Greengrass 容器镜像。

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**注意**  
该`latest`镜像包含安装在 Amazon Linux 2 基础映像上的 AWS IoT Greengrass 核心软件的最新稳定版本。您还可以从存储库中拉取其他版本。要查找所有可用映像的标签，请查看 [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) 上的 **标签**页面或使用 **aws ecr list-images** 命令。例如：  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

### 拉取容器镜像 (Windows)
<a name="docker-pull-image-windows"></a>

在命令提示符中运行以下命令。Docker 桌面必须先处于运行状态，然后您才能在 Windows 上使用 Docker 命令。

1. <a name="docker-get-login"></a>在 Amazon ECR 中登录 AWS IoT Greengrass 注册表。

   ```
   aws ecr get-login-password --region  us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com
   ```

   如果成功，输出将打印 `Login Succeeded`。

1. <a name="docker-docker-pull"></a>检索 AWS IoT Greengrass 容器镜像。

   ```
   docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```
**注意**  
该`latest`镜像包含安装在 Amazon Linux 2 基础映像上的 AWS IoT Greengrass 核心软件的最新稳定版本。您还可以从存储库中拉取其他版本。要查找所有可用映像的标签，请查看 [Docker Hub](https://hub.docker.com/r/amazon/aws-iot-greengrass) 上的 **标签**页面或使用 **aws ecr list-images** 命令。例如：  

   ```
   aws ecr list-images --region us-west-2 --registry-id 216483018798 --repository-name aws-iot-greengrass
   ```

## 步骤 2：创建和配置 Greengrass 组和核心
<a name="docker-config-gg"></a>

Docker 镜像安装了 AWS IoT Greengrass 核心软件，但你必须创建 Greengrass 组和内核。这包括下载证书和核心配置文件。
+ 按照 [模块 2：安装 AWS IoT Greengrass 核心软件](module2.md) 中的步骤操作。跳过下载和运行 AWS IoT Greengrass Core 软件的步骤。Docker 镜像中已设置软件及其运行时依赖项。

## 步骤 3： AWS IoT Greengrass 在本地运行
<a name="docker-run-gg"></a>

配置您的组后，便能配置和启动核心。有关演示如何执行此操作的步骤，请选择您的操作系统：

### 本地运行 Greengrass (Linux)
<a name="docker-run-gg-linux"></a>

在计算机终端中运行以下命令。

1. <a name="docker-create-certs-folder"></a>为设备的安全资源创建一个文件夹，然后将证书和密钥移入该文件夹中。运行以下命令。*path-to-security-files*替换为安全资源的路径，并*certificateId*替换为文件名中的证书 ID。

   ```
   mkdir /tmp/certs
   mv path-to-security-files/certificateId-certificate.pem.crt /tmp/certs
   mv path-to-security-files/certificateId-public.pem.key /tmp/certs
   mv path-to-security-files/certificateId-private.pem.key /tmp/certs
   mv path-to-security-files/AmazonRootCA1.pem /tmp/certs
   ```

1. <a name="docker-create-config-folder"></a>为设备配置创建一个文件夹，然后将 AWS IoT Greengrass Core 配置文件移至该文件夹。运行以下命令。*path-to-config-file*替换为配置文件的路径。

   ```
   mkdir /tmp/config
   mv path-to-config-file/config.json /tmp/config
   ```

1. <a name="docker-docker-run"></a>在 Docker 容器中启动 AWS IoT Greengrass 并绑定挂载证书和配置文件。

   将 `/tmp` 替换为您解压证书和配置文件的路径。

   ```
   docker run --rm --init -it --name aws-iot-greengrass \
   --entrypoint /greengrass-entrypoint.sh \
   -v /tmp/certs:/greengrass/certs \
   -v /tmp/config:/greengrass/config \
   -p 8883:8883 \
   216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   输出应类似于此示例：

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

### 本地运行 Greengrass (macOS)
<a name="docker-run-gg-mac"></a>

在计算机终端中运行以下命令。

1. <a name="docker-create-certs-folder"></a>为设备的安全资源创建一个文件夹，然后将证书和密钥移入该文件夹中。运行以下命令。*path-to-security-files*替换为安全资源的路径，并*certificateId*替换为文件名中的证书 ID。

   ```
   mkdir /tmp/certs
   mv path-to-security-files/certificateId-certificate.pem.crt /tmp/certs
   mv path-to-security-files/certificateId-public.pem.key /tmp/certs
   mv path-to-security-files/certificateId-private.pem.key /tmp/certs
   mv path-to-security-files/AmazonRootCA1.pem /tmp/certs
   ```

1. <a name="docker-create-config-folder"></a>为设备配置创建一个文件夹，然后将 AWS IoT Greengrass Core 配置文件移至该文件夹。运行以下命令。*path-to-config-file*替换为配置文件的路径。

   ```
   mkdir /tmp/config
   mv path-to-config-file/config.json /tmp/config
   ```

1. <a name="docker-docker-run"></a>在 Docker 容器中启动 AWS IoT Greengrass 并绑定挂载证书和配置文件。

   将 `/tmp` 替换为您解压证书和配置文件的路径。

   ```
   docker run --rm --init -it --name aws-iot-greengrass \
   --entrypoint /greengrass-entrypoint.sh \
   -v /tmp/certs:/greengrass/certs \
   -v /tmp/config:/greengrass/config \
   -p 8883:8883 \
   216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   输出应类似于此示例：

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

### 本地运行 Greengrass (Windows)
<a name="docker-run-gg-windows"></a>

1. 为设备的安全资源创建一个文件夹，然后将证书和密钥移入该文件夹中。在命令提示符中运行以下命令。*path-to-security-files*替换为安全资源的路径，并*certificateId*替换为文件名中的证书 ID。

   ```
   mkdir C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-certificate.pem.crt C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-public.pem.key C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\certificateId-private.pem.key C:\Users\%USERNAME%\Downloads\certs
   move path-to-security-files\AmazonRootCA1.pem C:\Users\%USERNAME%\Downloads\certs
   ```

1. 为设备配置创建一个文件夹，然后将 AWS IoT Greengrass Core 配置文件移至该文件夹。在命令提示符中运行以下命令。*path-to-config-file*替换为配置文件的路径。

   ```
   mkdir C:\Users\%USERNAME%\Downloads\config
   move path-to-config-file\config.json C:\Users\%USERNAME%\Downloads\config
   ```

1. 在 Docker 容器中启动 AWS IoT Greengrass 并绑定挂载证书和配置文件。在命令提示符处运行以下命令。

   ```
   docker run --rm --init -it --name aws-iot-greengrass --entrypoint /greengrass-entrypoint.sh -v c:/Users/%USERNAME%/Downloads/certs:/greengrass/certs -v c:/Users/%USERNAME%/Downloads/config:/greengrass/config -p 8883:8883 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
   ```

   当 Docker 提示您与 Docker 守护程序共享 `C:\` 驱动器时，允许它在 Docker 容器内绑定挂载 `C:\` 目录。有关更多信息，请参阅 Docker 文档中的[共享驱动器](https://docs.docker.com/docker-for-windows/#shared-drives)。

   输出应类似于此示例：

   ```
   Setting up greengrass daemon
   Validating hardlink/softlink protection
   Waiting for up to 30s for Daemon to start
   
   Greengrass successfully started with PID: 10
   ```

**注意**  
如果容器不打开 shell 并立即退出，则可以在启动映像时通过绑定挂载 Greengrass 运行时日志来调试问题。有关更多信息，请参阅 [在 Docker 容器之外保留 Greengrass 运行时日志](#debugging-docker-persist-logs)。

## 步骤 4：为 Greengrass 组配置“No container (无容器)”容器化
<a name="docker-no-container"></a>

在 Docker 容器 AWS IoT Greengrass 中运行时，所有 Lambda 函数都必须在不进行容器化的情况下运行。在此步骤中，将组的默认容器化设置为 **No container (无容器)**。在首次部署组之前，您必须执行此操作。

1. <a name="console-gg-groups"></a>**在 AWS IoT 控制台导航窗格的**管理**下，展开 **Greengrass** 设备，然后选择群组 (V1)。**

1. <a name="group-choose-group"></a>选择要更改其设置的组。

1. 选择 **Lambda 函数**选项卡。

1. 在**默认 Lambda 函数运行时环境**下，选择**编辑**。

1. 在**编辑默认 Lambda 函数运行时环境**中，更改 **Lambda 函数容器化**下的容器化设置。

1. 选择**保存**。

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

有关更多信息，请参阅 [在组中设置 Lambda 函数的默认容器化](lambda-group-config.md#lambda-containerization-groupsettings)。

**注意**  
默认情况下，Lambda 函数使用组容器化设置。当 AWS IoT Greengrass 在 Docker 容器中运行时，如果您覆盖任何 Lambda 函数的**无容器**设置，则部署将失败。

## 第 5 步：将 Lambda 函数部署到 Docker 容器 AWS IoT Greengrass
<a name="docker-add-lambdas"></a>

您可以将长期存在的 Lambda 函数部署到 Greengrass Docker 容器。
+ 执行 [模块 3（第 1 部分）：开启 Lambda 函数 AWS IoT Greengrass](module3-I.md) 中的步骤以将长期存在的 Hello World Lambda 函数部署到容器。

## 步骤 6：（可选）部署与 Docker 容器中运行的 Greengrass 交互的客户端设备
<a name="docker-add-devices"></a>

您还可以部署在 Docker 容器中运行 AWS IoT Greengrass 时与之交互的客户端设备。
+ 执行 [模块 4：与 AWS IoT Greengrass 群组中的客户端设备交互](module4.md) 中的步骤以部署连接到核心并发送 MQTT 消息的客户端设备。

## 停止 AWS IoT Greengrass Docker 容器
<a name="docker-stop"></a>

要停止 AWS IoT Greengrass Docker 容器，请在终端或命令提示符下按 Ctrl\$1C。此操作将向 Greengrass 守护程序进程发送 `SIGTERM` 以停用 Greengrass 守护程序进程及其启动的所有 Lambda 进程。Docker 容器通过 `/dev/init` 进程初始化为 PID 1，这有助于删除任何剩余的僵尸进程。有关更多信息，请参阅 [Docker 运行参考](https://docs.docker.com/engine/reference/commandline/run/#options)。

## 在 Docker AWS IoT Greengrass 容器中进行故障排除
<a name="troubleshooting-docker-gg"></a>

使用以下信息来帮助解决在 Docker 容器 AWS IoT Greengrass 中运行的问题。

### 错误：无法从非 TTY 设备执行交互式登录。
<a name="docker-troubleshootin-ecr-get-login-password"></a>

**解决方案：**运行 `aws ecr get-login-password` 命令时，可能会出现此错误。确保您已安装最新的 AWS CLI 版本 2 或版本 1。我们建议您使用 AWS CLI 版本 2。有关更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[安装 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)。

### 错误：未知选项：-no-include-email。
<a name="docker-troubleshooting-cli-version"></a>

**解决方案：**运行 `aws ecr get-login` 命令时，可能会出现此错误。确保安装了最新 AWS CLI 版本（例如，运行:`pip install awscli --upgrade --user`）。如果您使用的是 Windows，并且您已使用 MSI 安装程序安装 CLI，则必须重复安装过程。有关更多信息，请参阅*AWS Command Line Interface 用户指南*中的[在 Microsoft Windows 上安装 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/awscli-install-windows.html)。

### 警告： IPv4 已禁用。网络将不起作用。
<a name="docker-troubleshooting-ipv4-disabled"></a>

**解决方案：**在 Linux 计算机 AWS IoT Greengrass 上运行时，您可能会收到此警告或类似消息。按照本[步骤](#docker-linux-enable-ipv4)中的说明启用 IPv4 网络转发。 AWS IoT Greengrass 未启用 IPv4 转发功能时，云部署和 MQTT 通信不起作用。有关更多信息，请参阅 Docker 文档中的[在运行时配置具有命名空间的内核参数 (sysctls)](https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime)。

### 错误：防火墙阻止 Windows 和容器之间的文件共享。
<a name="docker-troubleshooting-firewall"></a>

**解决方案：**在 Windows 计算机上运行 Docker 时，您可能会收到此错误或 `Firewall Detected` 消息。如果您登录虚拟私有网络 (VPN) 并且网络设置阻止挂载共享驱动器，也会出现此错误。在这种情况下，请关闭 VPN 并重新运行 Docker 容器。

### 错误：调用 GetAuthorizationToken 操作时出现错误 (AccessDeniedException)：用户：arn: aws: iam::: user/ <account-id><user-name>无权在资源上执行:ecr:: GetAuthorizationToken
<a name="docker-troubleshooting-ecr-perms"></a>

如果您没有足够权限来访问 Amazon ECR 存储库，则运行 `aws ecr get-login-password` 命令时可能会收到此错误。有关更多信息，请参阅*Amazon ECR 用户指南*中的 [Amazon ECR 存储库策略示例](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html)和[访问 One Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html)。

有关一般 AWS IoT Greengrass 故障排除帮助，请参阅[故障排除 AWS IoT Greengrass](gg-troubleshooting.md)。

### AWS IoT Greengrass 在 Docker 容器中进行调试
<a name="debugging-docker-gg"></a>

要调试 Docker 容器的问题，您可以保留 Greengrass 运行时日志或将交互式 shell 附加到 Docker 容器。

#### 在 Docker 容器之外保留 Greengrass 运行时日志
<a name="debugging-docker-persist-logs"></a>

您可以在绑定挂载目录后运行 AWS IoT Greengrass Docker 容器。`/greengrass/ggc/var/log`即使容器退出或被删除，日志仍然存在。

**在 Linux 或 macOS 上**  
[停止任何在主机上运行的 Greengrass Docker 容器](#docker-stop)，然后在终端中运行以下命令。这会绑定挂载 Greengrass `log` 目录并启动 Docker 镜像。  
将 `/tmp` 替换为您解压证书和配置文件的路径。  

```
docker run --rm --init -it --name aws-iot-greengrass \
      --entrypoint /greengrass-entrypoint.sh \
      -v /tmp/certs:/greengrass/certs \
      -v /tmp/config:/greengrass/config \
      -v /tmp/log:/greengrass/ggc/var/log \
      -p 8883:8883 \
      216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
```
然后，您可以在主机上的 `/tmp/log` 中检查日志，以查看 Greengrass 在 Docker 容器内运行时发生的情况。

**在 Windows 上**  
[停止任何在主机上运行的 Greengrass Docker 容器](#docker-stop)，然后在命令提示符中运行以下命令。这会绑定挂载 Greengrass `log` 目录并启动 Docker 镜像。  

```
cd C:\Users\%USERNAME%\Downloads
mkdir log
docker run --rm --init -it --name aws-iot-greengrass --entrypoint /greengrass-entrypoint.sh -v c:/Users/%USERNAME%/Downloads/certs:/greengrass/certs -v c:/Users/%USERNAME%/Downloads/config:/greengrass/config -v c:/Users/%USERNAME%/Downloads/log:/greengrass/ggc/var/log -p 8883:8883 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest
```
然后，您可以在主机上的 `C:/Users/%USERNAME%/Downloads/log` 中检查日志，以查看 Greengrass 在 Docker 容器内运行时发生的情况。

#### 将交互式 Shell 附加到 Docker 容器
<a name="debugging-docker-attach-shell"></a>

您可以将交互式外壳附加到正在运行的 AWS IoT Greengrass Docker 容器上。这可以帮助您调查 Greengrass Docker 容器的状态。

**在 Linux 或 macOS 上**  
当 Greengrass Docker 容器正在运行时，在单独的终端中运行以下命令。  

```
docker exec -it $(docker ps -a -q -f "name=aws-iot-greengrass") /bin/bash
```

**在 Windows 上**  
当 Greengrass Docker 容器正在运行时，在单独的命令提示符中运行以下命令。  

```
docker ps -a -q -f "name=aws-iot-greengrass"
```
*gg-container-id*替换为上一个命令的`container_id`结果。  

```
docker exec -it gg-container-id /bin/bash
```