2
2

More than 3 years have passed since last update.

Greengrass V2をDockerコンテナ内で実行させる(on Raspberry Pi)

Posted at

Greengrass V2が、Dockerコンテナ内での実行に対応したようですので試してみました。

Dockerイメージですが、V1はarmやarm64向けにも提供されていましたが、V2に関してはamd64向けのみの提供のようです。(そしてlatestタグがV2に向いているのでV1をlatestで使っている人はびっくりしていることでしょう)

Raspberry Pi(Raspberry Pi OS 32bit)上で、試してみました。

マネジメントコンソールでの設定

いつもながら、やることがたくさんあります。

モノの登録

マネジメントコンソールでIoT Coreの画面を開きます。
「単一のAWS IoT モノの登録」を選択。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (2).png

名前をつけます。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (3).png

「1-Click 証明書作成」を選択。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (4).png

証明書が作成されますので、全てダウンロードしておきます。ルートCAも取得しましょう。
「有効化」ボタンのクリックも忘れずに。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (5).png

ポリシーは後で追加しますので、まずはモノを登録してしまいましょう。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (6).png

IAMポリシー、ロールの作成

Greengrass V2は動作にIAMポリシーが必要なので作成します。
(画面キャプチャがなくてすいません)

IAMポリシー(GreengrassV2TokenExchangeRoleAccess)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:DescribeCertificate",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams",
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe",
                "iot:Receive",
                "s3:GetBucketLocation"
            ],
            "Resource": "*"
        }
    ]
}

IAMロールは、先程作成したGreengrassV2TokenExchangeRoleAccessポリシーをアタッチ。信頼関係はこんな感じです。

IAMロールの信頼関係(GreengrassV2TokenExchangeRole)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "credentials.iot.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IoTロール、ポリシーの設定

IoT Coreのマネジメントコンソールに戻ります。
「安全性」の中にある「ロールエイリアス」を選択。
作成ボタンを選択。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (11).png

エイリアス先のロールとして、先程作成したIAMロールを選択。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (12).png

次にIoTポリシーを作成。

「安全性」の中にある「ポリシー」を選択。

1つめはgreengrass-docker-on-pi-pilicy

greengrass-docker-on-pi-pilicy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive",
        "iot:Connect",
        "greengrass:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

アドバンストモードに切り替えて、JSONを貼り付けると楽ちんです。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (9).png

もう一つはGreengrassCoreTokenExchangeRoleAliasPolicy
先程作ったロールエイリアスを指定します。

GreengrassCoreTokenExchangeRoleAliasPolicy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:AssumeRoleWithCertificate",
      "Resource": "arn:aws:iot:ap-northeast-1:xxxxxxxxxxxx:rolealias/GreengrassCoreTokenExchangeRoleAlias"
    }
  ]
}

証明書にポリシーをアタッチ

管理-モノのメニューから対象のモノを選択
→セキュリティタブを選択
→証明書を選択
→アクション-ポリシーのアタッチを選択
→greengrass-docker-on-pi-pilicyポリシーとGreengrassCoreTokenExchangeRoleAliasPolicyポリシーを選択

エンドポイント情報の取得

二種類のエンドポイントが必要です。
マネジメントコンソール上からは取得できそうにないので、CloudShellで取得します。
あとで使うのでメモしておきましょう。

aws iot describe-endpoint --endpoint-type iot:Data-ATS
aws iot describe-endpoint --endpoint-type iot:CredentialProvider

Dockerイメージのビルド

この章の作業はRaspberry Pi上で行います。

DockerfileはGitHubに公開されているのでこれを参考にしましょう。
https://github.com/aws-greengrass/aws-greengrass-docker

git clone -b v2.1.0 https://github.com/aws-greengrass/aws-greengrass-docker.git

取得したファイルはこんな感じです。

$ tree 
.
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── docker-compose.yml
├── greengrass-2.1.0.zip.sha256
└── greengrass-entrypoint.sh

Dockerfileのベースイメージがamazonlinux:2なのですが、arm向けには提供されておらず、残念ながらこのままでは動きません。
今回はベースイメージをpython:3.8-busterにしてみました。
また、必要なパッケージをyumではなくapt-getでインストールするように変更しました。

Dockerfile
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

+FROM python:3.8-buster

# Author
LABEL maintainer="AWS IoT Greengrass"

# Replace the args to lock to a specific version
ARG GREENGRASS_RELEASE_VERSION=2.1.0
ARG GREENGRASS_ZIP_FILE=greengrass-${GREENGRASS_RELEASE_VERSION}.zip
ARG GREENGRASS_RELEASE_URI=https://d2s8p88vqu9w66.cloudfront.net/releases/${GREENGRASS_ZIP_FILE}
ARG GREENGRASS_ZIP_SHA256=${GREENGRASS_ZIP_FILE}.sha256

# Set up Greengrass v2 execution parameters
# TINI_KILL_PROCESS_GROUP allows forwarding SIGTERM to all PIDs in the PID group so Greengrass can exit gracefully
ENV TINI_KILL_PROCESS_GROUP=1 \ 
    GGC_ROOT_PATH=/greengrass/v2 \
    PROVISION=false \
    AWS_REGION=us-east-1 \
    THING_NAME=default_thing_name \
    THING_GROUP_NAME=default_thing_group_name \
    TES_ROLE_NAME=default_tes_role_name \
    TES_ROLE_ALIAS_NAME=default_tes_role_alias_name \
    COMPONENT_DEFAULT_USER=default_component_user \
    DEPLOY_DEV_TOOLS=false \
    INIT_CONFIG=default_init_config
RUN env

# Entrypoint script to install and run Greengrass
COPY "greengrass-entrypoint.sh" /
COPY "${GREENGRASS_ZIP_SHA256}" /

# Install Greengrass v2 dependencies

RUN apt-get update -y && apt-get upgrade -y && apt-get install -y tar unzip wget sudo procps openjdk-11-jre-headless && \
    wget $GREENGRASS_RELEASE_URI && sha256sum -c ${GREENGRASS_ZIP_SHA256} && \
    rm -rf /var/lib/apt/lists/* && \
    chmod +x /greengrass-entrypoint.sh && \
    mkdir -p /opt/greengrassv2 $GGC_ROOT_PATH && unzip $GREENGRASS_ZIP_FILE -d /opt/greengrassv2 && rm $GREENGRASS_ZIP_FILE && rm $GREENGRASS_ZIP_SHA256

ENTRYPOINT ["/greengrass-entrypoint.sh"]

ビルドします。

docker build -t aws-iot-greengrass:2.1.0 .

Docker Composeの準備

必要なファイルを準備します。
ディレクトリ構成はこんな感じになります。
証明書類は、このファイル名に変更の上、格納。

$ tree 
.
├── .env
├── docker-compose.yml
├── greengrass-v2-certs
│   ├── AmazonRootCA1.pem
│   ├── device.pem.crt
│   ├── private.pem.key
│   └── public.pem.key
└── greengrass-v2-config
    └── config.yaml
.env
GGC_ROOT_PATH=/greengrass/v2
AWS_REGION=ap-northeast-1
PROVISION=false
COMPONENT_DEFAULT_USER=ggc_user:ggc_group
DEPLOY_DEV_TOOLS=true
INIT_CONFIG=/tmp/config/config.yaml
docker-compose.yml
version: '3.7'

services:
  greengrass:
    init: true
    container_name: aws-iot-greengrass
    image: aws-iot-greengrass:2.1.0
    env_file:
      - .env
    volumes:
      - ./greengrass-v2-config:/tmp/config/:ro
      - ./greengrass-v2-certs:/tmp/certs:ro

config.yamlのエンドポイントは取得したものに変更。

greengrass-v2-config/config.yaml
---
system:
  certificateFilePath: "/tmp/certs/device.pem.crt"
  privateKeyPath: "/tmp/certs/private.pem.key"
  rootCaPath: "/tmp/certs/AmazonRootCA1.pem"
  rootpath: "/greengrass/v2"
  thingName: "greengrass-docker-on-pi"
services:
  aws.greengrass.Nucleus:
    componentType: "NUCLEUS"
    version: "2.1.0"
    configuration:
      awsRegion: "ap-northeast-1"
      iotRoleAlias: "GreengrassCoreTokenExchangeRoleAlias"
      iotDataEndpoint: "[iot:Data-ATSのエンドポイント]"
      iotCredEndpoint: "[iot:CredentialProviderのエンドポイント]"

起動

準備が整いました。長かった。

$ docker-compose up
Creating network "greengrass-on-docker_default" with the default driver
Creating aws-iot-greengrass ... done
Attaching to aws-iot-greengrass
aws-iot-greengrass | Installing Greengrass for the first time...
aws-iot-greengrass | Root user is already configured to execute commands as other users.
aws-iot-greengrass | Using specified init config file at /tmp/config/config.yaml
aws-iot-greengrass | Running Greengrass with the following options: -Droot=/greengrass/v2 -Dlog.store=FILE -Dlog.level= -jar /opt/greengrassv2/lib/Greengrass.jar --provision false --deploy-dev-tools true --aws-region ap-northeast-1 --start false --component-default-user ggc_user:ggc_group --init-config /tmp/config/config.yaml
aws-iot-greengrass | /greengrass-entrypoint.sh: 51: [: false: unexpected operator
aws-iot-greengrass | Creating user ggc_user 
aws-iot-greengrass | ggc_user created 
aws-iot-greengrass | Creating group ggc_group 
aws-iot-greengrass | ggc_group created 
aws-iot-greengrass | Added ggc_user to ggc_group 
aws-iot-greengrass | Nucleus start set to false, exiting...
aws-iot-greengrass | Making loader script executable...
aws-iot-greengrass | Starting Greengrass...
aws-iot-greengrass | + set +m
aws-iot-greengrass | + dirname /greengrass/v2/alts/current/distro/bin/loader
aws-iot-greengrass | + PWD=/greengrass/v2/alts/current/distro/bin
aws-iot-greengrass | + sigterm_received=0
aws-iot-greengrass | + cd /greengrass/v2/alts/current/distro/bin/../../../..
aws-iot-greengrass | + pwd
aws-iot-greengrass | + GG_ROOT=/greengrass/v2
aws-iot-greengrass | + echo Greengrass root: /greengrass/v2
aws-iot-greengrass | + LAUNCH_DIR=/greengrass/v2/alts/current
aws-iot-greengrass | + CONFIG_FILE=
aws-iot-greengrass | + is_directory_link /greengrass/v2/alts/new
aws-iot-greengrass | + [ -L /greengrass/v2/alts/new ]
aws-iot-greengrass | + is_directory_link /greengrass/v2/alts/broken
aws-iot-greengrass | + [ -L /greengrass/v2/alts/broken ]
aws-iot-greengrass | Greengrass root: /greengrass/v2
aws-iot-greengrass | + is_directory_link /greengrass/v2/alts/old
aws-iot-greengrass | + [ -L /greengrass/v2/alts/old ]
aws-iot-greengrass | + j=1
aws-iot-greengrass | + [ 1 -le 3 ]
aws-iot-greengrass | + [ 0 -eq 0 ]
aws-iot-greengrass | + launch_kernel
aws-iot-greengrass | + is_directory_link /greengrass/v2/alts/current
aws-iot-greengrass | + [ -L /greengrass/v2/alts/current ]
aws-iot-greengrass | + [ -d /greengrass/v2/alts/current ]
aws-iot-greengrass | + [ -f /greengrass/v2/alts/current/launch.params ]
aws-iot-greengrass | + cat /greengrass/v2/alts/current/launch.params
aws-iot-greengrass | + JVM_OPTIONS=-Dlog.level= -Dlog.store=FILE
aws-iot-greengrass | + JVM_OPTIONS=-Dlog.level= -Dlog.store=FILE -Droot=/greengrass/v2
aws-iot-greengrass | + OPTIONS=--setup-system-service false
aws-iot-greengrass | + [ ! -z ]
aws-iot-greengrass | + echo JVM options: -Dlog.level= -Dlog.store=FILE -Droot=/greengrass/v2
aws-iot-greengrass | + echoJVM options: -Dlog.level= -Dlog.store=FILE -Droot=/greengrass/v2
aws-iot-greengrass |  Nucleus options: --setup-system-service falseNucleus options: --setup-system-service false
aws-iot-greengrass | 
aws-iot-greengrass | + child_pid=
aws-iot-greengrass | + trap echo Received SIGTERM; sigterm_received=1; kill -TERM ${child_pid} TERM
aws-iot-greengrass | + child_pid=92
aws-iot-greengrass | + java -Dlog.store=FILE -Dlog.level= -Dlog.store=FILE -Droot=/greengrass/v2 -jar /greengrass/v2/alts/current/distro/lib/Greengrass.jar --setup-system-service false
aws-iot-greengrass | + wait 92
aws-iot-greengrass | Launching Nucleus...
aws-iot-greengrass | Launched Nucleus successfully.

マネジメントコンソールからも確認できました。

ap-northeast-1.console.aws.amazon.com_iot_home_region=ap-northeast-1(Laptop with MDPI screen) (19).png

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2