【Part4】ラズパイにLambda関数をデプロイする
AWSでエッジコンピューティング環境を作る
Part4です。Greengrassの環境を構築できていない方はPart3からどうぞ
【Part3】AWSでエッジコンピューティング環境を作る(Lambda設定編)
ラズパイにGreengrass Coreを載せ、そこにデプロイするLambda関数の作成までできました。いよいよ実際にクラウド上から遠隔でデプロイしましょう(On The Air アップデートとか言うらしいです)。
Greengrassの各機能
しかし、まだ何ができるかしっくり来ていない方のほうが多いと思います。
AWS IoT Greengrass グループ
実際にエッジに反映させたいことは関数の他に、どういったリソースを使いたいか、AWSのなんのサービスにつなぐか、メッセージのやり取りはどうやって行うかなど、色々あるわけです。下図のように、これらをまとめて・セキュアに管理できるのがGreengrassの良いところです。
実は、Part2の設定で、すでにCoreの設定が完了しています。証明書関係をラズパイに転送したと思いますが、それがGreengrassとラズパイを対応付けるCoreの設定で、証明書を通じてセキュアな通信を保証しています。
今回は、この図の中でもLambdaとサブスクリプションを触ります。Greengrassで設定したものを、ラズパイにデプロイして"Hello World"のやり取りをするところまでやっていきましょう
Greengrass : Lambdaの設定
まず、Part2で作成した、AWS IoT Greengrassのグループを選択し、"Lambda"を選びます。
今回はPart3で作ったLambdaを使うので、"既存のLambda"を選択しましょう。
先程作ったLambda関数と、それに付随して作ったエイリアスを選択します。
これでGreengrass CoreにLambdaがひも付きます。
さて、紐付けたLambdaの状態では、Lambdaのライフサイクルはオンデマンドになっています。2つの違いは公式ページ(Greengrass Lambda 関数のライフサイクル設定)に詳しく書いていますが、
オンデマンド : 関数実行のたびにコンテナを作り、実行終了時に破棄される
無制限に稼働 : 一度作られた関数実行用のコンテナがずっと残る
両者の違いはカウンター(たとえば、AWS IoTにパブリッシュした数を数える)などを考えるとわかりやすくて、オンデマンドはコンテナが再作成された時点でカウンターが0にリセットされる一方で、無制限に稼働する場合は、エッジ端末が再起動するまではカウンターは増え続けるというイメージです。
Greengrass : Subscriptionの設定
GreengrassとLambdaの紐付けが終わったら、次はサブスクリプションの設定です。サブスクリプションとは、ざっくりいうと、AWS IoTや他のサービス、他のGreengrass Core端末と、メッセージのやり取りをする決まりみたいなものです。受け手と送り手のトピックが一致すると、送受信ができるようになります。
Greengrass groupのメニューからサブスクリプションを選択しましょう。
送り手(ソース)と、受け手(ターゲット)を決めます。今回はLambdaからメッセージを送るようになっているので、Lambda⇨AWS IoTです。
次に、トピックを決めます。
これでひとまずのサブスクリプションの定義は完了です。後で少し説明しますが、AWS IoT⇨Lambdaの方向にもメッセージを送る事はできるので、双方向の通信が可能です。
デプロイする
コレまでで、下記の設定が完了しました。
・Core (デバイス登録、証明書関連)
・Lambda (関数関連)
・サブスクリプション (メッセージ関連)
いよいよ、デプロイです!デプロイ前に、ラズパイ上のgreengrassdがきちんと起動しているかどうかをチェックしておきましょう。じゃないと、永遠にデプロイ実行中で止まります。
下図のようにアクション⇨デプロイと押すと、今まで設定したものをラズパイ上に反映してくれるわけです。
デプロイの成功/失敗は下図のように履歴で表示されます
実際、関数が上手く実行され、メッセージが届いているかを、AWS IoTのテストサービス上で確認することができます。
この設定をして、下記のようなメッセージが5秒おきに届いていれば成功です。
これにて、無事デプロイメントが完了です!
【応用】双方向のコミュニケーションにしてみる
Lambdaのハンドラー内に実行関数を書き、上記のサブスクリプションに加え、AWS IoT⇨Lambdaへのサブスクリプションも記述すると、トピックを受けた時点でラズパイ内にデプロイした関数が発火、IoTにデータを送信できるようになります。
参考までに、双方向向けのLambda関数も貼っておきます。greengrassHelloWorld.pyをこれに置き換えて設定します。
#
# Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
import greengrasssdk
import platform
import time
import json
# Creating a greengrass core sdk client
client = greengrasssdk.client('iot-data')
# Retrieving platform information to send from Greengrass Core
my_platform = platform.platform()
# Counter to keep track of invocations of the function_handler
my_counter = 0
def function_handler(event, context):
global my_counter
my_counter = my_counter + 1
if not my_platform:
client.publish(
topic='hello/world/counter',
payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core. Invocation Count: {}'.format(my_counter)})
)
else:
client.publish(
topic='hello/world/counter',
payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core running on platform: {}. Invocation Count: {}'
.format(my_platform, my_counter)})
)
time.sleep(20)
return
※実は先程設定した、オンデマンドと、長い存続期間によってAWS IoTで受けるcounterの値が変わってきます。コンテナのライフサイクルの関係でそうなっているので、試して違いを実感してみてください。
デバッグのコツ
さて、今回はコピペなので、基本的にうまくいくと思いますが、実際に関数を触っているとそういうわけにもいかず、エラーが出るとデバッグしなければいけません。AWS IoT上にデータが上手くあがっていなかったり、なにか異変がある場合、クラウド上のLambdaとは違うので、実行結果を見るにはラズパイ内に入って確認するしかありません。異変がある場合、まずデプロイされているか、そして正常に実行されているかどうかを確認しましょう
・デプロイされているかの確認。下記フォルダ内に実行するLambda関数の名前のログがある
$ sudo ls /greengrass/ggc/var/log/user/{region名}/{アカウントID}/
なければデプロイが上手くいっていない可能性が高い。あれば、実行時エラーの可能性が高い。実行時ログの確認は下記
$ sudo tail -f /greengrass/ggc/var/log/user/{region名}/{アカウントID}/Greengrass_HelloWorld.log
まとめ
今回までで、クラウドからエッジに関数をデプロイすることができました!これにより、できることがグッと広がってきます。
次回は、実際にGETしたデータを貯める方法についてまとめていきます。ではでは。
Part3. Lambda設定編
Part5. S3転送編
サポートいただけると励みになります! よろしくおねがいします!!