

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

# 将 AWS IoT Greengrass 组件部署到设备
<a name="manage-deployments"></a>

您可以使用 AWS IoT Greengrass 将组件部署到设备或设备组。您可以使用*部署*来定义发送到设备的组件和配置。 AWS IoT Greengrass 部署到代表 Greengrass 核心设备的*目标*、 AWS IoT 事物或事物组。 AWS IoT Greengrass 使用[AWS IoT Core 作业](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)部署到您的核心设备。您可以配置任务部署到设备的方式。

## 核心设备部署
<a name="core-device-deployments"></a>

每台核心设备都会运行该设备的部署组件。对同一目标的新部署会覆盖之前对目标的部署。创建部署时，您可以定义要应用于核心设备现有软件的组件和配置。

修改目标部署时，会将先前修订版中的组件替换为新修订版中的组件。例如，您将 [日志管理器](log-manager-component.md) 和 [密钥管理器](secret-manager-component.md) 组件部署至事物组 `TestGroup`。然后为 `TestGroup` 创建另一个部署，仅指定密钥管理器组件。因此，该组中的核心设备不再运行日志管理器。

## 平台依赖关系解析
<a name="platform-dependency-resolution"></a>

当核心设备收到部署时，它会检查组件是否与核心设备兼容。例如，如果您将 [Firehose](kinesis-firehose-component.md) 部署至 Windows 目标，则部署将失败。

## 组件依赖关系解析
<a name="component-dependency-resolution"></a>

在组件部署期间，核心设备会跨事物组验证所有组件的依赖关系与版本要求的兼容性。这可以确保所有组件及其依赖关系在继续部署之前满足版本限制。

在依赖关系解析过程中，先识别配方中没有依赖关系的目标组件。然后，系统使用广度优先搜索（BFS）构建依赖树，这种搜索会系统地探索每个目标节点，找出其依赖关系，然后进行下一个节点。每个节点都包含作为键的目标组件，以及作为值的版本要求。

版本要求综合了三组约束：
+ 现有事物组中已经确立的版本要求。
+ 部署所需的组件版本。在部署或更新部署时，必须选择一个组件版本。
+ 在配方的依赖关系部分中定义的任何组件版本约束。

### 解析组件依赖关系
<a name="resolving-dependencies"></a>

在部署过程中，Greengrass Nucleus 先尝试查找当前在满足要求的设备上运行的本地候选项。如果正在运行的组件满足要求，Nucleus 将从配方文件夹中获取存储的配方路径，然后在本地存储中查找最新的本地版本。

对于 AWS 云 部署，核心将调用 [ResolveComponentCandidates API](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_ResolveComponentCandidates.html)。此 API 将从最新的可用版本开始，并检查版本是否满足依赖关系和要求。Nucleus 收到来自 API 的响应时会选择最新版本。如果未从中找到满足要求的版本 AWS 云 ，则部署将失败。如果设备离线，则会回退至找出的原始本地候选项。如果找不到满足要求的本地候选项，则部署将失败。

对于本地部署，如果本地候选人存在并且符合要求，则核心仅使用本地候选人，而无需与之协商。 AWS 云如果没有这样的候选项，则部署将失败。

**注意**  
所有解析的配方都存储在本地，以供将来参考。

有关更多信息，请参阅中的[依赖关系解析](https://github.com/aws-greengrass/aws-greengrass-nucleus/wiki/Deployment#dependency-resolution)部分 GitHub。

如果 Greengrass Nucleus 能够成功解析所有组件，则 Nucleus 日志将包含以下行。

```
resolve-all-group-dependencies-finish. Finish resolving all groups dependencies.
```

**Example**  
下面是 Nucleus 如何解析组件要求的示例。  
+ 您可以部署依赖于组件 C 版本 1.0.0-1.9.0 的组件 A。
+ 也可以部署依赖于组件 C 版本 1.4.0-1.9.5 的组件 B。
通过组件依赖关系解析，Nucleus 将部署最新版本的组件 C 版本，以满足组件 A 和组件 C 的要求。组件 C 的最新版本为 1.9.0。

#### 组件依赖关系解析的常见失败案例
<a name="w2ab1c24c25b9c11c19"></a>

组件依赖关系解析可能因为以下两个主要原因而失败：目标版本要求冲突，或组件依赖关系要求冲突。

##### 场景 1：目标版本要求冲突
<a name="w2ab1c24c25b9c11c19b5"></a>
+ 某个事物存在于一个事物组中，您还想将该事物添加至一个新事物组中。如果新事物组要求的事物版本不同，则部署将失败。
+ 如果某个事物属于一个事物组，它希望通过事物部署来更新组件版本，则部署也可能会失败。

![\[导致部署失败的组件依赖关系。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/images/dependency-4.png)


*失败日志示例：*

```
2025-04-11T06:16:03.315Z [ERROR] (pool-3-thread-27) com.aws.greengrass.componentmanager.ComponentManager: Failed to negotiate version with cloud and no local version to fall back to. {componentName=ComponentC, versionRequirement={thing/ABC==2.0.0, thinggroup/ThingGroupA==1.0.0}}
2025-04-11T06:16:03.316Z [ERROR] (pool-3-thread-26) com.aws.greengrass.deployment.DeploymentService: Error occurred while processing deployment. {deploymentId=fbac24de-4ef9-44b0-a685-fdc63b0f02b8, serviceName=DeploymentService, currentState=RUNNING}
java.util.concurrent.ExecutionException: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentC version constraints: thing/ABC requires =2.0.0, thinggroup/ThingGroupA requires =1.0.0.
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:127)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:50)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentC version constraints: thing/ABC requires =2.0.0, thinggroup/ThingGroupA requires =1.0.0.
    at com.aws.greengrass.componentmanager.ComponentManager.negotiateVersionWithCloud(ComponentManager.java:232)
    at com.aws.greengrass.componentmanager.ComponentManager.resolveComponentVersion(ComponentManager.java:167)
    at com.aws.greengrass.componentmanager.DependencyResolver.lambda$resolveDependencies$0(DependencyResolver.java:134)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveComponentDependencies(DependencyResolver.java:231)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveDependencies(DependencyResolver.java:131)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.lambda$call$2(DefaultDeploymentTask.java:125)
    ... 4 more
```

日志显示存在版本冲突错误，因为 Nucleus 找不到同时满足两个相互冲突的要求的组件版本。

##### 如何解决
<a name="w2ab1c24c25b9c11c19b5c13"></a>
+ 如果要将组件保留在每个事物组中，可在每个事物组中选择相同的组件版本。
+ 选择一个满足部署要求的组件版本。
+ 如果要使用的组件版本不满足两个事物组的要求，请选择满足该事物组版本要求的组件版本，并仅在该事物组中使用该组件。

##### 场景 2：组件依赖关系版本要求冲突
<a name="w2ab1c24c25b9c11c19b7"></a>

如果一个组件是其他组件的依赖项，且其他组件需要该组件的不同版本或不同版本范围，则可能没有可用的版本能满足所有版本要求。在这种场景下，部署将失败。

**Example**  
部署组件 A（v2.5.0）、组件 B（v1.3.0）和组件 C（v1.0.0）  
+ 组件 A 需要组件 B 版本 >=1.0.0。

  ```
  ---
  ...
  ComponentName: ComponentA
  ComponentVersion: "2.5.0"
  ComponentDependencies:
      ComponentB:
          VersionRequirement: ">=1.0.0"
          DependencyType: "HARD"
  ...
  ```
+ 组件 C 需要组件 A 版本 <2.0.0。

  ```
  ---
  ...
  ComponentName: ComponentC
  ComponentVersion: "1.0.0"
  ComponentDependencies:
      ComponentA:
          VersionRequirement: "<2.0.0"
          DependencyType: "HARD"
  ...
  ```
组件 A 的两个要求之间存在版本冲突：  
+ 组件 A 在此部署中需要版本 2.5.0
+ 组件 C 需要组件 A 版本低于 2.0.0
这两个要求之间相互矛盾，因此 Nucleus 无法找到满足这两个要求的组件 A 版本。因此，依赖关系解析失败。

![\[导致部署失败的组件依赖关系。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/images/dependency-3.png)


*失败日志示例：*

```
2025-04-11T06:07:18.291Z [ERROR] (pool-3-thread-25) com.aws.greengrass.componentmanager.ComponentManager: Failed to negotiate version with cloud and no local version to fall back to. {componentName=ComponentA, versionRequirement={ComponentC=<2.0.0, thinggroup/ThingGroupA==2.5.0}}
2025-04-11T06:07:18.292Z [ERROR] (pool-3-thread-24) com.aws.greengrass.deployment.DeploymentService: Error occurred while processing deployment. {deploymentId=2ffac4df-1ac9-405c-8c11-28494a1b4382, serviceName=DeploymentService, currentState=RUNNING}
java.util.concurrent.ExecutionException: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentA version constraints: ComponentC requires <2.0.0, thinggroup/ThingGroupA requires =2.5.0.
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:127)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:50)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentA version constraints: ComponentC requires <2.0.0, thinggroup/ThingGroupA requires =2.5.0.
    at com.aws.greengrass.componentmanager.ComponentManager.negotiateVersionWithCloud(ComponentManager.java:232)
    at com.aws.greengrass.componentmanager.ComponentManager.resolveComponentVersion(ComponentManager.java:167)
    at com.aws.greengrass.componentmanager.DependencyResolver.lambda$resolveDependencies$0(DependencyResolver.java:134)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveComponentDependencies(DependencyResolver.java:231)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveDependencies(DependencyResolver.java:131)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.lambda$call$2(DefaultDeploymentTask.java:125)
    ... 4 more
```

日志表明，Nucleus 找不到满足以下要求的组件 A 版本。
+ ComponentA 的要求必须完全是 2.5.0 版（从 ThingGroup A 开始）。
+ 需要使用的是低于版本 2.0.0 的组件 C。

##### 如何解决
<a name="w2ab1c24c25b9c11c19b7c17"></a>
+ 如果要将组件保留在每个事物组中，可在每个事物组中选择相同的组件版本。
+ 选择一个满足部署要求的组件版本。
+ 如果要使用的组件版本不满足两个事物组的要求，请选择满足该事物组版本要求的组件版本，并仅在该事物组中使用该组件。

**提示**  
如果您在 AWS 提供的任何组件上看到此错误，则可以通过将冲突组件更新到最新版本来解决该错误。

## 从事物组中移除设备
<a name="thing-group-removal-behavior"></a>

从事物组中移除核心设备时，组件部署行为取决于核心设备运行的 [Greengrass Nucleus](greengrass-nucleus-component.md) 版本。

------
#### [ 2.5.1 and later ]

从事物组中移除核心设备时，其行为取决于 AWS IoT 策略是否授予`greengrass:ListThingGroupsForCoreDevice`权限。有关此权限和核心设备 AWS IoT 策略的更多信息，请参阅[设备身份验证和授权 AWS IoT Greengrass](device-auth.md)。
+ **如果 AWS IoT 策略授予此权限**

  <a name="thing-group-removal-behavior-remove-components"></a>当您从事物组中移 AWS IoT Greengrass 除核心设备时，会在下次对该设备进行部署时移除该事物组的组件。如果设备上的某个组件包含在下次部署中，则该组件不会从设备中移除。
+ **如果 AWS IoT 策略未授予此权限**

  <a name="thing-group-removal-behavior-no-remove-components"></a>从事物组中移除核心设备时， AWS IoT Greengrass 不会从设备中删除该事物组的组件。

  <a name="thing-group-removal-behavior-no-remove-components-how-to-remove"></a>要从设备中移除组件，请使用 Greengrass CLI 的[部署创建](gg-cli-deployment.md#deployment-create)命令。使用 `--remove` 参数指定要移除的组件，并使用 `--groupId` 参数指定事物组。

------
#### [ 2.5.0 ]

<a name="thing-group-removal-behavior-remove-components"></a>当您从事物组中移 AWS IoT Greengrass 除核心设备时，会在下次对该设备进行部署时移除该事物组的组件。如果设备上的某个组件包含在下次部署中，则该组件不会从设备中移除。

此行为需要核心设备的 AWS IoT 策略授予`greengrass:ListThingGroupsForCoreDevice`权限。如果核心设备没有此权限，则无法应用部署。有关更多信息，请参阅 [设备身份验证和授权 AWS IoT Greengrass](device-auth.md)。

------
#### [ 2.0.x - 2.4.x ]

<a name="thing-group-removal-behavior-no-remove-components"></a>从事物组中移除核心设备时， AWS IoT Greengrass 不会从设备中删除该事物组的组件。

<a name="thing-group-removal-behavior-no-remove-components-how-to-remove"></a>要从设备中移除组件，请使用 Greengrass CLI 的[部署创建](gg-cli-deployment.md#deployment-create)命令。使用 `--remove` 参数指定要移除的组件，并使用 `--groupId` 参数指定事物组。

------

## 部署
<a name="deployments"></a>

部署是持续的。创建部署时， AWS IoT Greengrass 会将部署部署部署部署部署到在线的目标设备。如果目标设备不在线，则它将在下次连接时收到部署 AWS IoT Greengrass。将核心设备添加到目标事物组时， AWS IoT Greengrass 会向该设备发送该事物组的最新部署。

默认情况下，在核心设备部署组件之前，它会通知设备上的每个组件。Greengrass 组件可以响应推迟部署的通知。如果设备电池电量不足或正在运行无法中断的进程，则可能需要推迟部署。有关更多信息，请参阅 [教程：开发可延迟组件更新的 Greengrass 组件](defer-component-updates-tutorial.md)。创建部署时，您可以将其配置为在不通知组件的情况下进行部署。

每个目标事物或目标组一次只能部署一个。这意味着，当您为目标创建部署时，将 AWS IoT Greengrass 不再部署该目标部署的先前版本。

## 部署选项
<a name="deployment-options"></a>

系统提供多个部署选项，可让您控制哪些设备会收到更新以及更新的部署方式。创建部署时，您可以配置以下选项：
+ **AWS IoT Greengrass 组件**

  定义要在目标设备上安装和运行的组件。 AWS IoT Greengrass 组件是您在 Greengrass 核心设备上部署和运行的软件模块。只有当组件支持设备的平台时，设备才会接收组件。这样，即使目标设备在多个平台上运行，您也可以将其部署到设备组。如果某个组件不支持该设备的平台，则该组件不会部署到设备上。

  您可以将自定义组件和 AWS提供的组件部署到您的设备上。部署组件时，会 AWS IoT Greengrass 识别所有组件依赖关系并将其部署。有关更多信息，请参阅[开发 AWS IoT Greengrass 组件](develop-greengrass-components.md)和[AWS提供的组件](public-components.md)。

  您可以为每个组件定义要部署的版本和配置更新。*配置更新*指定如何修改核心设备上组件的现有配置，如果核心设备上不存在组件，则指定如何修改组件的默认配置。您可以指定要重置为默认值的配置值以及要合并到核心设备上的新配置值。当核心设备收到针对不同目标的部署，并且每个部署都指定了兼容的组件版本时，核心设备会根据您创建部署的时间戳按顺序应用配置更新。有关更多信息，请参阅 [更新组件配置](update-component-configurations.md)。
**重要**  <a name="component-patch-update-note"></a>
<a name="component-patch-update"></a>部署组件时， AWS IoT Greengrass 会安装该组件所有依赖项的最新支持版本。因此，如果您向事物组中添加新设备或更新针对这些设备的部署，则 AWS提供的公共组件的新补丁版本可能会自动部署到您的核心设备上。某些自动更新（例如 Nucleus 更新）可能会导致您的设备意外重启。  
<a name="component-version-pinning"></a>为防止设备上运行的组件出现意外更新，我们建议您在[创建部署](create-deployments.md)时直接包含您对该组件的首选版本。有关 C AWS IoT Greengrass ore 软件更新行为的更多信息，请参阅[更新 AWS IoT Greengrass Core 软件（OTA）](update-greengrass-core-v2.md)。
+ **部署策略**

  定义何时可以安全部署配置，以及部署失败时需执行什么操作。您可以指定是否等待组件报告可以更新。如果设备应用的部署失败，您还可以指定是否将设备还原至之前的配置。
+ **停止配置**

  定义何时以及如何停止部署。如果符合您定义的标准，部署就会停止并失败。例如，您可以将部署配置为：在最少数量的设备收到部署后，若仍有一定比例的设备未能应用该部署，则部署将停止。
+ **推出配置**

  定义部署推送至目标设备的速度。您可以配置一个具有最小和最大速率范围的指数增长速率。
+ **超时配置**

  定义每台设备应用部署的最长时间。如果设备超过了您指定的持续时间，则该设备将无法应用部署。

**重要**  
自定义组件可以在 S3 存储桶中定义构件。当 AWS IoT Greengrass 核心软件部署组件时，它会从中下载该组件的工件。 AWS 云默认情况下，核心设备角色不允许访问 S3 存储桶。要部署在 S3 存储桶中定义构件的自定义组件，核心设备角色必须授予从该存储桶下载构件的权限。有关更多信息，请参阅 [允许访问 S3 存储桶中的组件构件](device-service-role.md#device-service-role-access-s3-bucket)。

**Topics**
+ [核心设备部署](#core-device-deployments)
+ [平台依赖关系解析](#platform-dependency-resolution)
+ [组件依赖关系解析](#component-dependency-resolution)
+ [从事物组中移除设备](#thing-group-removal-behavior)
+ [部署](#deployments)
+ [部署选项](#deployment-options)
+ [创建部署](create-deployments.md)
+ [创建子部署](create-subdeployments.md)
+ [修改部署](revise-deployments.md)
+ [取消部署](cancel-deployments.md)
+ [检查部署状态](check-deployment-status.md)