金像解剖学 - AWS 规范性指导

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

金像解剖学

AWS IoT Greengrass 大规模制造的核心设备通常是嵌入式 Linux 设备,它们的 Linux 发行版是使用 Yoct o 等工具构建的。通常,正如 Meta AWS 项目所证明的那样,Greengrass 边缘运行时会嵌入到发行版中。

此类设备通常将其文件系统组织成多个分区。本指南使用黄金图像作为包罗万象的术语。您的设备可能有几张金色镜像,用于刷新各个分区。

您的黄金映像可能包含设备的整个文件系统或仅包含其中的一部分。本指南重点介绍文件系统中需要考虑的部分 AWS IoT Greengrass,但没有规定如何更广泛地组装图像。

Greengrass 目录树

要了解本指南中讨论的黄金图像方法,请查看下表所示的 Greengrass 目录树的结构。

目录

描述

alts

启动参数和指向当前处于活动状态的 Greengrass 核心版本的符号链接。

bin

已安装二进制文件(如果安装了该组件,则为 Greengrass CLI 二进制文件)。这个目录通常是空的。

cli_ipc_info

适用于 Greengrass CLI 进程间通信 (IPC) 的 Scratchpad。如果您尚未安装 Greengrass CLI,则此目录为空。

config

所有 Greengrass 配置,包括组件配置。

deployments

用于管理部署和回滚状态的数据。

logs

核心和其他组件的日志文件。

packages

所有组件的工件和配方。

plugins

用于存放手动安装类型的aws.greengrass.plugin组件。否则,此目录不包含任何数据。

telemetry

Greengrass 使用 Scratchpad 来汇总准备发布的遥测数据。

work

用于组件的 Scratchpad。

logstelemetry、和work目录仅包含临时数据。它们不需要包含在金色图像中,因此如果您想最小化图像的大小,请省略它们。

Greengrass CLI 通常不安装在生产设备上,因此bincli_ipc_info和目录通常为空,通常不需要包含在黄金映像中。

只有在安装 Greengrass 时手动安装了插件(例如队列配置插件或自定义配置插件),该plugins目录才会包含数据。

deployments目录中的数据仅在部署正在进行时使用,因此在黄金映像中不需要这些数据。

因此altsconfigpackages目录最令人感兴趣。有时,如果您想最小化图像大小,这些是唯一需要包含在黄金映像中的 Greengrass 目录。

软件包目录的内容

packages 目录有三个子目录,如下表所示。

子目录

描述

artifacts

Greengrass 在部署期间下载的压缩组件工件。

artifacts-unarchived

对于.zip存档的工件,此目录包含相同的工件,但它们已解压缩,以便组件可以使用工件内容。

recipes

组件配方文件。

构件

以下示例树形列表packages/artifacts显示了工件的存储方式。

user@machine:~$ sudo tree /greengrass/v2/packages/artifacts /greengrass/v2/packages/artifacts ├── aws.greengrass.DockerApplicationManager ├── aws.greengrass.LogManager │ └── 2.3.7 │ └── aws.greengrass.LogManager.jar ├── aws.greengrass.Nucleus │ └── 2.12.6 │ └── aws.greengrass.nucleus.zip ├── aws.greengrass.SecretManager │ └── 2.1.8 │ └── aws.greengrass.SecretManager.jar ├── aws.greengrass.SecureTunneling │ └── 1.0.19 │ └── GreengrassV2SecureTunnelingComponent-1.0-all.jar ├── aws.greengrass.labs.CertificateRotator │ └── 1.1.0 │ └── certificate-rotator.zip ├── aws.greengrass.labs.HomeAssistant │ └── 1.0.0 │ └── home-assistant.zip └── aws.greengrass.telemetry.NucleusEmitter └── 1.0.8 └── aws.greengrass.telemetry.NucleusEmitter.jar 15 directories, 7 files

神器-未存档

以下示例树形列表packages/artifacts-unarchived显示了从.zip文件中提取的工件。

user@machine:~$ sudo tree /greengrass/v2/packages/artifacts-unarchived /greengrass/v2/packages/artifacts-unarchived ├── aws.greengrass.Nucleus │ └── 2.12.6 │ └── aws.greengrass.nucleus │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── THIRD-PARTY-LICENSES │ ├── bin │ │ ├── greengrass.exe │ │ ├── greengrass.service │ │ ├── greengrass.service.procd.template │ │ ├── greengrass.service.template │ │ ├── greengrass.xml.template │ │ ├── loader │ │ └── loader.cmd │ ├── conf │ │ └── recipe.yaml │ └── lib │ └── Greengrass.jar ├── aws.greengrass.SecureTunneling │ └── 1.0.19 ├── aws.greengrass.labs.CertificateRotator │ └── 1.1.0 │ └── certificate-rotator │ ├── __pycache__ │ │ ├── config.cpython-310.pyc │ │ ├── config.cpython-311.pyc │ │ ├── effective_config.cpython-310.pyc │ │ ├── effective_config.cpython-311.pyc │ │ ├── main.cpython-311.pyc │ │ ├── pki.cpython-310.pyc │ │ ├── pki.cpython-311.pyc │ │ ├── pki_file.cpython-310.pyc │ │ ├── pki_file.cpython-311.pyc │ │ ├── pki_hsm.cpython-310.pyc │ │ ├── pki_hsm.cpython-311.pyc │ │ ├── pubsub.cpython-310.pyc │ │ ├── pubsub.cpython-311.pyc │ │ ├── state.cpython-310.pyc │ │ ├── state.cpython-311.pyc │ │ ├── state_committing_certificate.cpython-310.pyc │ │ ├── state_committing_certificate.cpython-311.pyc │ │ ├── state_creating_certificate.cpython-310.pyc │ │ ├── state_creating_certificate.cpython-311.pyc │ │ ├── state_getting_job.cpython-310.pyc │ │ ├── state_getting_job.cpython-311.pyc │ │ ├── state_idle.cpython-310.pyc │ │ ├── state_idle.cpython-311.pyc │ │ ├── state_machine.cpython-310.pyc │ │ ├── state_machine.cpython-311.pyc │ │ ├── state_updating_job.cpython-310.pyc │ │ ├── state_updating_job.cpython-311.pyc │ │ ├── topic_base.cpython-310.pyc │ │ └── topic_base.cpython-311.pyc │ ├── config.py │ ├── effective_config.py │ ├── main.py │ ├── pki.py │ ├── pki_file.py │ ├── pki_hsm.py │ ├── pubsub.py │ ├── requirements.txt │ ├── scripts │ │ └── run.cmd │ ├── state.py │ ├── state_committing_certificate.py │ ├── state_creating_certificate.py │ ├── state_getting_job.py │ ├── state_idle.py │ ├── state_machine.py │ ├── state_updating_job.py │ └── topic_base.py └── aws.greengrass.labs.HomeAssistant └── 1.0.0 └── home-assistant ├── config │ ├── automations.yaml │ ├── configuration.yaml │ ├── groups.yaml │ ├── scenes.yaml │ └── scripts.yaml ├── docker-compose.yml ├── install.py └── secret.py 17 directories, 67 files

请注意,该alts目录链接到中的 Nucleus .jar 文件。packages/artifacts-unarchived例如:

user@machine:~$ sudo ls -l /greengrass/v2/alts/init total 8 lrwxrwxrwx 1 root root 97 Jun 27 08:12 distro -> /greengrass/v2/packages/artifacts-unarchived/aws.greengrass.Nucleus/2.12.6/aws.greengrass.nucleus -rw-r--r-- 1 root root 16 Jun 27 07:07 launch.params

因此,packages/artifacts-unarchived必须包含在您的金像中。

recipes

以下示例树形列表packages/recipes显示了食谱的存储方式。如清单所示,配方与摘要一起存储,以帮助 Greengrass 在收到部署时确定它是否已经有正确的文件。这种高度特定的格式使得撰写黄金图像变得困难。因此,为黄金设备拍摄快照是创建黄金映像的推荐方法。

user@machine:~$ sudo tree /greengrass/v2/packages/recipes /greengrass/v2/packages/recipes ├── 0ya1warrMfzlq5PUTvOgfHOununru_xCLUFACECM_R0@2.3.7.metadata.json ├── 0ya1warrMfzlq5PUTvOgfHOununru_xCLUFACECM_R0@2.3.7.recipe.yaml ├── 89r1-ak7xPauDt4O7EG03sSXVUO8ysdHTk-YdF0NAAc@2.12.6.metadata.json ├── 89r1-ak7xPauDt4O7EG03sSXVUO8ysdHTk-YdF0NAAc@2.12.6.recipe.yaml ├── VAZ-Grqe5g43yO7UtasQOR5jcQGILgPeRZQhVikLd9o@1.0.0.metadata.json ├── VAZ-Grqe5g43yO7UtasQOR5jcQGILgPeRZQhVikLd9o@1.0.0.recipe.yaml ├── ViMYPYs99-AzSt1gL2L2YD5P7sIN-yEhy23wWJK_JN8@1.0.8.metadata.json ├── ViMYPYs99-AzSt1gL2L2YD5P7sIN-yEhy23wWJK_JN8@1.0.8.recipe.yaml ├── _1hT2A6X0ZYtB_CfI_ZUOEMDV96DfQVkSmZh2bbGYXg@1.0.19.metadata.json ├── _1hT2A6X0ZYtB_CfI_ZUOEMDV96DfQVkSmZh2bbGYXg@1.0.19.recipe.yaml ├── gQWwM7MSL2kOsBADU9bOQJ1QqO8ZI3hqpbKT5Bv4Ijk@1.1.0.metadata.json ├── gQWwM7MSL2kOsBADU9bOQJ1QqO8ZI3hqpbKT5Bv4Ijk@1.1.0.recipe.yaml ├── j_j5Seyy01FOcIh95nBFy4HYf8P1kT-jW_nmV18ldbk@2.1.8.metadata.json └── j_j5Seyy01FOcIh95nBFy4HYf8P1kT-jW_nmV18ldbk@2.1.8.recipe.yaml 0 directories, 14 files

系统服务

如果 Greengrass 作为系统服务安装(通常用于嵌入式 Linux 设备),则黄金映像还必须包含包含启动脚本的目录。systemd

Docker 映像

如果您的设备使用以 Docker 镜像为工件的 AWS IoT Greengrass 组件,则这些构件将位于 Greengrass 目录树之外。因此,您需要在黄金映像中包含黄金设备的 Docker 镜像注册表。此注册表通常存储在/var/lib/docker

或者,您可以使用 Docker 命令复制存储在您的黄金设备上的 Docker 镜像,然后将这些 Docker 镜像加载到生产线上的每台设备上。通常,随着 Docker 镜像数量的增加,此方法速度较慢且可扩展性会降低。

密文

如果您的设备使用密钥管理器组件来同步来自的密钥 AWS Secrets Manager,则这些密钥将存储在您的黄金设备的 Greengrass 目录树中的config/config.tlog文件中。例如:

{"TS":1718878001465, "TP":["services","aws.greengrass.SecretManager","runtime","secretResponse"], "W":"changed", "V":"{\"secrets\":[ { \"arn\":\"arn:aws:secretsmanager:us-east-1:111122223333:secret:greengrass-home-assistant-KIzJfZ\", \"name\":\"greengrass-home-assistant\", \"versionId\":\"8e481177-9250-4458-9f1f-3690d28e4ae9\", \"encryptedSecretString\":\"AgV4j+We ... A7QjdE1w==\", \"versionStages\":[\"AWSCURRENT\"], \"createdDate\":1660648425915 } ] } "}

这些机密也存储在相应的config/effectiveConfig.yaml文件中:

aws.greengrass.SecretManager: componentType: "PLUGIN" configuration: cloudSecrets: - arn: "arn:aws:secretsmanager:us-east-1:111122223333:secret:greengrass-home-assistant-KIzJfZ" dependencies: - "aws.greengrass.Nucleus:SOFT" lifecycle: {} runtime: secretResponse: "{\"secrets\":[{\"arn\":\"arn:aws:secretsmanager:us-east-1:111122223333:secret:greengrass-home-assistant-KIzJfZ\"\ ,\"name\":\"greengrass-home-assistant\",\"versionId\":\"8e481177-9250-4458-9f1f-3690d28e4ae9\"\ ,\"encryptedSecretString\":\"AgV4Rpc9 ... MYeVALYQ==\"\ ,\"versionStages\":[\"AWSCURRENT\"],\"createdDate\":1660648425915}]}" version: "2.1.8"

即使您在黄金映像中包含该config目录,也请务必记住,G reengrass 秘密管理器组件会使用黄金设备的私钥对密钥进行加密。由于每台设备都有唯一的私钥,因此您的生产设备无法解密由您的黄金设备加密的密钥。

因此,我们建议您从黄金映像中删除加密机密,以防止您的生产设备错误地解密黄金设备机密。在设备首次与云通信之前,当磁盘上不存在密钥时,您的应用程序组件应该可以正常运行,或者至少可以正常运行。

当机密成为硬性要求时

如果您的组织要求生产设备在制造过程中填充机密,则您的生产线需要一个脚本或程序来复制密钥管理器组件的行为,以便在每台生产设备上填充机密。我们不推荐这种方法,因为它很复杂,而且你的秘密有可能在你的制作节目站以明文形式短暂保存。