Azure IoT Edgeを触って Azure Functions を触って見た。そもそもエッジ側で Functions が動いて何が嬉しいの?ぐらいから考える必要がある。
1. Install
IoT Hub 自体はポータルから作ればいいので、まずはでデバイスのエミューレータを作る。サンプルにしたがって、今回は、Ubuntu 16.04 の端末を Azure 上に展開してインストールします。この程度なら、Free プランで十分ですが、今後の実験のため Standard
にしておきます。
1.1. 前提条件
前提としては、Python 2.7 と Docker がインストールされていることのようだ。あとpip も使う。ガイドにはないのだが、最初下記のエラーがでて動かなかった。最初にセットアップした端末のみ動いた。なんでだろうと思っていたが、どうやら、docker の17.11
が現在のバージョンではうまくいかなかった模様。詳細は、docker 17.11.0 doesn't seem to work by KeyNotFoundException #430でシェアしておいた。
1. device でのインストール
1.1. Docker のインストール
様々なライブラリをインストールするのが面倒なので、Docker の公式にもある get.docker.com
で環境を構築してダウングレードしている。
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo apt-get remove docker-ce
sudo apt-get install docker-ce=17.09.0~ce-0~ubuntu
ちなみに、この過程で覚えた apt-get
のインストール可能なバージョンを見つけるためのコマンド。
sudo apt-cache showpkg docker-ce
1.2. pip のインストール
Ubuntu には、python 2.7 が既に入っている。
sudo apt-get install python-pip -y
1.3. IoT Hub の設定
ここで、先に、IoT Hube にデバイスの設定をする必要がある。これ面倒なので、自動化の方法もあると思うが、まずは手動で。
device に名前をつけて登録します。IoT Hub のポータルから。IoT Edge を選択し、Add IoT Edge device を選択する。

クリックしたら、デバイスの名前をつけます。

Connection String を取得しておきます。次以降で使います。

これで設定はオッケーです。
デバイス側の設定
デバイス側に、IoT Edgeをインストールします。
sudo pip install -U azure-iot-edge-runtime-ctl
先ほどの Connection String を使って、次のコマンドをを実施します。これにより、設定がなされます。
$ sudo iotedgectl setup --connection-string "YOUR_CONNECTION_STRING_HERE" --auto-cert-gen-force-no-passwords
INFO: Config directory does not exist.Creating directory: /etc/azure-iot-edge
INFO: Generating self signed certificates at: /var/lib/azure-iot-edge/certs
INFO: The runtime configuration file /etc/azure-iot-edge/config.json was updated with the setup options.
INFO: Executing 'setup'
INFO: Uninstalling all modules.
INFO: Stopping containers by label: net.azure-devices.edge.owner=Microsoft.Azure.Devices.Edge.Agent
INFO: Removing containers by label: net.azure-devices.edge.owner=Microsoft.Azure.Devices.Edge.Agent
Runtime setup successfully.
Using configuration:
Schema Version: 1
Connection String: HostName=iothubexp.azure-devices.net;DeviceId=device01;SharedAccessKey=******
Home Directory: /var/lib/azure-iot-edge
Hostname: device01
Log Level: info
Security Option: selfSigned
Force No Passwords: True
Certificate Subject:
countryCode: US, state: Washington, locality: Redmond
organization: Default Edge Organization, organizationUnit: Edge Unit, commonName: Edge Device CA
Deployment Type: docker
Docker Engine URI: unix:///var/run/docker.sock
Edge Agent Image: microsoft/azureiotedge-agent:1.0-preview
Registries:
Logging Driver: json-file
max-size: 10m
Use 'iotedgectl start' to start the runtime.
このコマンドを実行することによって、/etc/azure-iot-edge/
にconfig.json
が書かれます。/var/lib/azure-iot-edge
にホームディレクトリが作られて、その中に、module
と certs
が置かれています。config.json
の中では、IoT Edge のエージェントが入っている Dockerイメージの名前、IoT Hub で作成した、デバイスの Connection String 、セキュリティの設定が書かれています。
IoT Edge エージェントの実行
デバイス側で
sudo iotedgectl start
しばし待ちます。
最初に実行した時は、ログを見てもこんな感じ。 エラー出ているけど、これはまだモジュールを登録していないから。
$ sudo docker logs b6
2017-11-29 07:02:04 [INF] - Starting module management agent.
2017-11-29 07:02:04 [INF] - Version - 1.0.7516610 (03c94f85d0833a861a43c669842f0817924911d5)
2017-11-29 07:02:04 [INF] -
█████╗ ███████╗██╗ ██╗██████╗ ███████╗
██╔══██╗╚══███╔╝██║ ██║██╔══██╗██╔════╝
███████║ ███╔╝ ██║ ██║██████╔╝█████╗
██╔══██║ ███╔╝ ██║ ██║██╔══██╗██╔══╝
██║ ██║███████╗╚██████╔╝██║ ██║███████╗
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
██╗ ██████╗ ████████╗ ███████╗██████╗ ██████╗ ███████╗
██║██╔═══██╗╚══██╔══╝ ██╔════╝██╔══██╗██╔════╝ ██╔════╝
██║██║ ██║ ██║ █████╗ ██║ ██║██║ ███╗█████╗
██║██║ ██║ ██║ ██╔══╝ ██║ ██║██║ ██║██╔══╝
██║╚██████╔╝ ██║ ███████╗██████╔╝╚██████╔╝███████╗
╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═════╝ ╚═════╝ ╚══════╝
2017-11-29 07:02:04 [INF] - Edge agent attempting to connect to IoT Hub via AMQP...
2017-11-29 07:02:05 [INF] - Edge agent connected to IoT Hub via AMQP.
2017-11-29 07:02:05 [INF] - Edge agent config backup created here - backup.json
2017-11-29 07:02:05 [INF] - Deployment config in edge agent's desired properties is empty.
2017-11-29 07:02:05 [INF] - Using in-memory store
2017-11-29 07:02:05 [ERR] - Error refreshing edge agent configuration from twin.
Microsoft.Azure.Devices.Edge.Agent.Core.ConfigSources.ConfigEmptyException: This device has an empty configuration for the edge agent. Please set a deployment manifest.
ポータルで街灯のデバイスが、Connected になっていればOK.
ちなみに、失敗するケースもある。このエラーが出たら要注意。
2017-11-29 06:58:31 [ERR] - Error refreshing edge agent configuration from twin.
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at Microsoft.Azure.Devices.Client.DeviceClient.<>c__DisplayClass81_0.<ApplyTimeoutTwin>b__2(Task`1 t)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
ポータルもこんな感じ。

Docker のバージョンが、17.11 ではないか確認します(私は、17.09)バージョンも良さげなら一旦 docker image を消してから、再度先ほどのコンフィグをやり直して起動し直すといい感じ。
$ sudo iotedgectl stop
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
microsoft/azureiotedge-agent 1.0-preview 2531226ddfa5 6 days ago 281MB
$ sudo docker rmi -f 2531226ddfa5
Untagged: microsoft/azureiotedge-agent:1.0-preview
Untagged: microsoft/azureiotedge-agent@sha256:0f3a9c3ff461eb083adcc0d2edc66872594ff12bb2443368bd3d1f7f12e4eacf
Deleted: sha256:2531226ddfa5ff328b4973daab55b2292d1f53ebe104321a4c5b66d41a4e2378
$ sudo iotedgectl setup --connection-string "HostName=iothubexp.azure-devices.net;DeviceId=device02;SharedAccessKey=EDeAWZFq2ZJFp48aEuJXhYzcjtIE9602NCyYl/ZzdrQ=" --auto-cert-gen-force-no-passwords
$ sudo iotedgectl start
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6601c65fd6a0 microsoft/azureiotedge-agent:1.0-preview "/usr/bin/dotnet M..." 5 seconds ago Up 4 seconds edgeAgent
$ sudo docker logs 660
:
017-11-29 07:12:39 [ERR] - Error refreshing edge agent configuration from twin.
Microsoft.Azure.Devices.Edge.Agent.Core.ConfigSources.ConfigEmptyException: This device has an empty configuration for the edge agent. Please set a deployment manifest.
いい時のログが出ていればOK. ポータルでConnected になってたら完了。
IoT Hub からモジュールのインストール
さて、ここからが楽しいところです。IoTHub からモジュールをインストールして見ます。
デバイスのところから、Set Module を選択
Azure IoT Edge Module を選択
下記のモジュールは、デバイスのサンプルデータを送信するモジュールです。次の3つを設定して、Save
指示に従っていると、データが来ています。
デバイス側に行くと、今指定したデバイスが動いているのが確認できます。
$ sudo apt-get install watch
$ sudo watch docker ps
CONTAINER ID IMAGE
COMMAND CREATED STATUS PORTS
NAMES
b527ed753f13 microsoft/azureiotedge-hub:1.0-preview
"scripts/linux/sta..." 55 seconds ago Up 53 seconds 0.0.0.0:4
43->443/tcp, 0.0.0.0:8883->8883/tcp edgeHub
1c37e121fa83 microsoft/azureiotedge-simulated-temperature-sensor:1.0-prev
iew "/usr/bin/dotnet S..." 55 seconds ago Up 54 seconds
tempSensor
b65fd9bd76d0 microsoft/azureiotedge-agent:1.0-preview
"/usr/bin/dotnet M..." 19 minutes ago Up 19 minutes
edgeAgent
デバイス側でログが見れます。データを送っていますね。
$ sudo docker logs -f tempSensor
Added Cert: /mnt/edgemodule/edge-device-ca.cert.pem
11/29/2017 07:29:14> Sending message: 1, Body: [{"machine":{"temperature":21.745038762919158,"pressure":1.0848778337502838},"ambient":{"temperature":20.537994246481915,"humidity":24},"timeCreated":"2017-11-29T07:29:14.7214584Z"}]
11/29/2017 07:29:20> Sending message: 2, Body: [{"machine":{"temperature":22.884630813675297,"pressure":1.2147047762414895},"ambient":{"temperature":21.150602854625603,"humidity":25},"timeCreated":"2017-11-29T07:29:20.100425Z"}]
11/29/2017 07:29:25> Sending message: 3, Body: [{"machine":{"temperature":23.150549603114165,"pressure":1.2449993218737656},"ambient":{"temperature":21.1856078853298,"humidity":25},"timeCreated":"2017-11-29T07:29:25.1010247Z"}]
次回は、IoT Edge 側に送られたデータをみる手段がないので、IoT Edge 側の Azure Functions を作るのと、Azure Functions を使って、CosmosDB にぶち込んで見ましょう。