

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

# 开发 AWS IoT Greengrass 组件
<a name="develop-greengrass-components"></a>

您可以在 Greengrass 核心设备上开发和测试组件。因此，您无需与 AWS 云 交互即可创建和迭代 AWS IoT Greengrass 软件。完成组件版本后，可以将其上传到 AWS IoT Greengrass 云端，这样您和您的团队就可以将该组件部署到实例集中的其他设备上。有关如何部署组件的更多信息，请参阅 [将 AWS IoT Greengrass 组件部署到设备](manage-deployments.md)。

每个组件都包含*配方*和*构件*。
+ <a name="component-recipe-definition"></a>**配方**

  每个组件都包含一个用于定义其元数据的配方文件。此配方还指定了组件的配置参数、组件依赖关系、生命周期和平台兼容性。组件生命周期指定了安装、运行和关闭组件时要运行的命令。有关更多信息，请参阅 [AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)。

  您可以用 [JSON](https://en.wikipedia.org/wiki/JSON) 或 [YAML](https://en.wikipedia.org/wiki/YAML) 格式定义配方。
+ <a name="component-artifacts-definition"></a>**构件**

  组件可以有任意数量的构件，即组件二进制文件。构件可以包括脚本、编译的代码、静态资源以及组件使用的任何其他文件。组件还可以使用组件依赖关系中的构件。

AWS IoT Greengrass 提供了预构建组件，您可以在应用程序中使用这些组件并部署到您的设备上。例如，您可以使用流管理器组件将数据上传到各种 AWS 服务，也可以使用 CloudWatch 指标组件将自定义指标发布到 Amazon CloudWatch。有关更多信息，请参阅 [AWS 提供的组件](public-components.md)。

AWS IoT Greengrass 整理了一份名为 Greengrass 软件目录的 Greengrass 组件索引。该目录跟踪 Greengrass 社区开发的 Greengrass 组件。您可以从该目录中下载、修改和部署组件来创建 Greengrass 应用程序。有关更多信息，请参阅 [社区组件](greengrass-software-catalog.md)。

AWS IoT Greengrass Core 软件以系统用户和组的身份运行您在核心设备上配置的组件，例如 `ggc_user` 和 `ggc_group`。这意味着组件拥有该系统用户的权限。如果使用没有主目录的系统用户，那么组件将无法运行依赖主目录的命令或代码。例如，这意味着您不能使用 `pip install some-library --user` 命令来安装 Python 软件包。如果您按照[入门教程](getting-started.md)设置核心设备，那么您的系统用户则没有主目录。有关如何配置运行组件的用户和组的更多信息，请参阅 [配置运行组件的用户](configure-greengrass-core-v2.md#configure-component-user)。

**注意**  <a name="semver-note"></a>
<a name="semver-para"></a>AWS IoT Greengrass 使用组件的语义版本。语义版本遵循 *major*.*minor*.*patch* 编号系统。例如，版本 `1.0.0` 表示组件的第一个主要版本。有关更多信息，请参阅[语义版本规范](https://semver.org/)。

**Topics**
+ [组件生命周期](#component-lifecycle)
+ [组件类型](#component-types)
+ [创建 AWS IoT Greengrass 组件](create-components.md)
+ [使用本地部署测试 AWS IoT Greengrass 组件](test-components.md)
+ [发布组件以部署到您的核心设备](publish-components.md)
+ [与 AWS 服务交互](interact-with-aws-services.md)
+ [运行 Docker 容器](run-docker-container.md)
+ [AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)
+ [组件环境变量参考](component-environment-variables.md)

## 组件生命周期
<a name="component-lifecycle"></a>

*组件生命周期*定义了 AWS IoT Greengrass Core 软件用于安装和运行组件的阶段。每个阶段都定义一个脚本和其他信息，用于指定组件的行为。例如，在安装组件时，AWS IoT Greengrass Core 软件会运行该组件的 `install` 生命周期脚本。核心设备上的组件具有以下生命周期状态：
+ `NEW` – 组件的配方和构件已加载至核心设备，但未安装该组件。组件进入此状态后，它会运行其[安装脚本](component-recipe-reference.md#install-lifecycle-definition)。
+ `INSTALLED` – 该组件已安装于核心设备。组件在运行其[安装脚本](component-recipe-reference.md#install-lifecycle-definition)后进入此状态。
+ `STARTING` – 该组件在核心设备上启动。组件在运行其[安装脚本](component-recipe-reference.md#startup-lifecycle-definition)时进入此状态。如果启动成功，则组件进入 `RUNNING` 状态。
+ `RUNNING` – 该组件在核心设备上运行。当组件运行其[运行脚本](component-recipe-reference.md#run-lifecycle-definition)或启动脚本中有活跃的后台进程时，它就会进入此状态。
+ `FINISHED` – 组件成功运行并完成运行。
+ `STOPPING` – 组件停止运行。组件在运行其[关闭脚本](component-recipe-reference.md#shutdown-lifecycle-definition)时进入此状态。
+ `ERRORED` – 组件遇到错误。当组件进入此状态时，就会运行其[恢复脚本](component-recipe-reference.md#recover-lifecycle-definition)。然后，组件重启，尝试恢复正常运行。如果组件三次进入 `ERRORED` 状态而没有成功运行，则组件变为 `BROKEN`。
+ `BROKEN` – 组件多次遇到错误且无法恢复。您必须重新部署组件才能修复它。

## 组件类型
<a name="component-types"></a>

*组件类型*指定 AWS IoT Greengrass Core 软件如何运行组件。组件包括以下类型：
+ **Nucleus** (`aws.greengrass.nucleus`)

  Greengrass Nucleus 是提供 AWS IoT Greengrass Core 软件最低功能的组件。有关更多信息，请参阅 [Greengrass Nucleus](greengrass-nucleus-component.md)。
+ **插件** (`aws.greengrass.plugin`)

  Greengrass Nucleus 在与其相同的 Java 虚拟机（JVM）中运行该组件。当您在核心设备上更改此组件的版本时，核心会重新启动。要安装和运行插件组件，必须配置 Greengrass Nucleus，使其作为系统服务运行。有关更多信息，请参阅 [将 Greengrass Nucleus 配置为系统服务](configure-greengrass-core-v2.md#configure-system-service)。

  AWS 提供的几个组件为插件组件，允许它们直接与 Greengrass Nucleus 交互。插件组件使用与 Greengrass Nucleus 相同的日志文件。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。
+ **通用** (`aws.greengrass.generic`)

  如果通用组件定义了生命周期，Greengrass Nucleus 会运行该组件的生命周期脚本。

  此类型是自定义组件的默认类型。
+ **Lambda** (`aws.greengrass.lambda`)

  Greengrass Nucleus 使用 [Lambda 启动程序组件](lambda-launcher-component.md)运行 Lambda 函数。

  当您从 Lambda 函数创建组件时，该组件包括此类型。有关更多信息，请参阅 [运行 AWS Lambda 函数](run-lambda-functions.md)。

**注意**  <a name="recipe-component-type-recommendation"></a>
我们建议您不要在配方中指定组件类型。AWS IoT Greengrass 会在您创建组件时为您设置类型。

# 创建 AWS IoT Greengrass 组件
<a name="create-components"></a>

您可以在本地开发计算机或 Greengrass 核心设备上开发自定义 AWS IoT Greengrass 组件。AWS IoT Greengrass 提供 [AWS IoT Greengrass 开发工具包命令行界面（GDK CLI）](greengrass-development-kit-cli.md)，可帮助您根据预定义的组件模板和[社区组件](greengrass-software-catalog.md)创建、构建和发布组件。您还可以运行内置的 Shell 命令来创建、构建和发布组件。从以下选项中进行选择，以创建自定义 Greengrass 组件：
+ **使用 Greengrass 开发工具包 CLI**

  使用 GDK CLI 在本地开发计算机上开发组件。GDK CLI 构建组件源代码并将其打包成配方和构件，您可以将其作为私有组件发布到 AWS IoT Greengrass 服务。您可以配置 GDK CLI，以在发布组件时自动更新组件的版本和构件 URI，因此无需每次都更新配方。要使用 GDK CLI 开发组件，可以从 [Greengrass 软件目录](greengrass-software-catalog.md)中的模板或社区组件开始。有关更多信息，请参阅 [AWS IoT Greengrass 开发工具包命令行界面](greengrass-development-kit-cli.md)。
+ **运行内置 Shell 命令**

  您可以运行内置 Shell 命令在本地开发计算机或 Greengrass 核心设备上开发组件。您可以使用 Shell 命令将组件源代码复制或构建到构件中。每次创建组件的新版本时，都必须使用新的组件版本创建或更新配方。将组件发布到 AWS IoT Greengrass 服务时，必须更新配方中每个组件构件的 URI。

**Topics**
+ [创建组件（GDK CLI）](#create-component-gdk-cli)
+ [创建组件（Shell 命令）](#create-component-shell-commands)

## 创建组件（GDK CLI）
<a name="create-component-gdk-cli"></a>

按照本节中的说明，使用 GDK CLI 创建和构建组件。

**要开发 Greengrass 组件（GDK CLI），请执行以下操作**

1. 如果尚未安装 GDK CLI，请在开发计算机上进行安装。有关更多信息，请参阅 [安装或更新 AWS IoT Greengrass 开发工具包命令行界面](install-greengrass-development-kit-cli.md)。

1. 更改为要在其中创建组件文件夹的文件夹。

------
#### [ Linux or Unix ]

   ```
   mkdir ~/greengrassv2
   cd ~/greengrassv2
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   mkdir %USERPROFILE%\greengrassv2
   cd %USERPROFILE%\greengrassv2
   ```

------
#### [ PowerShell ]

   ```
   mkdir ~/greengrassv2
   cd ~/greengrassv2
   ```

------

1. 选择要下载的组件模板或社区组件。GDK CLI 下载模板或社区组件，因此您可以从功能示例开始。使用 [component list](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-list) 命令检索可用模板或社区组件的列表。
   + 要列出组件模板，请运行以下命令。响应中的每一行都包含模板的名称和编程语言。

     ```
     gdk component list --template
     ```
   + 要列出社区组件，请运行以下命令。

     ```
     gdk component list --repository
     ```

1. 创建并更改为供 GDK CLI 下载模板或社区组件的组件文件夹。将 *HelloWorld* 替换为组件的名称或其他可帮助您识别此组件文件夹的名称。

------
#### [ Linux or Unix ]

   ```
   mkdir HelloWorld
   cd HelloWorld
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   mkdir HelloWorld
   cd HelloWorld
   ```

------
#### [ PowerShell ]

   ```
   mkdir HelloWorld
   cd HelloWorld
   ```

------

1. 将模板或社区组件下载到当前文件夹。使用 [component init](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-init) 命令。
   + 要从模板创建组件文件夹，请运行以下命令。将 *HelloWorld* 替换为模板的名称，并将 *python* 替换为编程语言的名称。

     ```
     gdk component init --template HelloWorld --language python
     ```
   + 要从社区组件创建组件文件夹，请运行以下命令。将 *ComponentName* 替换为社区组件的名称。

     ```
     gdk component init --repository ComponentName
     ```
**注意**  
<a name="gdk-cli-component-init-empty-folder-requirement"></a>如果您使用的是 GDK CLI v1.0.0，则必须在空文件夹中运行此命令。GDK CLI 会将模板或社区组件下载到当前文件夹。  
<a name="gdk-cli-component-init-empty-folder-requirement-gdk-cli-v1.1.0"></a>如果您使用的是 GDK CLI v1.1.0 或更高版本，则可以指定 `--name` 参数来指定供 GDK CLI 下载模板或社区组件的文件夹。如果使用此参数，请指定一个不存在的文件夹。GDK CLI 会为您创建文件夹。如果您不指定此参数，GDK CLI 将使用当前文件夹，此文件夹必须为空。

1. GDK CLI 从名为 `gdk-config.json` 的 [GDK CLI 配置文件](gdk-cli-configuration-file.md)中读取数据，以生成和发布组件。此配置文件存在于组件文件夹的根目录中。在上一步中，将为您创建此文件。在这一步中，使用组件的相关信息更新 `gdk-config.json`。执行以下操作：

   1. 在文本编辑器中打开 `gdk-config.json`。

   1. （可选）更改组件的名称。组件名称是 `component` 对象中的关键。

   1. 更改组件的作者。

   1. （可选）更改组件的版本。指定下列项之一：<a name="gdk-cli-configuration-file-component-version-options"></a>
      + `NEXT_PATCH` – 当您选择此选项时，GDK CLI 将在您发布组件时设置版本。GDK CLI 会查询 AWS IoT Greengrass 服务以识别组件的最新发布版本。然后，它将版本设置为该版本之后的下一个补丁版本。如果您之前没有发布过组件，GDK CLI 将使用版本 `1.0.0`。

        如果您选择此选项，则无法使用 [Greengrass CLI](greengrass-cli-component.md) 在本地为运行 AWS IoT Greengrass Core 软件的本地开发计算机部署和测试组件。要启用本地部署，您必须改为指定语义版本。
      + 语义版本，例如 **1.0.0**。语义版本使用 *major*.*minor*.*patch* 编号系统。有关更多信息，请参阅[语义版本规范](https://semver.org/)。

        如果在要为其部署和测试组件的 Greengrass 核心设备上开发组件，请选择此选项。您必须使用特定版本构建组件，才能通过 [Greengrass CLI](greengrass-cli-component.md) 创建本地部署。

   1. （可选）更改组件的构建配置。构建配置定义了 GDK CLI 如何将组件的源代码构建到构件中。对于 `build_system`，您可以从以下选项中进行选择：<a name="gdk-cli-configuration-file-component-build-system-options"></a>
      + `zip` – 将组件的文件夹打包成 ZIP 文件以定义为该组件的唯一构件。为以下类型的组件选择此选项：
        + 使用解释型编程语言（例如 Python 或 JavaScript）的组件。
        + 用于打包除代码之外的文件的组件，例如机器学习模型或其他资源。

        GDK CLI 将组件的文件夹压缩成与组件文件夹同名的 zip 文件。例如，如果组件文件夹的名称为 `HelloWorld`，则 GDK CLI 会创建名为 `HelloWorld.zip` 的 zip 文件。
**注意**  
如果在 Windows 设备上使用 GDK CLI 版本 1.0.0，则组件文件夹名称和 zip 文件名称必须仅包含小写字母。

        当 GDK CLI 将组件的文件夹压缩成 zip 文件时，系统会跳过以下文件：
        + `gdk-config.json` 文件
        + 配方文件（`recipe.json` 或 `recipe.yaml`）
        + 构建文件夹，例如 `greengrass-build`
      + `maven` – 运行 `mvn clean package` 命令以将组件的源代码构建为构件。对于使用 [Maven](https://maven.apache.org/) 的组件（例如 Java 组件），请选择此选项。

        在 Windows 设备上，此功能适用于 GDK CLI v1.1.0 及更高版本。
      + `gradle` – 运行 `gradle build` 命令以将组件的源代码构建为构件。对于使用 [Gradle](https://gradle.org/) 的组件，请选择此选项。此功能适用于 GDK CLI v1.1.0 及更高版本。

        `gradle` 构建系统支持 Kotlin DSL 作为构建文件。此功能适用于 GDK CLI v1.2.0 及更高版本。
      + `gradlew` – 运行 `gradlew` 命令以将组件的源代码构建为构件。对于使用 [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) 的组件，请选择此选项。

        此功能适用于 GDK CLI v1.2.0 及更高版本。
      + `custom` – 运行自定义命令，将组件的源代码构建为配方和构件。在 `custom_build_command` 参数中指定自定义命令。

   1. 如果您为 `build_system` 指定 `custom`，请将 `custom_build_command` 添加到 `build` 对象中。在 `custom_build_command` 中，指定单个字符串或字符串列表，其中每个字符串都是命令中的一个单词。例如，要为 C\$1\$1 组件运行自定义构建命令，可以指定 **["cmake", "--build", "build", "--config", "Release"]**。

   1. <a name="gdk-cli-s3-bucket-name-formation"></a>如果您使用的是 GDK CLI v1.1.0 或更高版本，则可以指定 `--bucket` 参数来指定供 GDK CLI 上传组件构件的 S3 存储桶。<a name="gdk-cli-s3-bucket-name-formation-format"></a>如果未指定此参数，GDK CLI 会上传到名为 `bucket-region-accountId` 的 S3 存储桶，其中 *bucket* 和 *region* 是您在 `gdk-config.json` 中指定的值，*accountId* 是您的 AWS 账户 ID。如果存储桶不存在，GDK CLI 将创建该存储桶。

      更改组件的发布配置。执行以下操作：

      1. 指定用于托管组件构件的 S3 存储桶的名称。

      1. 指定供 GDK CLI 发布组件的 AWS 区域。

   这一步完成后，`gdk-config.json` 文件可能类似于以下示例。

   ```
   {
     "component": {
       "com.example.PythonHelloWorld": {
         "author": "Amazon",
         "version": "NEXT_PATCH",
         "build": {
           "build_system" : "zip"
         },
         "publish": {
           "bucket": "greengrass-component-artifacts",
           "region": "us-west-2"
         }
       }
     },
     "gdk_version": "1.0.0"
   }
   ```

1. 更新名为 `recipe.yaml` 或 `recipe.json` 的组件配方文件。执行以下操作：

   1. 如果您下载了使用 `zip` 构建系统的模板或社区组件，请检查 zip 构件名称是否与组件文件夹的名称相匹配。GDK CLI 将组件文件夹压缩成与组件文件夹同名的 ZIP 文件。配方在组件构件列表和使用 zip 构件中文件的生命周期脚本中包含 zip 构件名称。更新 `Artifacts` 和 `Lifecycle` 定义，使 zip 文件名与组件文件夹的名称相匹配。以下部分配方示例突出显示了 `Artifacts` 和 `Lifecycle` 定义中的 zip 文件名。

------
#### [ JSON ]

      ```
      {
        ...
        "Manifests": [
          {
            "Platform": {
              "os": "all"
            },
            "Artifacts": [
              {
                "URI": "s3://{COMPONENT_NAME}/{COMPONENT_VERSION}/HelloWorld.zip",
                "Unarchive": "ZIP"
              }
            ],
            "Lifecycle": {
              "Run": "python3 -u {artifacts:decompressedPath}/HelloWorld/main.py {configuration:/Message}"
            }
          }
        ]
      }
      ```

------
#### [ YAML ]

      ```
      ---
      ...
      Manifests:
        - Platform:
            os: all
          Artifacts:
            - URI: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/HelloWorld.zip"
              Unarchive: ZIP
          Lifecycle:
            Run: "python3 -u {artifacts:decompressedPath}/HelloWorld/main.py {configuration:/Message}"
      ```

------

   1. （可选）更新组件描述、默认配置、构件、生命周期脚本和平台支持。有关更多信息，请参阅 [AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)。

   这一步完成后，配方文件可能类似于以下示例。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "{COMPONENT_NAME}",
     "ComponentVersion": "{COMPONENT_VERSION}",
     "ComponentDescription": "This is a simple Hello World component written in Python.",
     "ComponentPublisher": "{COMPONENT_AUTHOR}",
     "ComponentConfiguration": {
       "DefaultConfiguration": {
         "Message": "World"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "all"
         },
         "Artifacts": [
           {
             "URI": "s3://{COMPONENT_NAME}/{COMPONENT_VERSION}/HelloWorld.zip",
             "Unarchive": "ZIP"
           }
         ],
         "Lifecycle": {
           "Run": "python3 -u {artifacts:decompressedPath}/HelloWorld/main.py {configuration:/Message}"
         }
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: "2020-01-25"
   ComponentName: "{COMPONENT_NAME}"
   ComponentVersion: "{COMPONENT_VERSION}"
   ComponentDescription: "This is a simple Hello World component written in Python."
   ComponentPublisher: "{COMPONENT_AUTHOR}"
   ComponentConfiguration:
     DefaultConfiguration:
       Message: "World"
   Manifests:
     - Platform:
         os: all
       Artifacts:
         - URI: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/HelloWorld.zip"
           Unarchive: ZIP
       Lifecycle:
         Run: "python3 -u {artifacts:decompressedPath}/HelloWorld/main.py {configuration:/Message}"
   ```

------

1. 开发和构建 Greengrass 组件。[component build](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-build) 命令在组件文件夹的 `greengrass-build` 文件夹中生成配方和构件。运行以下命令。

   ```
   gdk component build
   ```

准备测试组件时，使用 GDK CLI 将其发布到 AWS IoT Greengrass 服务。然后，可以将组件部署到 Greengrass 核心设备。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md)。

## 创建组件（Shell 命令）
<a name="create-component-shell-commands"></a>

按照本节中的说明，创建包含多个组件的源代码和构件的配方和构件文件夹。

**要开发 Greengrass 组件（Shell 命令），请执行以下操作**

1. <a name="create-component-recipes-artifacts-folder-step"></a>为您的组件创建一个文件夹，其中包含用于存放配方和构件的子文件夹。在 Greengrass 核心设备上运行以下命令来创建这些文件夹并更改为组件文件夹。将 *\$1/greengrassv2* 或 *%USERPROFILE%\$1greengrassv2* 替换为用于本地开发的文件夹路径。

------
#### [ Linux or Unix ]

   ```
   mkdir -p ~/greengrassv2/{recipes,artifacts}
   cd ~/greengrassv2
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   mkdir %USERPROFILE%\greengrassv2\\recipes, %USERPROFILE%\greengrassv2\\artifacts
   cd %USERPROFILE%\greengrassv2
   ```

------
#### [ PowerShell ]

   ```
   mkdir ~/greengrassv2/recipes, ~/greengrassv2/artifacts
   cd ~/greengrassv2
   ```

------

1. <a name="create-component-recipe-file-step"></a>使用文本编辑器创建配方文件，在该配方文件中定义组件的元数据、参数、依赖关系、生命周期和平台功能。在配方文件名中包含组件版本，以便您可以识别哪个配方对应哪个组件版本。您可以为配方选择 YAML 或 JSON 格式。

   <a name="nano-command-intro"></a>例如，在基于 Linux 的系统上，您可以运行以下命令来使用 GNU nano 创建该文件。

------
#### [ JSON ]

   ```
   nano recipes/com.example.HelloWorld-1.0.0.json
   ```

------
#### [ YAML ]

   ```
   nano recipes/com.example.HelloWorld-1.0.0.yaml
   ```

------
**注意**  
<a name="semver-para"></a>AWS IoT Greengrass 使用组件的语义版本。语义版本遵循 *major*.*minor*.*patch* 编号系统。例如，版本 `1.0.0` 表示组件的第一个主要版本。有关更多信息，请参阅[语义版本规范](https://semver.org/)。

1. 为您的组件定义配方。有关更多信息，请参阅 [AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)。

   您的配方可能类似于以下 Hello World 示例配方。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "com.example.HelloWorld",
     "ComponentVersion": "1.0.0",
     "ComponentDescription": "My first AWS IoT Greengrass component.",
     "ComponentPublisher": "Amazon",
     "ComponentConfiguration": {
       "DefaultConfiguration": {
         "Message": "world"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "linux"
         },
         "Lifecycle": {
           "run": "python3 -u {artifacts:path}/hello_world.py {configuration:/Message}"
         }
       },
       {
         "Platform": {
           "os": "windows"
         },
         "Lifecycle": {
           "run": "py -3 -u {artifacts:path}/hello_world.py {configuration:/Message}"
         }
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: '2020-01-25'
   ComponentName: com.example.HelloWorld
   ComponentVersion: '1.0.0'
   ComponentDescription: My first AWS IoT Greengrass component.
   ComponentPublisher: Amazon
   ComponentConfiguration:
     DefaultConfiguration:
       Message: world
   Manifests:
     - Platform:
         os: linux
       Lifecycle:
         run: |
           python3 -u {artifacts:path}/hello_world.py "{configuration:/Message}"
     - Platform:
         os: windows
       Lifecycle:
         run: |
           py -3 -u {artifacts:path}/hello_world.py "{configuration:/Message}"
   ```

------

   此配方运行 Hello World Python 脚本，该脚本可能类似于以下示例脚本。

   ```
   import sys
   
   message = "Hello, %s!" % sys.argv[1]
   
   # Print the message to stdout, which Greengrass saves in a log file.
   print(message)
   ```

1. 为要开发的组件版本创建文件夹。建议您为每个组件版本的构件使用单独的文件夹，以便您可以识别每个组件版本对应的构件。运行以下命令。

------
#### [ Linux or Unix ]

   ```
   mkdir -p artifacts/com.example.HelloWorld/1.0.0
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   mkdir artifacts/com.example.HelloWorld/1.0.0
   ```

------
#### [ PowerShell ]

   ```
   mkdir artifacts/com.example.HelloWorld/1.0.0
   ```

------
**重要**  <a name="local-artifact-folder-name-requirements"></a>
必须为构件文件夹路径使用以下格式。其中包括您在配方中指定的组件名称和版本。  

   ```
   artifacts/componentName/componentVersion/
   ```

1. 在上一步中创建的文件夹中为组件创建构件。构件可以包括软件、图像和组件使用的任何其他二进制文件。

   组件准备就绪后，请[测试组件](test-components.md)。

# 使用本地部署测试 AWS IoT Greengrass 组件
<a name="test-components"></a>

如果您在核心设备上开发 Greengrass 组件，则可以创建本地部署来安装和测试它。按照本节中的步骤创建本地部署。

如果您在另一台计算机（例如本地开发计算机）上开发组件，则无法创建本地部署。而是要将该组件发布至 AWS IoT Greengrass 服务，这样您就可以将其部署到 Greengrass 核心设备上进行测试。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md) 和[将 AWS IoT Greengrass 组件部署到设备](manage-deployments.md)。

**在 Greengrass 核心设备上测试组件**

1. 核心设备记录诸如组件更新之类的事件。您可以查看此日志文件来发现组件中的错误，并对其进行故障排除，例如无效配方。此日志文件还显示您的组件打印为标准输出（stdout）的消息。我们建议您在核心设备上再打开一个终端会话，以便实时查看新的日志消息。打开新的终端会话（例如通过 SSH），然后运行以下命令查看日志。将 `/greengrass/v2` 替换为 AWS IoT Greengrass 根文件夹路径。

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/greengrass.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2\logs\greengrass.log -Tail 10 -Wait
   ```

------

   您还可以查看您组件的日志文件。

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.HelloWorld.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2\logs\com.example.HelloWorld.log -Tail 10 -Wait
   ```

------

1. 在最初的终端会话中，运行以下命令即可使用您的组件更新核心设备。将 `/greengrass/v2` 替换为 AWS IoT Greengrass 根文件夹路径，并将 *\$1/greengrassv2* 替换为本地开发文件夹的路径。

------
#### [ Linux or Unix ]

   ```
   sudo /greengrass/v2/bin/greengrass-cli deployment create \
     --recipeDir ~/greengrassv2/recipes \
     --artifactDir ~/greengrassv2/artifacts \
     --merge "com.example.HelloWorld=1.0.0"
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   C:\greengrass\v2\bin\greengrass-cli deployment create ^
     --recipeDir %USERPROFILE%\greengrassv2\recipes ^
     --artifactDir %USERPROFILE%\greengrassv2\artifacts ^
     --merge "com.example.HelloWorld=1.0.0"
   ```

------
#### [ PowerShell ]

   ```
   C:\greengrass\v2\bin\greengrass-cli deployment create `
     --recipeDir ~/greengrassv2/recipes `
     --artifactDir ~/greengrassv2/artifacts `
     --merge "com.example.HelloWorld=1.0.0"
   ```

------
**注意**  
您也可以使用 `greengrass-cli deployment create` 命令来设置组件配置参数的值。有关更多信息，请参阅 [创建](gg-cli-deployment.md#deployment-create)。

1. 使用 `greengrass-cli deployment status` 命令监控组件的部署进度。

------
#### [ Unix or Linux ]

   ```
   sudo /greengrass/v2/bin/greengrass-cli deployment status \
     -i deployment-id
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   C:\greengrass\v2\bin\greengrass-cli deployment status ^
     -i deployment-id
   ```

------
#### [ PowerShell ]

   ```
   C:\greengrass\v2\bin\greengrass-cli deployment status `
     -i deployment-id
   ```

------

1. 测试您的组件，使其在 Greengrass 核心设备上运行。完成此版本组件后，将其上传至 AWS IoT Greengrass 服务。然后，可以将组件部署到其他核心设备。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md)。

# 发布组件以部署到您的核心设备
<a name="publish-components"></a>

构建或完成组件版本后，可以将其发布到 AWS IoT Greengrass 服务。然后，可以将其部署到 Greengrass 核心设备。

如果您使用 [Greengrass 工具包 CLI（GDK CLI）](greengrass-development-kit-cli.md)[开发和构建](create-components.md)组件，则可以[使用 GDK CLI](#publish-component-gdk-cli) 将该组件发布到 AWS 云。否则，请[使用内置 Shell 命令和 AWS CLI](#publish-component-shell-commands) 发布组件。

您还可以使用 AWS CloudFormation 从模板创建组件和其他 AWS 资源。有关更多信息，请参阅《AWS CloudFormation 用户指南》**中的[什么是AWS CloudFormation？](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)和 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-greengrassv2-componentversion.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-greengrassv2-componentversion.html)。

**Topics**
+ [发布组件（GDK CLI）](#publish-component-gdk-cli)
+ [发布组件（Shell 命令）](#publish-component-shell-commands)

## 发布组件（GDK CLI）
<a name="publish-component-gdk-cli"></a>

按照本节中的说明，使用 GDK CLI 发布组件。GDK CLI 将构建构件上传到 S3 存储桶，更新配方中的构件 URI，并根据配方创建组件。您可以在 [GDK CLI 配置文件](gdk-cli-configuration-file.md)中指定要使用的 S3 存储桶和区域。

<a name="gdk-cli-s3-bucket-name-formation"></a>如果您使用的是 GDK CLI v1.1.0 或更高版本，则可以指定 `--bucket` 参数来指定供 GDK CLI 上传组件构件的 S3 存储桶。<a name="gdk-cli-s3-bucket-name-formation-format"></a>如果未指定此参数，GDK CLI 会上传到名为 `bucket-region-accountId` 的 S3 存储桶，其中 *bucket* 和 *region* 是您在 `gdk-config.json` 中指定的值，*accountId* 是您的 AWS 账户 ID。如果存储桶不存在，GDK CLI 将创建该存储桶。

**重要**  <a name="publish-component-s3-bucket-token-exchange-role-permissions"></a>
默认情况下，核心设备角色不允许访问 S3 存储桶。如果这是您首次使用此 S3 存储桶，则必须向角色添加权限，才能允许核心设备从 S3 存储桶中检索组件构件。有关更多信息，请参阅 [允许访问 S3 存储桶中的组件构件](device-service-role.md#device-service-role-access-s3-bucket)。

**发布 Greengrass 组件（GDK CLI）**

1. 在命令提示符或终端中打开组件文件夹。

1. 如果没有 Greengrass 组件，请先构建。[component build](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-build) 命令在组件文件夹的 `greengrass-build` 文件夹中生成配方和构件。运行以下命令。

   ```
   gdk component build
   ```

1. 将该组件发布到 AWS 云。[组件发布](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-publish)命令将组件的构件上传到 Amazon S3，并使用每个构件的 URI 更新组件的配方。然后，它会在 AWS IoT Greengrass 服务中创建组件。
**注意**  <a name="publish-component-s3-bucket-artifact-digest-warning"></a>
AWS IoT Greengrass 在创建组件时计算每个构件的摘要。这意味着在创建组件后，无法修改 S3 存储桶中的构件文件。如果这样做，则包含此组件的部署会由于文件摘要不匹配而失败。如果修改构件文件，则必须创建新版本组件。

   如果您在 GDK CLI 配置文件中指定组件版本的 `NEXT_PATCH`，GDK CLI 会使用 AWS IoT Greengrass 服务中尚不存在的下一个补丁版本。

   运行以下命令。

   ```
   gdk component publish
   ```

   输出会显示 GDK CLI 创建的组件版本。

   发布组件后，可以将组件部署到核心设备。有关更多信息，请参阅 [将 AWS IoT Greengrass 组件部署到设备](manage-deployments.md)。

## 发布组件（Shell 命令）
<a name="publish-component-shell-commands"></a>

按照以下步骤使用 Shell 命令和 AWS Command Line Interface（AWS CLI）发布组件。发布组件时，您将执行以下操作：

1. 将组件构件发布到 S3 存储桶。

1. 将每个构件的 Amazon S3 URI 添加到组件配方。

1. 根据组件配方在 AWS IoT Greengrass 中创建组件版本。

**注意**  <a name="component-version-uniqueness-note"></a>
<a name="component-version-uniqueness-para"></a>您上传的每个组件版本都必须是唯一的。请务必上传正确的组件版本，因为上传后将无法对其进行编辑。

您可以按照以下步骤从开发计算机或 Greengrass 核心设备发布组件。

**发布组件（Shell 命令）**

1. 如果组件使用 AWS IoT Greengrass 服务中存在的版本，则必须更改该组件的版本。在文本编辑器中打开配方，增加版本并保存文件。选择反映您对组件所做更改的新版本。
**注意**  <a name="semver-note"></a>
<a name="semver-para"></a>AWS IoT Greengrass 使用组件的语义版本。语义版本遵循 *major*.*minor*.*patch* 编号系统。例如，版本 `1.0.0` 表示组件的第一个主要版本。有关更多信息，请参阅[语义版本规范](https://semver.org/)。

1. 如果组件有构件，请执行以下操作：

   1. 将组件构件发布到 AWS 账户 中的 S3 存储桶。
**提示**  <a name="artifact-path-tip"></a>
我们建议您在 S3 存储桶中构件的路径中包含组件名称和版本。此命名方案可以帮助您维护先前版本的组件所使用的构件，因此可以继续支持先前的组件版本。

      运行以下命令，将构件文件发布到 S3 存储桶。将 amzn-s3-demo-bucket 替换为存储的名称，然后将 *artifacts/com.example.HelloWorld/1.0.0/artifact.py* 替换为构件文件的路径。

      ```
      aws s3 cp artifacts/com.example.HelloWorld/1.0.0/artifact.py s3://amzn-s3-demo-bucket/artifacts/com.example.HelloWorld/1.0.0/artifact.py
      ```
**重要**  <a name="publish-component-s3-bucket-token-exchange-role-permissions"></a>
默认情况下，核心设备角色不允许访问 S3 存储桶。如果这是您首次使用此 S3 存储桶，则必须向角色添加权限，才能允许核心设备从 S3 存储桶中检索组件构件。有关更多信息，请参阅 [允许访问 S3 存储桶中的组件构件](device-service-role.md#device-service-role-access-s3-bucket)。

   1. 如果组件配方中不存在名为 `Artifacts` 的列表，请添加。每个清单中都会显示 `Artifacts` 列表，其中定义了组件在其支持的每个平台上的要求（或该组件对所有平台的默认要求）。

   1. 将每个构件添加到构件列表中，或更新现有构件的 URI。Amazon S3 URI 由存储桶名称和存储桶中构件对象的路径组成。构件的 Amazon S3 URI，应类似于以下示例。

      ```
      s3://amzn-s3-demo-bucket/artifacts/com.example.HelloWorld/1.0.0/artifact.py
      ```

   完成这些步骤后，您的配方应具有一个如下所示的 `Artifacts` 列表。

------
#### [ JSON ]

   ```
   {
     ...
     "Manifests": [
       {
         "Lifecycle": {
           ...
         },
         "Artifacts": [
           {
             "URI": "s3://amzn-s3-demo-bucket/artifacts/MyGreengrassComponent/1.0.0/artifact.py",
             "Unarchive": "NONE"
           }
         ]
       }
     ]
   }
   ```

**注意**  
您可以为 ZIP 构件添加 `"Unarchive": "ZIP"` 选项，以将 AWS IoT Greengrass Core 软件配置为在组件部署时解压缩构件。

------
#### [ YAML ]

   ```
   ...
   Manifests:
     - Lifecycle:
         ...
       Artifacts:
         - URI: s3://amzn-s3-demo-bucket/artifacts/MyGreengrassComponent/1.0.0/artifact.py
           Unarchive: NONE
   ```

**注意**  
您可以使用 `Unarchive: ZIP` 选项将 AWS IoT Greengrass Core 软件配置为在组件部署时解压缩 ZIP 构件。有关如何在组件中使用 ZIP 构件的更多信息，请参阅 [artifacts:decompressedPath 配方变量](component-recipe-reference.md#component-recipe-artifacts-decompressed-path)。

------

   有关配方的更多信息，请参阅[AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)。

1. 使用 AWS IoT Greengrass 控制台从配方文件创建组件。

   运行以下命令，从配方文件创建组件。此命令创建组件，并将其作为私有 AWS IoT Greengrass 组件发布到您的 AWS 账户 中。将 *path/to/recipeFile* 替换为配方文件的路径。

   ```
   aws greengrassv2 create-component-version --inline-recipe fileb://path/to/recipeFile
   ```

   复制响应中的 `arn`，以便在下一步中检查组件的状态。
**注意**  <a name="publish-component-s3-bucket-artifact-digest-warning"></a>
AWS IoT Greengrass 在创建组件时计算每个构件的摘要。这意味着在创建组件后，无法修改 S3 存储桶中的构件文件。如果这样做，则包含此组件的部署会由于文件摘要不匹配而失败。如果修改构件文件，则必须创建新版本组件。

1. AWS IoT Greengrass 服务中的每个组件都有一个状态。运行以下命令，确认您在此过程中发布的组件版本的状态。将 *com.example.HelloWorld* 和 *1.0.0* 替换为要查询的组件版本。将 `arn` 替换为上一步中的 ARN。

   ```
   aws greengrassv2 describe-component --arn "arn:aws:greengrass:region:account-id:components:com.example.HelloWorld:versions:1.0.0"
   ```

   此操作将返回一个包含组件元数据的响应。元数据中含有一个包含组件状态和任何错误（如果适用）的 `status` 对象。

   组件状态为 `DEPLOYABLE` 时，可以将组件部署到设备。有关更多信息，请参阅 [将 AWS IoT Greengrass 组件部署到设备](manage-deployments.md)。

# 与 AWS 服务交互
<a name="interact-with-aws-services"></a>

Greengrass 核心设备使用 X.509 证书，通过 TLS 双向身份验证协议连接到 AWS IoT Core。这些证书允许设备在没有 AWS 凭证的情况下与 AWS IoT 交互。凭证通常包含访问密钥 ID 和秘密访问密钥。其他 AWS 服务需要有 AWS 凭证（而不是 X.509 证书），才能在服务端点调用 API 操作。AWS IoT Core 拥有凭证提供程序，允许设备使用其 X.509 证书对 AWS 请求进行身份验证。AWS IoT 凭证提供程序使用 X.509 证书对设备进行身份验证，并且以有限权限临时安全令牌的形式签发 AWS 凭证。设备可以使用此令牌对任何 AWS 请求进行签名和身份验证。这样就无需在 Greengrass 核心设备上存储 AWS 凭证。有关更多信息，请参阅《AWS IoT Core 开发人员指南》**中的[授权直接调用 AWS 服务](https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html)。

为从 AWS IoT 获取凭证，Greengrass 核心设备使用指向 IAM 角色的 AWS IoT 角色别名。此 IAM 角色称为令牌交换角色**。在安装 AWS IoT Greengrass Core 软件时，您可以创建角色别名和令牌交换角色。要指定核心设备使用的角色别名，请配置 [Greengrass Nucleus](greengrass-nucleus-component.md) 的 `iotRoleAlias` 参数。

AWS IoT 凭证提供程序代表您担任令牌交换角色，为核心设备提供 AWS 凭证。您可以将合适的 IAM 策略附加到此角色，以允许核心设备访问 AWS 资源，例如 S3 存储桶中的组件构件。有关如何配置令牌交换角色的更多信息，请参阅[授权核心设备与 AWS 服务交互](device-service-role.md)。

Greengrass 核心设备将 AWS 凭证存储在内存中。默认情况下，凭证会在 1 小时后过期。如果 AWS IoT Greengrass Core 软件重新启动，则必须重新获取凭证。您可以使用 [UpdateRoleAlias](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateRoleAlias.html) 操作来配置凭证的有效期限。

AWS IoT Greengrass 提供一个公有组件，即令牌交换服务组件。您可以将该组件定义为自定义组件中的依赖关系，以与 AWS 服务交互。令牌交换服务为组件提供一个环境变量 `AWS_CONTAINER_CREDENTIALS_FULL_URI`。该变量为提供 AWS 凭证的本地服务器定义 URI。在您创建 AWS SDK 客户端时，该客户端会检查此环境变量并连接到本地服务器，以检索 AWS 凭证并使用这些凭证签署 API 请求。这样，您就可以使用 AWS SDK 和其他工具来调用组件中的 AWS 服务。有关更多信息，请参阅 [令牌交换服务](token-exchange-service-component.md)。

**重要**  <a name="token-exchange-service-aws-sdk-requirement"></a>
从 2016 年 7 月 13 日起，AWS SDK 支持以这种方式获取 AWS 凭证。您的组件必须使用在该日期或之后创建的 AWS SDK 版本。有关更多信息，请参阅《Amazon Elastic Container Service 开发人员指南》中的[使用支持的 AWS SDK](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html#task-iam-roles-minimum-sdk)。**

要在自定义组件中获取 AWS 凭证，请将 `aws.greengrass.TokenExchangeService` 定义为组件配方中的依赖关系。以下示例配方定义了一个组件，该组件用于安装 [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) 并运行 Python 脚本，该脚本使用来自令牌交换服务的 AWS 凭证列出 Amazon S3 存储桶。

**注意**  
要运行此示例组件，您的设备必须具有 `s3:ListAllMyBuckets` 权限。有关更多信息，请参阅 [授权核心设备与 AWS 服务交互](device-service-role.md)。

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.ListS3Buckets",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "A component that uses the token exchange service to list S3 buckets.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": "^2.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "pip3 install --user boto3",
        "Run": "python3 -u {artifacts:path}/list_s3_buckets.py"
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "install": "pip3 install --user boto3",
        "Run": "py -3 -u {artifacts:path}/list_s3_buckets.py"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.ListS3Buckets
ComponentVersion: '1.0.0'
ComponentDescription: A component that uses the token exchange service to list S3 buckets.
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.TokenExchangeService:
    VersionRequirement: '^2.0.0'
    DependencyType: HARD
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install:
        pip3 install --user boto3
      Run: |-
        python3 -u {artifacts:path}/list_s3_buckets.py
  - Platform:
      os: windows
    Lifecycle:
      install:
        pip3 install --user boto3
      Run: |-
        py -3 -u {artifacts:path}/list_s3_buckets.py
```

------

此示例组件运行以下 Python 脚本 `list_s3_buckets.py`，其中列出了 Amazon S3 存储桶。

```
import boto3
import os

try:
    print("Creating boto3 S3 client...")
    s3 = boto3.client('s3')
    print("Successfully created boto3 S3 client")
except Exception as e:
    print("Failed to create boto3 s3 client. Error: " + str(e))
    exit(1)

try:
    print("Listing S3 buckets...")
    response = s3.list_buckets()
    for bucket in response['Buckets']:
        print(f'\t{bucket["Name"]}')
    print("Successfully listed S3 buckets")
except Exception as e:
    print("Failed to list S3 buckets. Error: " + str(e))
    exit(1)
```

# 运行 Docker 容器
<a name="run-docker-container"></a>

您可以将 AWS IoT Greengrass 组件配置为使用存储在以下位置的映像运行 [Docker](https://www.docker.com/) 容器：
+ Amazon Elastic Container Registry（Amazon ECR）中的公共和私有映像存储库
+ 公共 Docker Hub 存储库
+ 公共 Docker 可信注册表
+ S3 存储桶

在您的自定义组件中，将 Docker 映像 URI 作为构件包括在内，以检索映像并在核心设备上运行。对于 Amazon ECR 和 Docker Hub 映像，您可以使用 [Docker 应用程序管理器](docker-application-manager-component.md)组件下载映像并管理私有 Amazon ECR 存储库的凭证。

**Topics**
+ [要求](#run-docker-container-requirements)
+ [通过 Amazon ECR 或 Docker Hub 中的公共映像运行 Docker 容器](#run-docker-container-public-ecr-dockerhub)
+ [通过 Amazon ECR 中的私有映像运行 Docker 容器](#run-docker-container-private-ecr)
+ [通过 Amazon S3 中的映像运行 Docker 容器](#run-docker-container-s3)
+ [在 Docker 容器组件中使用进程间通信](#docker-container-ipc)
+ [在 Docker 容器组件中使用 AWS 凭证 (Linux)](#docker-container-token-exchange-service)
+ [在 Docker 容器组件中使用流管理器（Linux）](#docker-container-stream-manager)

## 要求
<a name="run-docker-container-requirements"></a>

要在组件中运行 Docker 容器，您需要：
+ Greengrass 核心设备。如果没有，请参阅[教程：AWS IoT Greengrass V2 入门](getting-started.md)。
+ <a name="docker-engine-requirement"></a>Greengrass 核心设备上安装的 [Docker Engine](https://docs.docker.com/engine/) 1.9.1 或更高版本。版本 20.10 是经验证可与 AWS IoT Greengrass 核心软件配合使用的最新版本。在部署运行 Docker 容器的组件之前，必须直接在核心设备上安装 Docker。
**提示**  
您还可以将核心设备配置为在组件安装时安装 Docker Engine。例如，以下安装脚本可在加载 Docker 映像之前安装 Docker Engine。此安装脚本适用于基于 Debian 的 Linux 发行版，例如 Ubuntu。如果您使用此命令将组件配置为安装 Docker Engine，则可能需要在生命周期脚本中将 `RequiresPrivilege` 设置为 `true` 才能运行安装和 `docker` 命令。有关更多信息，请参阅 [AWS IoT Greengrass 组件配方参考](component-recipe-reference.md)。  

  ```
  apt-get install docker-ce docker-ce-cli containerd.io && docker load -i {artifacts:path}/hello-world.tar
  ```
+ <a name="docker-user-permissions-requirement"></a>运行 Docker 容器组件的系统用户必须具有根或管理员权限，或者您必须将 Docker 配置为以非根用户或非管理员用户身份运行。
  + 在 Linux 设备上，您可向 `docker` 组中添加一个用户以调用 `docker` 命令，无需 `sudo`。
  + 在 Windows 设备上，您可将用户添加到 `docker-users` 组中以调用 `docker` 命令，无需管理员权限。

------
#### [ Linux or Unix ]

  要添加 `ggc_user` 或您用于运行 Docker 容器组件的非根用户至 `docker` 组中，请运行以下命令：

  ```
  sudo usermod -aG docker ggc_user
  ```

  有关更多信息，请参阅[以非根用户身份管理 Docker](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)。

------
#### [ Windows Command Prompt (CMD) ]

  要添加 `ggc_user` 或您用于运行 Docker 容器组件的非根用户至 `docker-users` 组中，请以管理员身份运行以下命令：

  ```
  net localgroup docker-users ggc_user /add
  ```

------
#### [ Windows PowerShell ]

  要添加 `ggc_user` 或您用于运行 Docker 容器组件的非根用户至 `docker-users` 组中，请以管理员身份运行以下命令：

  ```
  Add-LocalGroupMember -Group docker-users -Member ggc_user
  ```

------
+ [作为卷挂载](https://docs.docker.com/storage/volumes/)在 Docker 容器中的 Docker 容器组件访问的文件。
+ <a name="docker-proxy-requirement"></a>如果您[将 AWS IoT Greengrass Core 软件配置为使用网络代理](configure-greengrass-core-v2.md#configure-alpn-network-proxy)，则必须[将 Docker 配置为使用相同的代理服务器](https://docs.docker.com/network/proxy/)。

除这些要求外，您还必须满足以下要求（如果其适用于您的环境）：
+ 要使用 [Docker Compose](https://docs.docker.com/compose/) 创建和启动 Docker 容器，请在 Greengrass 核心设备上安装 Docker Compose，然后将您的 Docker Compose 文件上传到 S3 桶。您必须将 Compose 文件存储在 AWS 账户 与 AWS 区域 组件相同的 S3 存储桶中。有关在自定义组件中使用 `docker-compose up` 命令的示例，请参阅[通过 Amazon ECR 或 Docker Hub 中的公共映像运行 Docker 容器](#run-docker-container-public-ecr-dockerhub)。
+ 如果您在网络代理 AWS IoT Greengrass 后面运行，请将 Docker 守护程序配置为使用[代理服务器](https://docs.docker.com/network/proxy/)。
+ 如果您的 Docker 映像存储在 Amazon ECR 或 Docker Hub 中，请将 [Docker 组件管理器](docker-application-manager-component.md)组件作为依赖关系包含在 Docker 容器组件中。在部署组件之前，必须在核心设备上启动 Docker 进程守护程序。

  此外，还要将图像 URIs 作为组件工件包括在内。图片 URIs 必须采用以下示例所示的格式`docker:registry/image[:tag|@digest]`：<a name="docker-image-artifact-uri"></a>
  + Amazon ECR 私有映像：`docker:account-id.dkr.ecr.region.amazonaws.com/repository/image[:tag|@digest]`
  + Amazon ECR 公共映像：`docker:public.ecr.aws/repository/image[:tag|@digest]`
  + Docker Hub 公共映像：`docker:name[:tag|@digest]`

  有关通过存储在公共存储库中的映像运行 Docker 容器的更多信息，请参阅[通过 Amazon ECR 或 Docker Hub 中的公共映像运行 Docker 容器](#run-docker-container-public-ecr-dockerhub)。
+ 如果您的 Docker 映像存储在 Amazon ECR 私有存储库中，则必须将令牌交换服务组件作为依赖关系包含在 Docker 容器组件中。此外，[Greengrass 设备角色](device-service-role.md)必须允许执行 `ecr:GetAuthorizationToken`、`ecr:BatchGetImage` 和 `ecr:GetDownloadUrlForLayer` 操作，如以下示例 IAM 策略中所示。

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": [
          "ecr:GetAuthorizationToken",
          "ecr:BatchGetImage",
          "ecr:GetDownloadUrlForLayer"
        ],
        "Resource": [
          "*"
        ],
        "Effect": "Allow"
      }
    ]
  }
  ```

------

  有关通过存储在 Amazon ECR 私有存储库中的映像运行 Docker 容器的信息，请参阅[通过 Amazon ECR 中的私有映像运行 Docker 容器](#run-docker-container-private-ecr)。
+ 要使用存储在 Amazon ECR 私有存储库中的 Docker 映像，私有存储库必须与核心设备位于同一 AWS 区域 位置。
+ 如果您的 Docker 映像或 Compose 文件存储在 S3 桶中，则 [Greengrass 设备角色](device-service-role.md)必须允许 `s3:GetObject` 权限，以便让核心设备将映像下载为组件构件，如以下示例 IAM 策略所示。

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": [
          "s3:GetObject"
        ],
        "Resource": [
          "*"
        ],
        "Effect": "Allow"
      }
    ]
  }
  ```

------

  有关通过存储在 Amazon S3 中的映像运行 Docker 容器的信息，请参阅[通过 Amazon S3 中的映像运行 Docker 容器](#run-docker-container-s3)。
+ <a name="docker-greengrass-features-requirements"></a>要在 Docker 容器组件中使用进程间通信（IPC）、 AWS 凭证或流管理器，必须在运行 Docker 容器时指定其他选项。有关更多信息，请参阅下列内容：<a name="docker-greengrass-features-requirements-links"></a>
  + [在 Docker 容器组件中使用进程间通信](#docker-container-ipc)
  + [在 Docker 容器组件中使用 AWS 凭证 (Linux)](#docker-container-token-exchange-service)
  + [在 Docker 容器组件中使用流管理器（Linux）](#docker-container-stream-manager)

## 通过 Amazon ECR 或 Docker Hub 中的公共映像运行 Docker 容器
<a name="run-docker-container-public-ecr-dockerhub"></a>

本节介绍如何创建自定义组件，使其使用 Docker Compose 通过存储在 Amazon ECR 和 Docker Hub 的 Docker 映像中运行 Docker 容器。

**使用 Docker Compose 运行 Docker 容器**

1. 创建 Docker Compose 文件并将其上传到 Amazon S3 桶。确保 [Greengrass 设备角色](device-service-role.md)允许 `s3:GetObject` 权限，使设备能够访问 Compose 文件。以下示例中显示的示例撰写文件包括来自亚马逊 ECR 的亚马逊 CloudWatch 代理镜像和来自 Docker Hub 的 MySQL 镜像。

   ```
   version: "3"
   services:
     cloudwatchagent:
       image: "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest"
     mysql:
       image: "mysql:8.0"
   ```

1. [在 AWS IoT Greengrass 核心设备上创建自定义组件](create-components.md)。以下示例中的配方具有以下属性：
   + 作为依赖关系的 Docker 应用程序管理器组件。此组件允许 AWS IoT Greengrass 从公共 Amazon ECR 和 Docker Hub 存储库下载映像。
   + 指定公共 Amazon ECR 资源库中 Docker 映像的组件构件。
   + 指定公共 Docker Hub 资源库中 Docker 映像的组件构件。
   + 指定 Docker Compose 文件的组件构件，该文件包含要运行的 Docker 映像的容器。
   + 使用 [docker-compose up](https://docs.docker.com/compose/reference/up/) 通过指定的映像创建和启动容器的生命周期运行脚本。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "com.example.MyDockerComposeComponent",
     "ComponentVersion": "1.0.0",
     "ComponentDescription": "A component that uses Docker Compose to run images from public Amazon ECR and Docker Hub.",
     "ComponentPublisher": "Amazon",
     "ComponentDependencies": {
       "aws.greengrass.DockerApplicationManager": {
         "VersionRequirement": "~2.0.0"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "all"
         },
         "Lifecycle": {
           "Run": "docker-compose -f {artifacts:path}/docker-compose.yaml up"
         },
         "Artifacts": [
           {
             "URI": "docker:public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest"
           },
           {
             "URI": "docker:mysql:8.0"
           },
           {
             "URI": "s3://amzn-s3-demo-bucket/folder/docker-compose.yaml"
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: '2020-01-25'
   ComponentName: com.example.MyDockerComposeComponent
   ComponentVersion: '1.0.0'
   ComponentDescription: 'A component that uses Docker Compose to run images from public Amazon ECR and Docker Hub.'
   ComponentPublisher: Amazon
   ComponentDependencies:
     aws.greengrass.DockerApplicationManager:
       VersionRequirement: ~2.0.0
   Manifests:
     - Platform:
         os: all
       Lifecycle:
           Run: docker-compose -f {artifacts:path}/docker-compose.yaml up
       Artifacts:
         - URI: "docker:public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest"
         - URI: "docker:mysql:8.0"
         - URI: "s3://amzn-s3-demo-bucket/folder/docker-compose.yaml"
   ```

------
**注意**  
<a name="docker-greengrass-features-requirements"></a>要在 Docker 容器组件中使用进程间通信（IPC）、 AWS 凭证或流管理器，必须在运行 Docker 容器时指定其他选项。有关更多信息，请参阅下列内容：  
[在 Docker 容器组件中使用进程间通信](#docker-container-ipc)
[在 Docker 容器组件中使用 AWS 凭证 (Linux)](#docker-container-token-exchange-service)
[在 Docker 容器组件中使用流管理器（Linux）](#docker-container-stream-manager)

1. [测试组件](test-components.md)，以验证其是否按预期运行。
**重要**  
在部署组件之前，必须安装并启动 Docker 进程守护程序。

   在本地部署组件后，您可以运行 [docker container ls](https://docs.docker.com/engine/reference/commandline/container_ls/) 命令来验证您的容器是否运行。

   ```
   docker container ls
   ```

1. 组件准备就绪后，将该组件上传 AWS IoT Greengrass 到以部署到其他核心设备。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md)。

## 通过 Amazon ECR 中的私有映像运行 Docker 容器
<a name="run-docker-container-private-ecr"></a>

本节介绍如何创建自定义组件，使其通过存储在 Amazon ECR 私有存储库中的 Docker 映像运行 Docker 容器。

**运行 Docker 容器**

1. [在 AWS IoT Greengrass 核心设备上创建自定义组件](create-components.md)。使用以下配方示例，它具有以下属性：
   + 作为依赖关系的 Docker 应用程序管理器组件。此组件允许 AWS IoT Greengrass 管理从私有存储库下载映像的凭证。
   + 作为依赖关系的令牌交换服务组件。此组件允许检索 AWS 凭证 AWS IoT Greengrass 以与 Amazon ECR 进行交互。
   + 指定私有 Amazon ECR 存储库中 Docker 映像的组件构件。
   + 使用 [docker run](https://docs.docker.com/engine/reference/commandline/run/) 从映像创建和启动容器的生命周期运行脚本。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "com.example.MyPrivateDockerComponent",
     "ComponentVersion": "1.0.0",
     "ComponentDescription": "A component that runs a Docker container from a private Amazon ECR image.",
     "ComponentPublisher": "Amazon",
     "ComponentDependencies": {
       "aws.greengrass.DockerApplicationManager": {
         "VersionRequirement": "~2.0.0"
       },
       "aws.greengrass.TokenExchangeService": {
         "VersionRequirement": "~2.0.0"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "all"
         },
         "Lifecycle": {
           "Run": "docker run account-id.dkr.ecr.region.amazonaws.com/repository[:tag|@digest]"
         },
         "Artifacts": [
           {
             "URI": "docker:account-id.dkr.ecr.region.amazonaws.com/repository[:tag|@digest]"
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: '2020-01-25'
   ComponentName: com.example.MyPrivateDockerComponent
   ComponentVersion: '1.0.0'
   ComponentDescription: 'A component that runs a Docker container from a private Amazon ECR image.'
   ComponentPublisher: Amazon
   ComponentDependencies:
     aws.greengrass.DockerApplicationManager:
       VersionRequirement: ~2.0.0
     aws.greengrass.TokenExchangeService:
       VersionRequirement: ~2.0.0
   Manifests:
     - Platform:
         os: all
       Lifecycle:
           Run: docker run account-id.dkr.ecr.region.amazonaws.com/repository[:tag|@digest]
       Artifacts:
         - URI: "docker:account-id.dkr.ecr.region.amazonaws.com/repository[:tag|@digest]"
   ```

------
**注意**  
<a name="docker-greengrass-features-requirements"></a>要在 Docker 容器组件中使用进程间通信（IPC）、 AWS 凭证或流管理器，必须在运行 Docker 容器时指定其他选项。有关更多信息，请参阅下列内容：  
[在 Docker 容器组件中使用进程间通信](#docker-container-ipc)
[在 Docker 容器组件中使用 AWS 凭证 (Linux)](#docker-container-token-exchange-service)
[在 Docker 容器组件中使用流管理器（Linux）](#docker-container-stream-manager)

1. [测试组件](test-components.md)，以验证其是否按预期运行。
**重要**  
在部署组件之前，必须安装并启动 Docker 进程守护程序。

   在本地部署组件后，您可以运行 [docker container ls](https://docs.docker.com/engine/reference/commandline/container_ls/) 命令来验证您的容器是否运行。

   ```
   docker container ls
   ```

1. 将组件上传到 AWS IoT Greengrass 以部署到其他核心设备。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md)。

## 通过 Amazon S3 中的映像运行 Docker 容器
<a name="run-docker-container-s3"></a>

本节介绍如何通过存储在 Amazon S3 中的 Docker 映像在组件中运行 Docker 容器。

**通过 Amazon S3 中的映像在组件中运行 Docker 容器**

1. 运行 [docker save](https://docs.docker.com/engine/reference/commandline/save/) 命令以创建 Docker 容器的备份。您需要将此备份作为组件构件提供，以便在 AWS IoT Greengrass上运行容器。*hello-world*替换为图像的名称，然后*hello-world.tar*替换为要创建的存档文件的名称。

   ```
   docker save hello-world > artifacts/com.example.MyDockerComponent/1.0.0/hello-world.tar
   ```

1. [在 AWS IoT Greengrass 核心设备上创建自定义组件](create-components.md)。使用以下配方示例，它具有以下属性：
   + 使用 [docker load](https://docs.docker.com/engine/reference/commandline/load/) 从存档中加载 Docker 映像的生命周期安装脚本。
   + 使用 [docker run](https://docs.docker.com/engine/reference/commandline/run/) 从映像创建和启动容器的生命周期运行脚本。`--rm` 选项将在容器退出时对其进行清理。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "com.example.MyS3DockerComponent",
     "ComponentVersion": "1.0.0",
     "ComponentDescription": "A component that runs a Docker container from an image in an S3 bucket.",
     "ComponentPublisher": "Amazon",
     "Manifests": [
       {
         "Platform": {
           "os": "linux"
         },
         "Lifecycle": {
           "install": {
             "Script": "docker load -i {artifacts:path}/hello-world.tar"
           },
           "Run": {
             "Script": "docker run --rm hello-world"
           }
         }
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: '2020-01-25'
   ComponentName: com.example.MyS3DockerComponent
   ComponentVersion: '1.0.0'
   ComponentDescription: 'A component that runs a Docker container from an image in an S3 bucket.'
   ComponentPublisher: Amazon
   Manifests:
     - Platform:
         os: linux
       Lifecycle:
         install:
           Script: docker load -i {artifacts:path}/hello-world.tar
         Run:
           Script: docker run --rm hello-world
   ```

------
**注意**  
<a name="docker-greengrass-features-requirements"></a>要在 Docker 容器组件中使用进程间通信（IPC）、 AWS 凭证或流管理器，必须在运行 Docker 容器时指定其他选项。有关更多信息，请参阅下列内容：  
[在 Docker 容器组件中使用进程间通信](#docker-container-ipc)
[在 Docker 容器组件中使用 AWS 凭证 (Linux)](#docker-container-token-exchange-service)
[在 Docker 容器组件中使用流管理器（Linux）](#docker-container-stream-manager)

1. [测试组件](test-components.md)，以验证其是否按预期运行。

   在本地部署组件后，您可以运行 [docker container ls](https://docs.docker.com/engine/reference/commandline/container_ls/) 命令来验证您的容器是否运行。

   ```
   docker container ls
   ```

1. 组件准备就绪后，将 Docker 映像存档上传到 S3 桶，然后将其 URI 添加到组件配方中。然后，您可以将组件上传到 AWS IoT Greengrass 以部署到其他核心设备。有关更多信息，请参阅 [发布组件以部署到您的核心设备](publish-components.md)。

   完成后，组件配方应类似于以下示例。

------
#### [ JSON ]

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "com.example.MyS3DockerComponent",
     "ComponentVersion": "1.0.0",
     "ComponentDescription": "A component that runs a Docker container from an image in an S3 bucket.",
     "ComponentPublisher": "Amazon",
     "Manifests": [
       {
         "Platform": {
           "os": "linux"
         },
         "Lifecycle": {
           "install": {
             "Script": "docker load -i {artifacts:path}/hello-world.tar"
           },
           "Run": {
             "Script": "docker run --rm hello-world"
           }
         },
         "Artifacts": [
           {
             "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.MyDockerComponent/1.0.0/hello-world.tar"
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   ```
   ---
   RecipeFormatVersion: '2020-01-25'
   ComponentName: com.example.MyS3DockerComponent
   ComponentVersion: '1.0.0'
   ComponentDescription: 'A component that runs a Docker container from an image in an S3 bucket.'
   ComponentPublisher: Amazon
   Manifests:
     - Platform:
         os: linux
       Lifecycle:
         install:
           Script: docker load -i {artifacts:path}/hello-world.tar
         Run:
           Script: docker run --rm hello-world
       Artifacts:
         - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.MyDockerComponent/1.0.0/hello-world.tar
   ```

------

## 在 Docker 容器组件中使用进程间通信
<a name="docker-container-ipc"></a>

您可以使用中的 Greengrass 进程间通信 (IPC) 库与 Greengrass 核、 AWS IoT Device SDK 其他 Greengrass 组件以及进行通信。 AWS IoT Core有关更多信息，请参阅 [使用 AWS IoT Device SDK 与 Greengrass 原子核、其他组件进行通信，以及 AWS IoT Core与 Greengrass 核、其他组件进行通信 AWS IoT Core](interprocess-communication.md)。

要在 Docker 容器组件中使用 IPC，必须使用以下参数运行 Docker 容器：
+ 将 IPC 套接字挂载在容器中。Greengrass Nucleus在 `AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT` 环境变量中提供 IPC 套接字文件路径。
+ 将 `SVCUID` 和 `AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT` 环境变量设置为 Greengrass Nucleus为组件提供的值。您的组件使用这些环境变量来验证与 Greengrass Nucleus的连接。

**Example 示例配方：将 MQTT 消息发布到 AWS IoT Core (Python)**  
以下配方定义了一个将 MQTT 消息发布到的 Docker 容器组件示例。 AWS IoT Core该配方具有以下属性：  
+ 一种授权策略 (`accessControl`)，允许组件向其发布 AWS IoT Core 有关所有主题的 MQTT 消息。有关更多信息，请参阅 [授权组件执行 IPC 操作](interprocess-communication.md#ipc-authorization-policies) 和 [AWS IoT Core MQTT IPC 授权](ipc-iot-core-mqtt.md#ipc-iot-core-mqtt-authorization)。
+ 将 Docker 映像指定为 Amazon S3 中的 TAR 存档的组件构件。
+ 从 TAR 存档中加载 Docker 映像的生命周期安装脚本。
+ 通过映像运行 Docker 容器的生命周期运行脚本。[Docker run](https://docs.docker.com/engine/reference/run/) 命令具有以下参数：
  + `-v` 参数将 Greengrass IPC 套接字挂载在容器中。
  + 前两个 `-e` 参数在 Docker 容器中设置所需的环境变量。
  + 其他 `-e` 参数设置本示例使用的环境变量。
  + `--rm` 参数将在容器退出时对其进行清理。

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.python.docker.PublishToIoTCore",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Uses interprocess communication to publish an MQTT message to IoT Core.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "topic": "test/topic/java",
      "message": "Hello, World!",
      "qos": "1",
      "accessControl": {
        "aws.greengrass.ipc.mqttproxy": {
          "com.example.python.docker.PublishToIoTCore:pubsub:1": {
            "policyDescription": "Allows access to publish to IoT Core on all topics.",
            "operations": [
              "aws.greengrass#PublishToIoTCore"
            ],
            "resources": [
              "*"
            ]
          }
        }
      }
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "all"
      },
      "Lifecycle": {
        "install": "docker load -i {artifacts:path}/publish-to-iot-core.tar",
        "Run": "docker run -v $AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT:$AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT -e SVCUID -e AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT -e MQTT_TOPIC=\"{configuration:/topic}\" -e MQTT_MESSAGE=\"{configuration:/message}\" -e MQTT_QOS=\"{configuration:/qos}\" --rm publish-to-iot-core"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.PublishToIoTCore/1.0.0/publish-to-iot-core.tar"
        }
      ]
    }
  ]
}
```

```
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.python.docker.PublishToIoTCore
ComponentVersion: 1.0.0
ComponentDescription: Uses interprocess communication to publish an MQTT message to IoT Core.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    topic: 'test/topic/java'
    message: 'Hello, World!'
    qos: '1'
    accessControl:
      aws.greengrass.ipc.mqttproxy:
        'com.example.python.docker.PublishToIoTCore:pubsub:1':
          policyDescription: Allows access to publish to IoT Core on all topics.
          operations:
            - 'aws.greengrass#PublishToIoTCore'
          resources:
            - '*'
Manifests:
  - Platform:
      os: all
    Lifecycle:
      install: 'docker load -i {artifacts:path}/publish-to-iot-core.tar'
      Run: |
        docker run \
          -v $AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT:$AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT \
          -e SVCUID \
          -e AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT \
          -e MQTT_TOPIC="{configuration:/topic}" \
          -e MQTT_MESSAGE="{configuration:/message}" \
          -e MQTT_QOS="{configuration:/qos}" \
          --rm publish-to-iot-core
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.PublishToIoTCore/1.0.0/publish-to-iot-core.tar
```

## 在 Docker 容器组件中使用 AWS 凭证 (Linux)
<a name="docker-container-token-exchange-service"></a>

您可以使用[令牌交换服务组件](token-exchange-service-component.md)与 Greengrass 组件中的 AWS 服务进行交互。此组件使用本地容器服务器提供来自核心设备的[令牌交换角色](device-service-role.md)的 AWS 凭证。有关更多信息，请参阅 [与 AWS 服务交互](interact-with-aws-services.md)。

**注意**  
本节中的示例仅适用于 Linux 核心设备。

要在 Docker 容器组件中使用来自令牌交换服务的 AWS 凭证，必须使用以下参数运行 Docker 容器：
+ 使用 `--network=host` 参数提供对主机网络的访问权限。此选项使 Docker 容器能够连接到本地令牌交换服务以检索 AWS 凭据。此参数仅适用于 Linux 版 Docker。
**警告**  <a name="docker-network-host-security-warning"></a>
此选项允许容器访问主机上的所有本地网络接口，因此与不能访问主机网络的 Docker 容器相比，该选项的安全性较低。在开发和运行使用此选项的 Docker 容器组件时，请考虑这一点。有关更多信息，请参阅 *Docker 文档*中的[网络：主机](https://docs.docker.com/engine/reference/run/#network-host)。
+ 将`AWS_CONTAINER_CREDENTIALS_FULL_URI`和`AWS_CONTAINER_AUTHORIZATION_TOKEN`环境变量设置为 Greengrass 核为组件提供的值。 AWS SDKs 使用这些环境变量来检索 AWS 凭证。

**Example 示例配方：在 Docker 容器组件中列出 S3 桶（Python）**  
以下配方定义了一个可以列出您 AWS 账户中 S3 桶的示例 Docker 容器组件。该配方具有以下属性：  
+ 作为依赖关系的令牌交换服务组件。这种依赖关系使组件能够检索 AWS 凭证以与其他 AWS 服务进行交互。
+ 将 Docker 映像指定为 Amazon S3 中的 TAR 存档的组件构件。
+ 从 TAR 存档中加载 Docker 映像的生命周期安装脚本。
+ 通过映像运行 Docker 容器的生命周期运行脚本。[Docker run](https://docs.docker.com/engine/reference/run/) 命令具有以下参数：
  + `--network=host` 参数提供容器对主机网络的访问权限，以便容器可以连接到令牌交换服务。
  + `-e` 参数在 Docker 容器中设置所需的环境变量。
  + `--rm` 参数将在容器退出时对其进行清理。

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.python.docker.ListS3Buckets",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Uses the token exchange service to lists your S3 buckets.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": "^2.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "docker load -i {artifacts:path}/list-s3-buckets.tar",
        "Run": "docker run --network=host -e AWS_CONTAINER_AUTHORIZATION_TOKEN -e AWS_CONTAINER_CREDENTIALS_FULL_URI --rm list-s3-buckets"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.ListS3Buckets/1.0.0/list-s3-buckets.tar"
        }
      ]
    }
  ]
}
```

```
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.python.docker.ListS3Buckets
ComponentVersion: 1.0.0
ComponentDescription: Uses the token exchange service to lists your S3 buckets.
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.TokenExchangeService:
    VersionRequirement: ^2.0.0
    DependencyType: HARD
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: 'docker load -i {artifacts:path}/list-s3-buckets.tar'
      Run: |
        docker run \
          --network=host \
          -e AWS_CONTAINER_AUTHORIZATION_TOKEN \
          -e AWS_CONTAINER_CREDENTIALS_FULL_URI \
          --rm list-s3-buckets
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.ListS3Buckets/1.0.0/list-s3-buckets.tar
```

## 在 Docker 容器组件中使用流管理器（Linux）
<a name="docker-container-stream-manager"></a>

您可以使用[流管理器组件](stream-manager-component.md)来管理 Greengrass 组件中的数据流。此组件使您能够处理数据流并将大量物联网数据传输到. AWS 云 AWS IoT Greengrass 提供了用于与流管理器组件交互的流管理器 SDK。有关更多信息，请参阅 [管理 Greengrass 核心设备上的数据流](manage-data-streams.md)。

**注意**  
本节中的示例仅适用于 Linux 核心设备。

要在 Docker 容器组件中使用流管理器 SDK，必须使用以下参数运行 Docker 容器：
+ 使用 `--network=host` 参数提供对主机网络的访问权限。此选项使 Docker 容器能够通过本地 TLS 连接与流管理器组件进行交互。此参数仅适用于 Linux 版 Docker
**警告**  <a name="docker-network-host-security-warning"></a>
此选项允许容器访问主机上的所有本地网络接口，因此与不能访问主机网络的 Docker 容器相比，该选项的安全性较低。在开发和运行使用此选项的 Docker 容器组件时，请考虑这一点。有关更多信息，请参阅 *Docker 文档*中的[网络：主机](https://docs.docker.com/engine/reference/run/#network-host)。
+ 如果您将流管理器组件配置为需要身份验证（这是默认行为），请将 `AWS_CONTAINER_CREDENTIALS_FULL_URI` 环境变量设置为 Greengrass Nucleus为组件提供的值。有关更多信息，请参阅[流管理器配置](stream-manager-component.md#stream-manager-component-configuration)。
+ 如果将流管理器组件配置为使用非默认端口，请使用[进程间通信（IPC）](interprocess-communication.md)从流管理器组件配置中获取该端口。要使用 IPC，您必须使用其他选项运行 Docker 容器。有关更多信息，请参阅下列内容：
  + [在应用程序代码中连接至流管理器](use-stream-manager-in-custom-components.md#connect-to-stream-manager)
  + [在 Docker 容器组件中使用进程间通信](#docker-container-ipc)

**Example 示例配方：将文件流式传输到 Docker 容器组件中的 S3 桶（Python）**  
以下配方定义了一个用于创建文件并将其流式传输到 S3 桶的示例 Docker 容器组件。该配方具有以下属性：  
+ 作为依赖关系的流管理器组件。此依赖关系使组件能够使用流管理器 SDK 与流管理器组件进行交互。
+ 将 Docker 映像指定为 Amazon S3 中的 TAR 存档的组件构件。
+ 从 TAR 存档中加载 Docker 映像的生命周期安装脚本。
+ 通过映像运行 Docker 容器的生命周期运行脚本。[Docker run](https://docs.docker.com/engine/reference/run/) 命令具有以下参数：
  + `--network=host` 参数提供容器对主机网络的访问权限，以便容器可以连接到流管理器组件。
  + 第一个 `-e` 参数在 Docker 容器中设置所需的 `AWS_CONTAINER_AUTHORIZATION_TOKEN` 环境变量。
  + 其他 `-e` 参数设置本示例使用的环境变量。
  + `-v` 参数将组件的[工作文件夹](component-recipe-reference.md#component-recipe-work-path)挂载到容器中。此示例在工作文件夹中创建一个文件，以便使用流管理器将该文件上传到 Amazon S3。
  + `--rm` 参数将在容器退出时对其进行清理。

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.python.docker.StreamFileToS3",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Creates a text file and uses stream manager to stream the file to S3.",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.StreamManager": {
      "VersionRequirement": "^2.0.0",
      "DependencyType": "HARD"
    }
  },
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "bucketName": ""
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "install": "docker load -i {artifacts:path}/stream-file-to-s3.tar",
        "Run": "docker run --network=host -e AWS_CONTAINER_AUTHORIZATION_TOKEN -e BUCKET_NAME=\"{configuration:/bucketName}\" -e WORK_PATH=\"{work:path}\" -v {work:path}:{work:path} --rm stream-file-to-s3"
      },
      "Artifacts": [
        {
          "URI": "s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.StreamFileToS3/1.0.0/stream-file-to-s3.tar"
        }
      ]
    }
  ]
}
```

```
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.python.docker.StreamFileToS3
ComponentVersion: 1.0.0
ComponentDescription: Creates a text file and uses stream manager to stream the file to S3.
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.StreamManager:
    VersionRequirement: ^2.0.0
    DependencyType: HARD
ComponentConfiguration:
  DefaultConfiguration:
    bucketName: ''
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      install: 'docker load -i {artifacts:path}/stream-file-to-s3.tar'
      Run: |
        docker run \
          --network=host \
          -e AWS_CONTAINER_AUTHORIZATION_TOKEN \
          -e BUCKET_NAME="{configuration:/bucketName}" \
          -e WORK_PATH="{work:path}" \
          -v {work:path}:{work:path} \
          --rm stream-file-to-s3
    Artifacts:
      - URI: s3://amzn-s3-demo-bucket/artifacts/com.example.python.docker.StreamFileToS3/1.0.0/stream-file-to-s3.tar
```

# AWS IoT Greengrass 组件配方参考
<a name="component-recipe-reference"></a>

组件配方是一个定义组件详细信息、依赖关系、构件和生命周期的文件。例如，组件*生命周期*指定了安装、运行和关闭组件时要运行的命令。内 AWS IoT Greengrass 核使用您在配方中定义的生命周期来安装和运行组件。部署组件时，该 AWS IoT Greengrass 服务使用配方来识别要部署到核心设备的依赖项和工件。

在配方中，您可以为组件支持的每个平台定义唯一的依赖关系和生命周期。您可以利用这一功能将组件部署到具有不同要求的多个平台的设备上。您还可以使用它来 AWS IoT Greengrass 防止在不支持组件的设备上安装该组件。

每个配方都包含一份*清单*。每个清单都指定了一组平台要求以及平台满足这些要求的核心设备要使用的生命周期和构件。核心设备使用第一份清单，其中包含该设备满足的平台要求。指定没有任何平台要求的清单，以匹配任何核心设备。

您还可以指定清单中没有的全局生命周期。在全局生命周期中，您可以使用*选择键*来标识生命周期的子部分。然后，您可以在清单中指定这些选择键，以便在清单的生命周期之外使用全局生命周期中的这些部分。仅当清单未定义生命周期时，核心设备才会使用清单的选择键。您可以使用清单中的 `all` 选择来匹配全局生命周期的各个部分，而无需选择键。

在 AWS IoT Greengrass 核心软件选择与核心设备匹配的清单后，它会执行以下操作来确定要使用的生命周期步骤：
+ 如果所选清单定义了生命周期，则核心设备将使用该生命周期。
+ 如果所选清单未定义生命周期，则核心设备将使用全局生命周期。核心设备执行以下操作来确定要使用全局生命周期的哪些部分：
  + 如果清单定义了选择键，则核心设备将使用全局生命周期中包含清单选择键的部分。
  + 如果清单未定义选择键，则核心设备将使用全局生命周期中没有选择键的部分。此行为等同于定义 `all` 选择的清单。

**重要**  <a name="recipe-core-device-manifest-requirement"></a>
核心设备必须满足至少一个清单的平台要求才能安装该组件。如果没有清单与核心设备匹配，则 AWS IoT Greengrass 核心软件不会安装该组件，部署将失败。

您可以用 [JSON](https://en.wikipedia.org/wiki/JSON) 或 [YAML](https://en.wikipedia.org/wiki/YAML) 格式定义配方。配方示例部分包括各种格式的配方。

**Topics**
+ [配方验证](#recipe-validation)
+ [配方格式](#recipe-format)
+ [配方变量](#recipe-variables)
+ [配方示例](#recipe-examples)

## 配方验证
<a name="recipe-validation"></a>

Greengrass 在创建组件版本时会验证 JSON 或 YAML 组件配方。此配方验证会检查您的 JSON 或 YAML 组件配方中是否存在常见错误，以防止出现潜在的部署问题。验证会检查配方中是否存在常见错误（例如，缺少逗号、大括号和字段），并确保配方格式正确。

如果您收到配方验证错误消息，请检查您的配方中是否缺少逗号、大括号或字段。查看[配方格式](#recipe-format)，确认您没有遗漏任何字段。

## 配方格式
<a name="recipe-format"></a>

在为组件定义配方时，需要在配方文档中指定以下信息。同样的结构适用于 YAML 和 JSON 格式的配方。

`RecipeFormatVersion`  
配方模板版本。选择以下选项：  
+ `2020-01-25`

`ComponentName`  
此配方定义的组件名称。在每个区域中，组件名称必须是唯一的 AWS 账户 。  
**提示**  
+ 使用反向域名格式以避免公司内部的域名冲突。例如，如果您的公司拥有 `example.com`，而您开展的是一个太阳能项目，则可以将您的 Hello World 组件命名为 `com.example.solar.HelloWorld`。这有助于避免公司内部的组件名称冲突。
+ 避免在组件名称中使用 `aws.greengrass` 前缀。 AWS IoT Greengrass 将此前缀用于它提供的[公有组件](public-components.md)。如果您选择与公有组件相同的名称，则您的组件将替换该组件。然后，在部署依赖于该公共组件的组件时， AWS IoT Greengrass 提供您的组件而不是公共组件。此功能允许您覆盖公有组件的行为，但如果您不打算覆盖公有组件，它也可能会破坏其他组件。

`ComponentVersion`  
组件版本。主要值、次要值和补丁值的最大值为 999999。  
<a name="semver-para"></a>AWS IoT Greengrass 使用组件的语义版本。语义版本遵循 *major*.*minor*.*patch* 编号系统。例如，版本 `1.0.0` 表示组件的第一个主要版本。有关更多信息，请参阅[语义版本规范](https://semver.org/)。

`ComponentDescription`  
（可选）组件的描述。

`ComponentPublisher`  
组件的发布者或作者。

`ComponentConfiguration`  
（可选）定义组件配置或参数的对象。您可以定义默认配置，然后在部署组件时，可以指定要提供给组件的配置对象。组件配置支持嵌套参数和结构。该对象包含以下信息：    
`DefaultConfiguration`  
定义组件默认配置的对象。您可以定义此对象的结构。  
<a name="configuration-value-type-note"></a>AWS IoT Greengrass 使用 JSON 作为配置值。JSON 指定了数字类型，但不区分整数和浮点数。因此， AWS IoT Greengrass中的配置值可能会转换为浮点数。为确保您的组件使用正确的数据类型，我们建议您将数字配置值定义为字符串。然后，让组件将其解析为整数或浮点数。这样可以确保您的配置值在配置和核心设备上具有相同的类型。

`ComponentDependencies`  <a name="recipe-reference-component-dependencies"></a>
（可选）一个对象字典，每个对象都定义了组件的组件依赖关系。每个对象的密钥标识组件依赖关系的名称。 AWS IoT Greengrass 安装组件时安装组件依赖关系。 AWS IoT Greengrass 等待依赖关系启动后再启动组件。每个对象包含以下信息：    
`VersionRequirement`  
npm 风格的语义版本约束，用于定义此依赖关系的兼容组件版本。您可以指定一个版本或一系列版本。有关更多信息，请参阅 [npm 语义版本计算器](https://semver.npmjs.com/)。  
`DependencyType`  
（可选）这种依赖关系的类型。从以下选项中进行选择。  
+ `SOFT` – 如果依赖关系更改状态，组件不会重新启动。
+ `HARD` – 如果依赖关系更改状态，组件将会重新启动。
默认值为 `HARD`。

`ComponentType`  
（可选）组件的类型。  
我们不建议您在配方中指定组件类型。 AWS IoT Greengrass 在创建组件时为您设置类型。
类型可以是以下项之一：  
+ `aws.greengrass.generic` – 组件运行命令或提供构件。
+ `aws.greengrass.lambda` – 组件使用 [Lambda 启动组件](lambda-launcher-component.md)运行 Lambda 函数。`ComponentSource` 参数指定此组件运行的 Lambda 函数的 ARN。

  我们不建议您使用此选项，因为它是在您通过 Lambda 函数创建组件 AWS IoT Greengrass 时设置的。有关更多信息，请参阅 [运行 AWS Lambda 函数](run-lambda-functions.md)。
+ `aws.greengrass.plugin` – 该组件与 Greengrass Nucleus 在同一 Java 虚拟机（JVM）中运行。如果您部署或重启插件组件，Greengrass Nucleus 将重新启动。

  插件组件使用与 Greengrass Nucleus 相同的日志文件。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。

  我们不建议您在组件配方中使用此选项，因为它适用于 AWS由 Java 编写的、直接与 Greengrass 核心接口的组件。有关哪些公有组件是插件的更多信息，请参阅 [AWS 提供的组件](public-components.md)。
+ `aws.greengrass.nucleus` – 核心成分。有关更多信息，请参阅 [Greengrass Nucleus](greengrass-nucleus-component.md)。

  我们建议您不要在组件配方中使用此选项。它适用于 Greengrass Nucleus 组件，该组件提供了 AWS IoT Greengrass Core 软件的最低功能。
从配方创建组件时默认为 `aws.greengrass.generic`，从 Lambda 函数创建组件时默认为 `aws.greengrass.lambda`。  
有关更多信息，请参阅 [组件类型](develop-greengrass-components.md#component-types)。

`ComponentSource`  
（可选）组件运行的 Lambda 函数的 ARN。  
我们不建议您在配方中指定组件来源。 AWS IoT Greengrass 当您通过 Lambda 函数创建组件时，为您设置此参数。有关更多信息，请参阅 [运行 AWS Lambda 函数](run-lambda-functions.md)。

  `Manifests`   
对象列表，每个对象都定义了组件的生命周期、参数和平台要求。如果核心设备符合多个清单的平台要求，则 AWS IoT Greengrass 使用核心设备匹配的第一个清单。为确保核心设备使用正确的清单，请先定义平台要求更严格的清单。适用于所有平台的清单必须是列表中的最后一个清单。  
核心设备必须满足至少一个清单的平台要求才能安装该组件。如果没有清单与核心设备匹配，则 AWS IoT Greengrass 核心软件不会安装该组件，部署将失败。
每个对象包含以下信息：    
`Name`  
（可选）此清单定义的平台友好名称。  
如果省略此参数，则会从平台 AWS IoT Greengrass 创建名称，`os`然后。`architecture`  
  `Platform`   
（可选）定义此清单所适用平台的对象。省略此参数可定义适用于所有平台的清单。  
此对象指定有关核心设备运行平台的键值对。部署此组件时， AWS IoT Greengrass Core 软件会将这些键值对与核心设备上的平台属性进行比较。C AWS IoT Greengrass ore 软件始终定义`os`和`architecture`，它可能会定义其他属性。部署 Greengrass Nucleus 组件时，您可以为核心设备指定自定义平台属性。有关更多信息，请参阅 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的[平台覆盖参数](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-platform-overrides)。  
对于每个键/值对，可以指定以下值之一：  
+ 一个精确的值，例如 `linux` 或 `windows`。必须以字母或数字开头。
+ `*`，可匹配任何值。当值不存在时，也可匹配。
+ Java 风格的正则表达式，例如 `/windows|linux/`。正则表达式必须以斜杠字符（`/`）开头和结尾。例如，正则表达式 `/.+/` 匹配任何非空值。
该对象包含以下信息：    
`runtime`  
此清单支持的平台的 [Greengrass Nucleus 运行时](https://docs.aws.amazon.com/greengrass/v2/developerguide/how-it-works.html#concept-overview)。使用平台 `runtime` 定义多个清单时，配方中支持的运行时值仅为 `aws_nucleus_lite` 和 `*`。要瞄准经典设备，则不得在配方中指定运行时字段。支持的 Greengrass Nucleus 运行时包括以下值：  
+ `*`
+ `aws_nucleus_lite`  
`os`  
（可选）此清单支持的平台操作系统名称。常见平台包括以下值：  
+ `linux`
+ `windows`
+ `darwin` (macOS)  
`architecture`  
（可选）此清单支持的平台处理器架构。常见架构包括以下值：  
+ `amd64`
+ `arm`
+ `aarch64`
+ `x86`  
`architecture.detail`  
（可选）此清单支持的平台处理器架构细节。常见架构细节包括以下值：  
+ `arm61`
+ `arm71`
+ `arm81`  
`key`  
（可选）您为此清单定义的平台属性。*Key*替换为平台属性的名称。 AWS IoT Greengrass Core 软件将此平台属性与您在 Greengrass nucleus 组件配置中指定的键值对进行匹配。有关更多信息，请参阅 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的[平台覆盖参数](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-platform-overrides)。  
使用反向域名格式以避免公司内部的域名冲突。例如，如果您的公司拥有 `example.com`，而您开展的是广播项目，则可以将自定义平台属性命名为 `com.example.radio.RadioModule`。这有助于避免公司内部的平台属性名称冲突。
例如，您可以定义平台属性 `com.example.radio.RadioModule`，根据核心设备上可用的无线电模块来指定不同的清单。每个清单可以包含适用于不同硬件配置的不同构件，因此您可以将最少的软件集部署到核心设备。  
  `Lifecycle`   
定义如何在此清单定义的平台上安装和运行组件的对象或字符串。您还可以定义适用于所有平台的[全局生命周期](#global-lifecycle-definition)。只有当要使用的清单没有指定生命周期时，核心设备才会使用全局生命周期。  
您可以在清单中定义该生命周期。您在此处指定的生命周期步骤仅适用于此清单所定义的平台。您还可以定义适用于所有平台的[全局生命周期](#global-lifecycle-definition)。
该对象或字符串包含以下信息：    
  `Setenv`   
（可选）提供给所有生命周期脚本的环境变量词典。您可以在每个生命周期脚本中使用 `Setenv` 覆盖这些环境变量。  
  `install`   
（可选）定义组件安装时要运行的脚本的对象或字符串。每次软件启动时， AWS IoT Greengrass Core 软件也会运行此生命周期步骤。  
如果 `install` 脚本以成功代码退出，则组件将进入 `INSTALLED` 状态。  
该对象或字符串包含以下信息：    
`Script`  <a name="recipe-lifecycle-script"></a>
待运行脚本。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Skipif`  <a name="recipe-lifecycle-skipif"></a>
（可选）用于确定是否运行脚本的检查。您可以定义检查路径上是否有可执行文件或文件是否存在。如果输出为真，则 AWS IoT Greengrass Core 软件将跳过该步骤。选择以下检查之一：  
+ `onpath runnable` – 检查系统路径上是否有可运行对象。例如，如果 Python 3 可用，则使用 **onpath python3** 跳过此生命周期步骤。
+ `exists file` – 检查文件是否存在。例如，如果存在 `/tmp/my-configuration.db`，则使用 **exists /tmp/my-configuration.db** 可跳过此生命周期步骤。  
`Timeout`  <a name="recipe-lifecycle-timeout"></a>
（可选）在 AWS IoT Greengrass Core 软件终止进程之前，脚本可以运行的最长时间（以秒为单位）。  
默认值：120 秒  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `run`   
（可选）定义组件启动时要运行的脚本的对象或字符串。  
当此生命周期步骤运行时，组件进入 `RUNNING` 状态。如果 `run` 脚本以成功代码退出，则组件将进入 `STOPPING` 状态。若指定了 `shutdown` 脚本，则会运行；否则组件进入 `FINISHED` 状态。  
依赖此组件的组件将在此生命周期步骤运行时启动。要运行后台进程，例如依赖组件使用的服务，请改用 `startup` 生命周期步骤。  
当您部署具有 `run` 生命周期的组件时，核心设备可以在此生命周期脚本运行后立即报告部署已完成。因此，即使 `run` 生命周期脚本在运行后不久就失败了，也可成功完成部署。如果您希望部署状态取决于组件启动脚本的结果，请改用 `startup` 生命周期步骤。  
您只能定义一个 `startup` 或 `run` 生命周期。
该对象或字符串包含以下信息：    
`Script`  <a name="recipe-lifecycle-script"></a>
待运行脚本。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Skipif`  <a name="recipe-lifecycle-skipif"></a>
（可选）用于确定是否运行脚本的检查。您可以定义检查路径上是否有可执行文件或文件是否存在。如果输出为 true，则 AWS IoT Greengrass Core 软件将跳过该步骤。选择以下检查之一：  
+ `onpath runnable` – 检查系统路径上是否有可运行对象。例如，如果 Python 3 可用，则使用 **onpath python3** 跳过此生命周期步骤。
+ `exists file` – 检查文件是否存在。例如，如果存在 `/tmp/my-configuration.db`，则使用 **exists /tmp/my-configuration.db** 可跳过此生命周期步骤。  
`Timeout`  <a name="recipe-lifecycle-timeout"></a>
（可选）在 AWS IoT Greengrass 核心软件终止进程之前，脚本可以运行的最大时间（以秒为单位）。  
默认情况下，此生命周期步骤不会超时。如果省略此超时，`run` 脚本将一直运行直到退出。  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `startup`   
（可选）定义组件启动时要运行的后台进程的对象或字符串。  
使用 `startup` 运行命令，该命令必须成功退出或将组件状态更新为 `RUNNING`，然后才能启动依赖组件。使用 [UpdateState](ipc-component-lifecycle.md#ipc-operation-updatestate)IPC 操作将组件的状态设置为`RUNNING`或`ERRORED`当组件启动未退出的脚本时。例如，您可以定义一个 `/etc/init.d/mysqld start` 启动 MySQL 进程的 `startup` 步骤。  
当此生命周期步骤运行时，组件进入 `STARTING` 状态。如果 `startup` 脚本以成功代码退出，则组件将进入 `RUNNING` 状态。然后，可以启动依赖组件。  
当您部署具有 `startup` 生命周期的组件时，核心设备可以在此生命周期脚本退出或报告其状态后将部署报告为已完成。换句话说，部署的状态 `IN_PROGRESS` 一直持续到所有组件的启动脚本退出或报告状态为止。  
您只能定义一个 `startup` 或 `run` 生命周期。
该对象或字符串包含以下信息：    
`Script`  <a name="recipe-lifecycle-script"></a>
待运行脚本。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Skipif`  <a name="recipe-lifecycle-skipif"></a>
（可选）用于确定是否运行脚本的检查。您可以定义检查路径上是否有可执行文件或文件是否存在。如果输出为 true，则 AWS IoT Greengrass Core 软件将跳过该步骤。选择以下检查之一：  
+ `onpath runnable` – 检查系统路径上是否有可运行对象。例如，如果 Python 3 可用，则使用 **onpath python3** 跳过此生命周期步骤。
+ `exists file` – 检查文件是否存在。例如，如果存在 `/tmp/my-configuration.db`，则使用 **exists /tmp/my-configuration.db** 可跳过此生命周期步骤。  
`Timeout`  <a name="recipe-lifecycle-timeout"></a>
（可选）在 AWS IoT Greengrass Core 软件终止进程之前，脚本可以运行的最长时间（以秒为单位）。  
默认值：120 秒  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `shutdown`   
（可选）定义组件关闭时要运行的脚本的对象或字符串。使用关闭生命周期来执行要在组件处于 `STOPPING` 状态时运行的代码。关闭生命周期可用于停止 `startup` 或 `run` 脚本启动的进程。  
如果您在 `startup` 中启动后台进程，请使用 `shutdown` 步骤在组件关闭时停止该进程。例如，您可以定义一个使用 `/etc/init.d/mysqld stop` 停止 MySQL 进程的 `shutdown` 步骤。  
该 `shutdown` 脚本在组件进入 `STOPPING` 状态后运行。如果此脚本成功完成，组件将进入 `FINISHED` 状态。  
该对象或字符串包含以下信息：    
`Script`  <a name="recipe-lifecycle-script"></a>
待运行脚本。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Skipif`  <a name="recipe-lifecycle-skipif"></a>
（可选）用于确定是否运行脚本的检查。您可以定义检查路径上是否有可执行文件或文件是否存在。如果输出为 true，则 AWS IoT Greengrass Core 软件将跳过该步骤。选择以下检查之一：  
+ `onpath runnable` – 检查系统路径上是否有可运行对象。例如，如果 Python 3 可用，则使用 **onpath python3** 跳过此生命周期步骤。
+ `exists file` – 检查文件是否存在。例如，如果存在 `/tmp/my-configuration.db`，则使用 **exists /tmp/my-configuration.db** 可跳过此生命周期步骤。  
`Timeout`  
（可选）在 AWS IoT Greengrass 核心软件终止进程之前，脚本可以运行的最大时间（以秒为单位）。  
默认值：15 秒。  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `recover`   
（可选）定义组件遇到错误时要运行的脚本的对象或字符串。  
此步骤在组件进入 `ERRORED` 状态时运行。如果组件三次变为 `ERRORED` 而没有成功恢复，组件就会变为 `BROKEN` 状态。要修复 `BROKEN` 组件，必须将其重新部署。  
该对象或字符串包含以下信息：    
`Script`  <a name="recipe-lifecycle-script"></a>
待运行脚本。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Skipif`  <a name="recipe-lifecycle-skipif"></a>
（可选）用于确定是否运行脚本的检查。您可以定义检查路径上是否有可执行文件或文件是否存在。如果输出为 true，则 AWS IoT Greengrass Core 软件将跳过该步骤。选择以下检查之一：  
+ `onpath runnable` – 检查系统路径上是否有可运行对象。例如，如果 Python 3 可用，则使用 **onpath python3** 跳过此生命周期步骤。
+ `exists file` – 检查文件是否存在。例如，如果存在 `/tmp/my-configuration.db`，则使用 **exists /tmp/my-configuration.db** 可跳过此生命周期步骤。  
`Timeout`  
（可选）在 AWS IoT Greengrass 核心软件终止进程之前，脚本可以运行的最大时间（以秒为单位）。  
默认值：60 秒。  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `bootstrap`   
（可选）定义要求 AWS IoT Greengrass Core 软件或核心设备重新启动的脚本的对象或字符串。这样，您就可以开发一个组件，例如在安装操作系统更新或运行时更新后执行重启。  
要安装不需要重启 AWS IoT Greengrass 核心软件或设备的更新或依赖项，请使用[安装生命周期](#install-lifecycle-definition)。
在以下情况下，当 AWS IoT Greengrass 核心软件部署组件时，此生命周期步骤在安装生命周期步骤之前运行：  
+ 组件首次部署至核心设备。
+ 组件版本变更。
+ 引导脚本会因组件配置更新而改变。
 AWS IoT Greengrass 核心软件完成部署中包含引导步骤的所有组件的引导步骤后，软件将重新启动。  
必须将 AWS IoT Greengrass 核心软件配置为系统服务才能重新启动 AWS IoT Greengrass 核心软件或核心设备。如果您未将 AWS IoT Greengrass Core 软件配置为系统服务，则该软件将无法重新启动。有关更多信息，请参阅 [将 Greengrass Nucleus 配置为系统服务](configure-greengrass-core-v2.md#configure-system-service)。
该对象或字符串包含以下信息：    
`BootstrapOnRollback`  
启用此功能后，`BootstrapOnRollback` 仅会在那些因目标部署失败而已经完成或尝试执行引导生命周期步骤的组件上运行。此功能适用于 Greengrass Nucleus 版本 2.12.0 及更高版本。
（可选）您可以将引导生命周期步骤作为回滚部署的一部分来运行。若您将此选项设置为 `true`，则将运行在回滚部署中定义的引导生命周期步骤。部署失败时，先前版本的组件引导生命周期将在回滚部署期间再次运行。  
默认值为 `false`。  
`Script`  
待运行脚本。此脚本的退出代码定义了重启指令。使用以下退出代码：  
+ `0`— 不要重启 AWS IoT Greengrass 核心软件或核心设备。在所有组件启动后， AWS IoT Greengrass Core 软件仍会重新启动。
+ `100`— 请求重新启动 AWS IoT Greengrass 核心软件。
+ `101` – 请求重启核心设备。
退出代码 100 至 199 保留给特殊行为使用。其他退出代码代表脚本错误。  
`RequiresPrivilege`  <a name="recipe-lifecycle-requiresprivilege"></a>
（可选）您可以使用根权限运行脚本。如果将此选项设置为`true`，则 AWS IoT Greengrass Core 软件将以 root 用户身份运行此生命周期脚本，而不是以您配置为运行此组件的系统用户的身份运行此生命周期脚本。默认值为 `false`。  
`Timeout`  <a name="recipe-lifecycle-timeout"></a>
（可选）在 AWS IoT Greengrass Core 软件终止进程之前，脚本可以运行的最长时间（以秒为单位）。  
默认值：120 秒  
`Setenv`  <a name="recipe-lifecycle-environment"></a>
（可选）提供给脚本的环境变量词典。这些环境变量会覆盖您在 `Lifecycle.Setenv` 中提供的变量。  
  `Selections`   
（可选）选择键列表，用于指定要为此清单运行的[全局生命周期](#global-lifecycle-definition)的各个部分。在全局生命周期中，您可以使用任何级别的选择键来定义生命周期步骤，以选择生命周期的子部分。然后，核心设备使用与该清单中的选择键相匹配的部分。有关更多信息，请参阅[全局生命周期示例](#global-lifecycle-definition)。  
只有当该清单未定义生命周期时，核心设备才会使用全局生命周期中的选择。
您可以指定 `all` 选择键来运行全局生命周期中没有选择键的部分。  
  `Artifacts`   
（可选）对象列表，每个对象都定义了该清单所定义平台上组件的二进制工件。例如，您可以将代码或图像定义为构件。  
部署组件时， AWS IoT Greengrass Core 软件会将构件下载到核心设备上的文件夹。您也可以将构件定义为软件下载后提取的存档文件。  
您可以使用[配方变量](#recipe-variables)来获取核心设备上安装构件的文件夹路径。  
+ 普通文件 – 使用 [artifacts:path 配方变量](#component-recipe-artifacts-path)来获取包含构建的文件夹路径。例如，在配方中指定 `{artifacts:path}/my_script.py` 以获取包含 URI `s3://amzn-s3-demo-bucket/path/to/my_script.py` 的构件路径。
+ 提取的存档 – 使用 [artifacts:decompressedPath 配方变量](#component-recipe-artifacts-decompressed-path)来获取包含已提取存档构件的文件夹路径。C AWS IoT Greengrass ore 软件将每个存档提取到与存档同名的文件夹中。例如，在配方中指定 `{artifacts:decompressedPath}/my_archive/my_script.py` 以获取包含 URI `s3://amzn-s3-demo-bucket/path/to/my_archive.zip` 的存档构件 `my_script.py` 路径。
在本地核心设备上开发带有存档构件的组件时，可能没有该构件的 URI。要使用提取构件的 `Unarchive` 选项测试组件，请指定一个文件名与存档构件文件名匹配的 URI。您可以指定期望上传存档构件的 URI，也可以指定一个新的占位符 URI。例如，要在本地部署期间提取 `my_archive.zip` 构件，可以指定 `s3://amzn-s3-demo-bucket/my_archive.zip`。
每个对象包含以下信息：    
`Uri`  
S3 存储桶中的构件 URI。安装组件时， AWS IoT Greengrass Core 软件会从此 URI 中获取工件，除非该构件已存在于设备上。在每个清单中，每个构件都必须有一个唯一的文件名。  
`Unarchive`  
（可选）要解压缩的档案类型。从以下选项中进行选择：  
+ `NONE` – 该文件不是要解压的存档。 AWS IoT Greengrass Core 软件将构件安装至核心设备上的文件夹。您可以使用 [artifacts:path 配方变量](#component-recipe-artifacts-path)来获取此文件夹的路径。
+ `ZIP` – 该文件是一个 ZIP 存档。C AWS IoT Greengrass ore 软件将存档提取到与存档同名的文件夹。您可以使用 [artifacts:decompressedPath 配方变量](#component-recipe-artifacts-decompressed-path)来获取包含此文件夹的文件夹路径。
默认值为 `NONE`。  
  `Permission`   
（可选）定义为此构件文件设置的访问权限的对象。您可以设置读取权限和执行权限。  
您无法设置写入权限，因为 AWS IoT Greengrass 核心软件不允许组件编辑构件文件夹中的构件文件。要编辑组件中的构件文件，请将其复制到其他位置或发布并部署新的构件文件。
如果您将工件定义为要解压缩的存档，则 AWS IoT Greengrass Core 软件会对其从存档中解压缩的文件设置这些访问权限。C AWS IoT Greengrass ore 软件将文件夹的访问权限设置`ALL`为`Read`和`Execute`。这样，组件就可以查看文件夹中的解压文件。要为存档中的单个文件设置权限，可以在[安装生命周期脚本](#install-lifecycle-definition)中设置权限。  
该对象包含以下信息：    
`Read`  
（可选）要为此构件文件设置的读取权限。要允许其他组件访问此构件，例如依赖于此组件的组件，请指定 `ALL`。从以下选项中进行选择：  
+ `NONE` – 文件不可读。
+ `OWNER` – 您配置为运行此组件的系统用户可以读取该文件。
+ `ALL` – 所有用户均可读取该文件。
默认值为 `OWNER`。  
`Execute`  
（可选）要为此构件文件设置的运行权限。`Execute` 权限意味着 `Read` 权限。例如，如果您将 `Execute` 指定为 `ALL`，则所有用户都可以读取和运行此构件文件。  
从以下选项中进行选择：  
+ `NONE` – 该文件无法运行。
+ `OWNER` – 该文件可由您配置为运行该组件的系统用户运行。
+ `ALL` – 所有用户均可运行该文件。
默认值为 `NONE`。  
`Digest`  
（只读）构件的加密摘要哈希值。创建组件时， AWS IoT Greengrass 使用哈希算法计算构件文件的哈希值。然后，在部署组件时，Greengrass Nucleus 会计算已下载构件的哈希值，并将哈希值与该摘要进行比较，以便在安装之前验证构件。如果哈希值与摘要不匹配，则部署失败。  
如果您设置了此参数，则 AWS IoT Greengrass 会替换您在创建组件时设置的值。  
`Algorithm`  
（只读） AWS IoT Greengrass 用于计算工件摘要哈希值的哈希算法。  
如果您设置了此参数，则 AWS IoT Greengrass 会替换您在创建组件时设置的值。

  `Lifecycle`   
定义如何安装和运行组件的对象。只有当要使用的[清单](#manifest-definition)没有指定生命周期时，核心设备才会使用全局生命周期。  
您可以在清单外定义该生命周期。您还可以定义适用于与该清单匹配的平台的[清单生命周期](#manifest-lifecycle-definition)。
在全局生命周期中，您可以指定为每个清单中指定的某些[选择键](#manifest-selections-definition)运行的生命周期。选择键是字符串，用于标识要为每个清单运行的全局生命周期的各个部分。  
`all` 选择键是任何没有选择键部分的默认值。这意味着您可以在清单中指定 `all` 选择键来运行全局生命周期的各个部分，而无需选择键。在全局生命周期中，您无需指定 `all` 选择键。  
如果清单未定义生命周期或选择键，则核心设备将默认使用 `all` 选择键。这意味着在这种情况下，核心设备使用全局生命周期中不使用选择键的部分。  
此对象包含的信息与[清单生命周期](#manifest-lifecycle-definition)相同，但您可以在任何级别指定选择键来选择生命周期的子部分。  
建议每个选择键只使用小写字母，以避免选择键和生命周期键之间发生冲突。生命周期键名以大写字母开头。

**Example 带有顶层选择键的全局生命周期示例**  

```
Lifecycle:
  key1:
    install:
      SkipIf: either onpath executable or exists file
      Script: command1
  key2:
    install:
      Script: command2
  all:
    install:
      Script: command3
```

**Example 带有底层选择键的全局生命周期示例**  

```
Lifecycle:
  install:
    Script:
      key1: command1
      key2: command2
      all: command3
```

**Example 带有多个选择键级别的全局生命周期示例**  

```
Lifecycle:
  key1:
    install:
      SkipIf: either onpath executable or exists file
      Script: command1
  key2:
    install:
      Script: command2
  all:
    install:
      Script:
        key3: command3
        key4: command4
        all: command5
```

## 配方变量
<a name="recipe-variables"></a>

配方变量显示来自当前组件和核心的信息，供您在配方中使用。例如，您可以使用配方变量将组件配置参数传递给在生命周期脚本中运行的应用程序。

您可以在组件配方的以下部分中使用配方变量：
+ 生命周期定义。
+ 组件配置定义，前提是您使用 [Greengrass](greengrass-nucleus-component.md) nucleus v2.6.0 或更高版本并将配置选项设置为。[interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)`true`在[部署组件配置更新](update-component-configurations.md#merge-configuration-update-recipe-variables)时，也可以使用配方变量。

配方变量使用 `{recipe_variable}` 语法。大括号表示配方变量。

AWS IoT Greengrass 支持以下配方变量：

`component_dependency_name:configuration:json_pointer`  
此配方定义的组件或该组件所依赖的组件的配置参数值。  
您可以使用此变量为在组件生命周期中运行的脚本提供参数。  
AWS IoT Greengrass 仅在组件生命周期定义中支持此配方变量。
此配方变量的输入如下：  
+ <a name="recipe-variable-component-dependency-name"></a>`component_dependency_name` –（可选）要查询的组件依赖关系名称。省略此段可查询此配方定义的组件。您只能指定直接依赖关系。
+ `json_pointer` – 指向要评估的配置值的 JSON 指针。JSON 指针以正斜杠 `/` 开头。要识别嵌套组件配置中的值，请使用正斜杠 (`/`) 分隔配置中每一级的键。您可以使用数字作为键来指定列表中的索引。有关更多信息，请参阅 [JSON 指针规范](https://tools.ietf.org/html/rfc6901)。

  AWS IoT Greengrass Core 使用 JSON 指针获取 YAML 格式的食谱。
JSON 指针可以引用以下节点类型：  
+ 一个值节点。 AWS IoT Greengrass Core 将配方变量替换为该值的字符串表示形式。空值转换为 `null` 字符串。
+ 一个对象节点。 AWS IoT Greengrass Core 将配方变量替换为该对象的序列化 JSON 字符串表示形式。
+ 没有节点。 AWS IoT Greengrass Core 不会替换配方变量。
例如，`{configuration:/Message}` 配方变量检索组件配置中 `Message` 键的值。`{com.example.MyComponentDependency:configuration:/server/port}` 配方变量检索组件依赖关系的 `server` 配置对象中 `port` 的值。

  `component_dependency_name:artifacts:path`   
此配方定义的组件或该组件所依赖的组件的构件根路径。  
安装组件时，会将该组件的构件 AWS IoT Greengrass 复制到此变量公开的文件夹。例如，您可以使用此变量来标识要在组件生命周期中运行的脚本的位置。  
<a name="recipe-variable-artifact-folder-permissions"></a>此路径下的文件夹为只读文件夹。要修改构件文件，请将文件复制到其他位置，例如当前工作目录（`$PWD` 或 `.`）。然后，修改那里的文件。  
<a name="recipe-variable-component-dependency-artifact-file-permissions"></a>要从组件依赖关系中读取或运行构件，则该构件 `Read` 或 `Execute` 权限必须是 `ALL`。有关更多信息，请参阅您在组件配方中定义的[构件权限](#component-artifact-permission)。  
此配方变量的输入如下：  
+ <a name="recipe-variable-component-dependency-name"></a>`component_dependency_name` –（可选）要查询的组件依赖关系名称。省略此段可查询此配方定义的组件。您只能指定直接依赖关系。

  `component_dependency_name:artifacts:decompressedPath`   
此配方定义的组件或该组件所依赖的组件的解压存档构件的根路径。  
安装组件后，将该组件的存档工件 AWS IoT Greengrass 解压缩到此变量公开的文件夹。例如，您可以使用此变量来标识要在组件生命周期中运行的脚本的位置。  
每个构件都会解压至解压路径内的一个文件夹，该文件夹与构件同名，但没有扩展名。例如，名为 `models.zip` 的 ZIP 构件解压至 `{artifacts:decompressedPath}/models` 文件夹。  
<a name="recipe-variable-artifact-folder-permissions"></a>此路径下的文件夹为只读文件夹。要修改构件文件，请将文件复制到其他位置，例如当前工作目录（`$PWD` 或 `.`）。然后，修改那里的文件。  
<a name="recipe-variable-component-dependency-artifact-file-permissions"></a>要从组件依赖关系中读取或运行构件，则该构件 `Read` 或 `Execute` 权限必须是 `ALL`。有关更多信息，请参阅您在组件配方中定义的[构件权限](#component-artifact-permission)。  
此配方变量的输入如下：  
+ <a name="recipe-variable-component-dependency-name"></a>`component_dependency_name` –（可选）要查询的组件依赖关系名称。省略此段可查询此配方定义的组件。您只能指定直接依赖关系。

  `component_dependency_name:work:path`   
此功能适用于 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的 v2.0.4 及更高版本。  
此配方定义的组件或该组件所依赖的组件的工作路径。从组件的上下文运行时，此配方变量的值等同于 `$PWD` 环境变量和 [pwd](https://en.wikipedia.org/wiki/Pwd) 命令的输出。  
您可以使用此配方变量在组件和依赖关系之间共享文件。  
此路径下的文件夹可由此配方定义的组件以及以同一用户和组身份运行的其他组件进行读写操作。  
此配方变量的输入如下：  
+ <a name="recipe-variable-component-dependency-name"></a>`component_dependency_name` –（可选）要查询的组件依赖关系名称。省略此段可查询此配方定义的组件。您只能指定直接依赖关系。

`kernel:rootPath`  
 AWS IoT Greengrass 核心根路径。

`iot:thingName`  
此功能适用于 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的 v2.3.0 及更高版本。  
核心设备的名称 AWS IoT 。

## 配方示例
<a name="recipe-examples"></a>

您可以参考以下配方示例，以帮助您为组件创建配方。

AWS IoT Greengrass 策划了一份名为 Greengrass 软件目录的 Greengrass 组件索引。该目录跟踪 Greengrass 社区开发的 Greengrass 组件。您可以从该目录中下载、修改和部署组件来创建 Greengrass 应用程序。有关更多信息，请参阅 [社区组件](greengrass-software-catalog.md)。

**Topics**
+ [Hello World 组件配方](#recipe-example-hello-world)
+ [Python 运行时组件示例](#recipe-example-python-runtime)
+ [指定多个字段的组件配方](#recipe-example-all-fields)

### Hello World 组件配方
<a name="recipe-example-hello-world"></a>

以下配方描述了一个运行 Python 脚本的 Hello World 组件。该组件支持所有平台，接受 AWS IoT Greengrass 作为实参传递给 Python 脚本的 `Message` 参数。这是[入门教程](getting-started.md)中 Hello World 组件的配方。

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.HelloWorld",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "My first AWS IoT Greengrass component.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "Message": "world"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "run": "python3 -u {artifacts:path}/hello_world.py {configuration:/Message}"
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "run": "py -3 -u {artifacts:path}/hello_world.py {configuration:/Message}"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.HelloWorld
ComponentVersion: '1.0.0'
ComponentDescription: My first AWS IoT Greengrass component.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    Message: world
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      run: |
        python3 -u {artifacts:path}/hello_world.py "{configuration:/Message}"
  - Platform:
      os: windows
    Lifecycle:
      run: |
        py -3 -u {artifacts:path}/hello_world.py "{configuration:/Message}"
```

------

### Python 运行时组件示例
<a name="recipe-example-python-runtime"></a>

以下配方描述了一个安装 Python 的组件。此组件支持 64 位 Linux 设备。

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.PythonRuntime",
  "ComponentDescription": "Installs Python 3.7",
  "ComponentPublisher": "Amazon",
  "ComponentVersion": "3.7.0",
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "architecture": "amd64"
      },
      "Lifecycle": {
        "install": "apt-get update\napt-get install python3.7"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.PythonRuntime
ComponentDescription: Installs Python 3.7
ComponentPublisher: Amazon
ComponentVersion: '3.7.0'
Manifests:
  - Platform:
      os: linux
      architecture: amd64
    Lifecycle:
      install: |
        apt-get update
        apt-get install python3.7
```

------

### 指定多个字段的组件配方
<a name="recipe-example-all-fields"></a>

以下组件配方使用多个配方字段。

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.FooService",
  "ComponentDescription": "Complete recipe for AWS IoT Greengrass components",
  "ComponentPublisher": "Amazon",
  "ComponentVersion": "1.0.0",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "TestParam": "TestValue"
    }
  },
  "ComponentDependencies": {
    "BarService": {
      "VersionRequirement": "^1.1.0",
      "DependencyType": "SOFT"
    },
    "BazService": {
      "VersionRequirement": "^2.0.0"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux",
        "architecture": "amd64"
      },
      "Lifecycle": {
        "install": {
          "Skipif": "onpath git",
          "Script": "sudo apt-get install git"
        },
        "Setenv": {
          "environment_variable1": "variable_value1",
          "environment_variable2": "variable_value2"
        }
      },
      "Artifacts": [
        {
          "Uri": "s3://amzn-s3-demo-bucket/hello_world.zip",
          "Unarchive": "ZIP"
        },
        {
          "Uri": "s3://amzn-s3-demo-bucket/hello_world_linux.py"
        }
      ]
    },
    {
      "Lifecycle": {
        "install": {
          "Skipif": "onpath git",
          "Script": "sudo apt-get install git",
          "RequiresPrivilege": "true"
        }
      },
      "Artifacts": [
        {
          "Uri": "s3://amzn-s3-demo-bucket/hello_world.py"
        }
      ]
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.FooService
ComponentDescription: Complete recipe for AWS IoT Greengrass components
ComponentPublisher: Amazon
ComponentVersion: 1.0.0
ComponentConfiguration:
  DefaultConfiguration:
    TestParam: TestValue
ComponentDependencies:
  BarService:
    VersionRequirement: ^1.1.0
    DependencyType: SOFT
  BazService:
    VersionRequirement: ^2.0.0
Manifests:
  - Platform:
      os: linux
      architecture: amd64
    Lifecycle:
      install:
        SkipIf: onpath git
        Script: sudo apt-get install git
      SetEnv:
        environment_variable1: variable_value1
        environment_variable2: variable_value2
    Artifacts:
      - Uri: 's3://amzn-s3-demo-bucket/hello_world.zip'
        Unarchive: ZIP
      - Uri: 's3://amzn-s3-demo-bucket/hello_world_linux.py'
  - Lifecycle:
      install:
        SkipIf: onpath git
        Script: sudo apt-get install git
        RequiresPrivilege: 'true'
    Artifacts:
      - Uri: 's3://amzn-s3-demo-bucket/hello_world.py'
```

------

# 组件环境变量参考
<a name="component-environment-variables"></a>

 AWS IoT Greengrass Core 软件在运行组件生命周期脚本时会设置环境变量。你可以在组件中获取这些环境变量来获取事物名称 AWS 区域、和 Greengrass nucleus 版本。该软件还会设置您的组件在使用[进程间通信 SDK](interprocess-communication.md) 以及[与 AWS 服务交互](interact-with-aws-services.md)时所需的环境变量。

您还可以为组件的生命周期脚本设置自定义环境变量。有关更多信息，请参阅 [Setenv](component-recipe-reference.md#lifecycle-setenv-definition)。

C AWS IoT Greengrass ore 软件设置以下环境变量：

`AWS_IOT_THING_NAME`  
代表这个 Greengrass 核心设备 AWS IoT 的事物的名称。

`AWS_REGION`  
这款 Greengrass 核心设备的工作 AWS 区域 地点。  
然后 AWS SDKs 使用此环境变量来标识要使用的默认区域。此变量等效于 `AWS_DEFAULT_REGION`。

`AWS_DEFAULT_REGION`  
这款 Greengrass 核心设备的工作 AWS 区域 地点。  
 AWS CLI 使用此环境变量来标识要使用的默认区域。此变量等效于 `AWS_REGION`。

`GGC_VERSION`  
在此 Greengrass 核心设备上运行的 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的版本。

`GG_ROOT_CA_PATH`  
此功能适用于 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的 v2.5.5 及更高版本。  
GreengRass Nucleus 使用的根证书颁发机构（CA）证书的路径。

`AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT`  
组件用来与 C AWS IoT Greengrass ore 软件通信的 IPC 插槽的路径。有关更多信息，请参阅 [使用 AWS IoT Device SDK 与 Greengrass 原子核、其他组件进行通信，以及 AWS IoT Core与 Greengrass 核、其他组件进行通信 AWS IoT Core](interprocess-communication.md)。

`SVCUID`  
组件用来连接到 IPC 套接字并与 C AWS IoT Greengrass ore 软件通信的秘密令牌。有关更多信息，请参阅 [使用 AWS IoT Device SDK 与 Greengrass 原子核、其他组件进行通信，以及 AWS IoT Core与 Greengrass 核、其他组件进行通信 AWS IoT Core](interprocess-communication.md)。

`AWS_CONTAINER_AUTHORIZATION_TOKEN`  
组件用于从[令牌交换服务组件](token-exchange-service-component.md)检索凭证的秘密令牌。

`AWS_CONTAINER_CREDENTIALS_FULL_URI`  
组件请求从[令牌交换服务组件](token-exchange-service-component.md)检索凭证的 URI。