亚马逊AWS官方博客

借助 AWS IoT Greengrass Docker Application Deployment 连接器将容器应用部署到 IoT 边缘

AWS IoT Greengrass 是将云功能扩展到本地设备的软件。这使得设备可以更靠近信息源来收集和分析数据,自主响应本地事件,同时在本地网络上彼此安全地通信。AWS IoT Greengrass 开发人员可以使用 AWS Lambda 函数和预构建的连接器来创建无服务器应用程序,这些应用程序将部署到设备上以进行本地执行。
AWS IoT Greengrass 近期发布了一个新特性, 使得在 AWS IoT Greengrass Core 上运行 Docker 映像更容易。Docker Application Deployment连接器使用 Docker Compose 从 docker-compose.yml 文件启动多容器 Docker 应用程序。具体而言,连接器运行 docker-compose 命令来管理单个核心设备上的 Docker 容器。连接器可以访问存储在 Docker 容器注册表中的 Docker 映像,包括 Amazon Elastic Container Registry (Amazon ECR)、Docker 中心和私有 Docker 信任的Registry.
通过使用Greengrass Docker Application Deployment连接器,你可以将在企业应用直接封装成容器部署到IoT边缘供设备调用,也可以将机器学习模型容器化后在边缘测提供推理等功能.同时企业也可以通过在Registry中更新容器镜像并结合版本更新的功能快速更新这些边缘设备上的应用.
下面我们通过一个简单示例展示如何将一个应用(NodeRed)容器化部署到AWS IoT Greengrass 核心中并使用连接器访问

先决条件

  • 此功能需要AWS IoT Greengrass 核心软件 v1.10 以上版本
  • Greengrass 核心中已安装Python3.7及以上版本,并已添加到 PATH 环境变量
  • Greengrass 核心上已安装 Docker Engine v1.9.1 或更高版本
  • Greengrass 核心上已安装 Docker Compose.
  • AWS Cli具有S3,ECR,IoT等相应服务使用权限

构建运行环境

1.在边缘设备中部署AWS IoT GreenGrass 核心软件.

创建AWS IoT GreenGrass组和部署AWS IoT GreenGrass 核心软件过程可以参考https://docs.thinkwithwp.com/zh_cn/greengrass/latest/developerguide/gg-core.html
如在创建和部署过程中发现问题请参阅 AWS IoT Greengrass 文档中的故障排除部分。

2.在边缘设备中安装Python 3.7及以上版本.

使用

sudo yum install python37

在设备上安装Python3.7版本,使用

which python3 和 echo $PATH

检查Python3 是否在PATH变量中.

3.在边缘设备中安装Docker Engine v1.9.1.

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce

安装完成后启动docker服务并配置为ec2-user或其他用户增加运行权限

sudo systemctl start docker
systemctl enable docker.service
sudo usermod -a -G docker ec2-user

使用

docker info 确认Docker 的版本及安装情况

4.在边缘设备中安装 Docker Compose.

使用如下命令进行安装

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

使用如下命令检查docker-compose的版本和安装情况

docker-compose version

构建容器应用

1.构建容器镜像
容器镜像可以通过Docker file进行创建也可以直接通过Dockerhub等公共仓库拉取镜像
使用Docker file 创建Image的方法可以参考Docker官方文档
https://docs.docker.com/engine/reference/commandline/image_build/
此教程中我们直接从Docker拉取镜像
使用命令

docker pull nodered/node-red

拉取NodeRed官方镜像到本地并使用docker images命令确认镜像在本地

 

 

2.将容器进行推送至Amazon ECR

  • 创建ECR 存储库
    使用如下命令创建存储库
aws ecr create-repository --repository-name ggdocker
  • 使用如下命令将本地镜像标记并上传至 ECR库中
`aws ecr get-login --no-include-email`
docker tag  Imageid accountid.dkr.ecr.ap-southeast-1.amazonaws.com/ggdocker:latest
docker push accountid.dkr.ecr.ap-southeast-1.amazonaws.com/ggdocker:latest

认存储库中有对应镜像

 

 

 

 

 

同时记录AWS ECR 中Image URL路径
3.构建 Compose file
我们需要使用Compose 文件用于定义和运行多容器Docker 应用程序以及它们的配置。通过 Compose我们可以使用 YML 文件来配置应用程序需要的所有服务。
该教程中所使用到的Compose如下

version: "3.7"
services:
  node-red:
    image: imageid.dkr.ecr.ap-southeast-1.amazonaws.com/ggdocker:latest
    environment:
      - TZ=Europe/Amsterdam
    ports:
      - "1880:1880"
    networks:
      - node-red-net
    volumes:
      - node-red-data  

volumes:
  node-red-data:

networks:
  node-red-net:

将以上内容保存到Docker-compose-node-red.yml文件
并上传到一个S3存储桶中通过以上步骤我们完成了容器镜像及compose文件的的创建。

启用Docker Application Deployment连接器

在创建Docker Application Deployment连接器之前,我们需要确认创建的Greengrass组具有以下权限

  • 从S3存储桶中读取的权限(具有s3:GetObject)
    以下示例策略作为参考
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessToComposeFileS3Bucket",
            "Action": [
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::bucket-name/*"
        }
    ]
}
  • 从ECR中拉取Docker 镜像的权限
    以下示例策略作为参考:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGetEcrRepositories",
            "Effect": "Allow",
            "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage"
            ],
            "Resource": [
                "arn:aws:ecr:区域:account-id:repository/repository-name"
            ]
        },
        {
            "Sid": "AllowGetEcrAuthToken",
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}
  • 如果你的镜像来自私有存储库还需要私有存储库的访问权限
  • Cloudwatch日志的写入权限(便于排错,可选)

此外我们需要在核心设备上创建一个文件夹如myCompose用于存储Compose文件的本地副本,同时对于docker的执行用户需要有这个文件夹的读取和写入权限.

完成以上准备工作后,我们在创建好的Greengrass组中点击 Add connector创建连接器

 

 

 

 

 

 

 

 

选择Docker Application Deployment连接器

 

 

 

 

 

 

 

 

 

 

 

 

在步骤2中进行如下配置

 

 

 

 

 

 

 

 

 

 

 

 

  • Docker Compose file in S3 选择之前存放在S3桶中的Compose文件
  • Directory path for local Compose file 选择本地Compose文件副本存放路径
  • Docker user ID (optional) docker执行的用户UID,可以使id 命令查找(如root账号则是0),注意需要有访问本地Compose文件目录的权限
    点击ADD完成配置
    在Greengrass group中选择Deploy 进行部署,部署前请确认Greegrass服务已启动

 

 

 

 

 

 

 

 

 

等待部署完成

 

 

 

 

 

 

在核心设备中执行docker ps 可以看到连接器的容器应用已部署完成

 

 

我们可以使用浏览器快速验证容器是否部署成功并运行正常

 

 

 

 

 

与Docker Application Deployment连接器通信

AWS IoT Greengrass 支持 Greengrass 组件和 Docker 容器之间的以下通信通道:

  1. Greengrass Lambda 函数可以使用 REST API 与 Docker 容器中的进程进行通信。您可以在 Docker 容器中设置打开端口的服务器。 Lambda 函数可以在此端口上与容器进行通信。
  2. Docker 容器中的进程可以通过本地 Greengrass 消息代理交换 MQTT 消息。您可以将 Docker 容器设置为 Greengrass 组中的 Greengrass 设备,然后创建订阅以允许容器与组中的 Greengrass Lambda 函数、设备和其他连接器或与 AWS IoT 本地影子服务进行通信。
  3. Greengrass Lambda 函数可以更新共享文件以将信息传递给 Docker 容器。您可以使用 Compose 文件绑定装载 Docker 容器的共享文件路径。

更多信息可以参考 使用 Greengrass 连接器与服务和协议集成
https://docs.thinkwithwp.com/zh_cn/greengrass/latest/developerguide/connectors.html

本篇作者

王非

AWS解决方案架构师,负责基于AWS云计算方案的架构咨询和设计实现,同时致力于物联网服务的应用以及推广和推进企业服务迁移上云进程