🐡

Menderで始める組み込みOTA 第11回 : 接続編3 : Jetson AGX Orinを接続

2022/08/30に公開

MenderはオープンソースベースのLinux向けOTA(Over the Air Update)ソリューションです。

Mender is a secure, risk tolerant and efficient over-the-air update manager. Remotely manage and deploy software updates to your IoT devices at scale, worldwide.

https://mender.io/

筆者の会社コードギアではこのたびご縁あってMenderの技術サポートを提供する機会を得ました。
この一連の記事ではMender OTAソリューションの技術的な側面を紹介します。


*Menderで始める組み込みOTA」記事インデックス

以下、Quickstart編

以下、接続編

はじめに

今回はNvidia社のJetsonシリーズより、Jetson AGX Orin 開発キット を mender.io に接続し、いくつかのOTAジョブを実行するまでをご紹介します。

Jetson AGX Orin はNvidia社の最新の組み込み向けプラットフォームで、Ubuntu 20.04 ベースのLinux を採用しています。そのため、menderソリューションを比較的簡単に実行可能です。この記事ではターゲットとしてJetson AGX Orin 開発キットを利用していますが。基本どのモデルでも同様の手順で利用可能と思われます。

ターゲットの確認

Jetsonシリーズは製品に利用するための「製品モジュール」と、主に開発に利用するための「開発キット」があり、搭載されているRAMサイズやEMMCメモリのサイズによりいくつかのバリエーションが存在します。今回はこの中で最初に発売された「開発キット」を利用します。

Jetson AGX Orin 開発者キットの主な仕様は以下です。

CPU : 12コア ARM Cortex A78
メモリ : 32GB
eMMC : 64GB
ネットワーク : 10Gb Ethernet x1
ディスプレイ : Dixplay Port 1.4 x1 (4K対応)

10Gbit Ethenetは普通のGigabit Hubでも利用可能です。Display Port は変換ケーブルを利用してHDMIモニタに出力することも可能ですが、新しめのHDMI 2.0対応のアクティブ式変換ケーブルを利用しないと映像が映らないことあります。

搭載されているOSは当初 Linux for Tegra (L4T) バージョン R34.1.0 でした。2022年8月現在、R35.1.0 がリリースされておりアップデートも可能ですが、この記事では R34.1.0 で実行しています。

https://developer.nvidia.com/embedded/jetson-linux

Jetson AGX Orin 開発キットを Menderに接続

まず、第2回 : mender.ioの試用アカウントを取得 の内容にしたがって mender.io の試用アカウント取得後、mender.io の WebUIにログインします。

例によって CONNECT A DEVICE ダイアログを表示し、表示される接続文字列をコピーして AGX Orinの bash ターミナルにペースト実行することにします。これは sshでログインすると実行しやすいので、もしまだインストールしていなければ、Ubuntuデスクトップ上のターミナルで以下を実行してsshデーモンをインストールします。

Jetson のターミナルで実行
sudo apt install sshd

上手くインストールされ実行中になると、systemctl で確認できます。

nvidia@linux:~$ systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: e>
     Active: active (running) since Fri 2022-06-24 09:01:59 PDT; 2 months 4 day>
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1051 (sshd)
      Tasks: 1 (limit: 36463)
     Memory: 3.5M
     CGroup: /system.slice/ssh.service
             └─1051 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

Jun 24 09:01:59 linux systemd[1]: Starting OpenBSD Secure Shell server...
Jun 24 09:01:59 linux sshd[1051]: Server listening on 0.0.0.0 port 22.
Jun 24 09:01:59 linux sshd[1051]: Server listening on :: port 22.
Jun 24 09:01:59 linux systemd[1]: Started OpenBSD Secure Shell server.
Aug 28 08:41:43 linux sshd[3063]: Accepted password for nvidia from 2409:10:c86>
Aug 28 08:41:43 linux sshd[3063]: pam_unix(sshd:session): session opened for us>
nvidia@linux:~$

これ以降、Windows 10 のコマンドプロンプトから以下のように接続可能になります。
デフォルトのホスト名 = linux で、ユーザー nvidia (初期パスワード nvidia)でログイン可能です。
最初にログインする際には sshキーを保存するかを訊かれるので、yes を入力します。

Microsoft Windows [Version 10.0.19044.1889]
(c) Microsoft Corporation. All rights reserved.

C:\Users\hiron>ping linux.local

linux.local [2409:10:c860:1200:810b:52bc:6fb1:8a24]に ping を送信しています 32  バイトのデータ:
2409:10:c860:1200:810b:52bc:6fb1:8a24 からの応答: 時間 =5ms
2409:10:c860:1200:810b:52bc:6fb1:8a24 からの応答: 時間 =2ms
2409:10:c860:1200:810b:52bc:6fb1:8a24 からの応答: 時間 =2ms
2409:10:c860:1200:810b:52bc:6fb1:8a24 からの応答: 時間 =2ms

2409:10:c860:1200:810b:52bc:6fb1:8a24 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 2ms、最大 = 5ms、平均 = 2ms

C:\Users\hiron>ping -4 linux.local

linux.local [192.168.5.33]に ping を送信しています 32 バイトのデータ:
192.168.5.33 からの応答: バイト数 =32 時間 =4ms TTL=64
192.168.5.33 からの応答: バイト数 =32 時間 =2ms TTL=64
192.168.5.33 からの応答: バイト数 =32 時間 =2ms TTL=64
192.168.5.33 からの応答: バイト数 =32 時間 =2ms TTL=64

192.168.5.33 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 2ms、最大 = 4ms、平均 = 2ms

C:\Users\hiron>ssh linux.local -l nvidia
The authenticity of host 'linux.local (2409:10:c860:1200:810b:52bc:6fb1:8a24)' can't be established.
ECDSA key fingerprint is SHA256:gDlW/YMMeE64THUQTNrqvnqdn3b0ha6e57fVrK3H7uA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'linux.local,2409:10:c860:1200:810b:52bc:6fb1:8a24' (ECDSA) to the list of known hosts.
nvidia@linux.local's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.10.65-tegra aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

168 updates can be applied immediately.
85 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Last login: Fri Jun 24 07:38:29 2022 from 192.168.5.11
nvidia@linux:~$ uname -a
Linux linux 5.10.65-tegra #1 SMP PREEMPT Fri Mar 11 18:12:45 PST 2022 aarch64 aarch64 aarch64 GNU/Linux
nvidia@linux:~$ cat /etc/nv_tegra_release
# R34 (release), REVISION: 0.1, GCID: 29941907, BOARD: t186ref, EABI: aarch64, DATE: Sat Mar 12 02:32:39 UTC 2022
nvidia@linux:~$ ifconfig -a

(中略)

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1466
        inet 192.168.5.33  netmask 255.255.255.0  broadcast 192.168.5.255
        inet6 fe80::4ab0:2dff:fe78:aab0  prefixlen 64  scopeid 0x20<link>
        inet6 2409:10:c860:1200:810b:52bc:6fb1:8a24  prefixlen 64  scopeid 0x0<global>
        inet6 2409:10:c860:1200:4ab0:2dff:fe78:aab0  prefixlen 64  scopeid 0x0<global>
        ether 48:b0:2d:78:aa:b0  txqueuelen 1000  (Ethernet)
        RX packets 169281  bytes 192357898 (192.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16636  bytes 1670753 (1.6 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


nvidia@linux:~$ 

Jetsonデバイスの MACアドレスは 48:b0:2d:78:aa:b0 のようです。


ここで、 mender.io にログインし、ダッシュボードからいつものように CONNECT A DEVICE を実行して開いたダイアログで、Raspbery Pi Quick Start の所にある GET STARTED ボタンを押します。

今回のデバイスはJetsonですが、最初のOTAを実行するために、Device type には raspberrypi3を入力して NEXTを押してください。(Device Type は後で変更可能です)

次のダイアログに表示される接続文字列を COPY TO CLIPBOARD ボタンを押してコピーしたあと、先ほどsshでで接続したbash のターミナル画面にペーストして実行します。途中一か所 sudo コマンドのパスワードを訊かれるところがあるのですが、表示文字の間に埋もれてしまいます。表示が止まったところで現在のユーザーのパスワードを入力しENTERを押すとインストールが進みます。

COPY TO CLIPBOARD を実行

nvidia@linux:~$ JWT_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMmUzOGQwZS1jZWU3LTQ0MjUtOTFkOS00OTExMDk0ZmZmNWQiLCJzdWIiOiJlODYxNTQ3Yy05YmZkLTUwNTQtYjgzMi00NWVmZDU5Yzk4YTciLCJleHAiOjE2NjIzMTc4OTksImlhdCI6MTY2MTcxMzA5OSwibWVuZGVyLnRlbmFudCI6IjYxYWQwNzM0MzYxYTk1YjE0YTM3NWExOCIsIm1lbmRlci51c2VyIjp0cnVlLCJpc3MiOiJNZW5kZXIgVXNlcnMiLCJzY3AiOiJtZW5kZXIuKiIsIm1lbmRlci5wbGFuIjoiZW50ZXJwcmlzZSIsIm1lbmRlci50cmlhbCI6dHJ1ZSwibWVuZGVyLmFkZG9ucyI6W3sibmFtZSI6ImNvbmZpZ3VyZSIsImVuYWJsZWQiOnRydWV9LHsibmFtZSI6InRyb3VibGVzaG9vdCIsImVuYWJsZWQiOnRydWV9LHsibmFtZSI6Im1vbml0b3IiLCJlbmFibGVkIjp0cnVlfV0sIm5iZiI6MTY2MTcxMzA5OX0.sV_bILOYOoU0eKfzYg8AuvUrz3v3Mg4vkG6FOnfjHxvX1PigZDvh9MC_UvOfqZGpdClFsR0N5-SZw1IHEFnbUFDldq2r78YsExhrxsIz2__oMhxpEzi89TZQxuOhsutF44B7rQ7GGrlDk0r0hHVAf7JNyeugJXkN4-TwDnQ8FRWgcZh-CIaEiHFwBLdGpDcZHf-wiRRxkYHdSQKzb8zKNFZiRFhtO35usTQulFQF5A050kfUR3tfugjTd1_zUhW3UA5x1JppWwoaqxPC3xr1cMrzNTg4a2QgKn6sMpnB8EANsFPQBPUrQL5OJ43m4iWgbj8lBWR_8bNRYsSMQ8F_bBVh9S7stAS39TFdK10QafcKQUTEwDz0Fo85DKm2yZfdCfEoWu7FYO-WIAwSKx9o98pjxxToL22pnX6V1YZMt6kH6K_TPjORks014mMS5VKgLycRKfAQ8bh_vEut6gsCFcI3ZCmEANPIGZJyiBCGCGCoLj8S8sGQPDuKiN-T-cIo"
nvidia@linux:~$ TENANT_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW5kZXIudGVuYW50IjoiNjFhZDA3MzQzNjFhOTViMTRhMzc1YTE4IiwiaXNzIjoiTWVuZGVyIiwic3ViIjoiNjFhZDA3MzQzNjFhOTViMTRhMzc1YTE4In0.mcBW_FtR2xTO6njMbvDzbSfdvS36UIUF-xz3Af6Hp_n7T5teMIPW7cB3CveELbD9KZrf5mpmPtjKGwKLORRNxz_hcypu_nTwY-oYJlhrx6zI2D0_TqTfcciIqlCqpsYrrADAQhUy6rbToxPrZJ7SHH3obe09qzMAt7_Yi6s4ysTgJ1S34mIIDmjOWrPkoVocKh6HMGq8kdWjG1oHAcsuh63VtGzW7Lg8SH8Xdknvk62T5v8XM1b7ctQK7uWbJAETHul6WhLDkhUV9t_vztXMXXVJnbvIhxO6Gmr2BwB1BQ7pSJPSabl7EY209j2OaC9trUMzGrDqyh-WXIpIURbHsxXUtrGxVdZXLhLwT0ox8X0fuzJ9JhKNm8NYgCsh-kytYzgZS5e7spKsmFdvxvUQT988pg8phqWAOxFGKGOWI9PiSqL8QFK1PDPUPRY_ye7oaqON2mZ5ckrx_zaGXhFO-mZ-1VMBDdYyGcjHfEhOxsUPcqokyxEsrFN0FEo2XrMp"
nvidia@linux:~$ wget -O- https://get.mender.io | sudo bash -s -- --demo --commercial --jwt-token $JWT_TOKEN -- --quiet --device-type "raspberrypi3" --tenant-token $TENANT_TOKEN --retry-poll 300 --update-poll 1800 --inventory-poll 28800 --hosted-mender
--2022-08-28 12:00:39--  https://get.mender.io/
Resolving get.mender.io (get.mender.io)... [sudo] password for nvidia: 34.107.174.45
Connecting to get.mender.io (get.mender.io)|34.107.174.45|:443... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: https://downloads.mender.io/repos/scripts/install-mender.sh [following]
--2022-08-28 12:00:39--  https://downloads.mender.io/repos/scripts/install-mender.sh
Resolving downloads.mender.io (downloads.mender.io)... 2600:9000:2224:4a00:17:e5ba:7bc0:93a1, 2600:9000:2224:dc00:17:e5ba:7bc0:93a1, 2600:9000:2224:3a00:17:e5ba:7bc0:93a1, ...
Connecting to downloads.mender.io (downloads.mender.io)|2600:9000:2224:4a00:17:e5ba:7bc0:93a1|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15682 (15K) [text/plain]
Saving to: ‘STDOUT’

-                   100%[===================>]  15.31K  --.-KB/s    in 0.007s

2022-08-28 12:00:40 (2.07 MB/s) - written to stdout [15682/15682]

(このあたりで nvidiaユーザーのパスワードを入力し ENTER を押す)


                          _
 _ __ ___   ___ _ __   __| | ___ _ __
| '_ ` _ \ / _ \ '_ \ / _` |/ _ \ '__|
| | | | | |  __/ | | | (_| |  __/ |
|_| |_| |_|\___|_| |_|\__,_|\___|_|

Running the Mender installation script.
--

  Detected distribution:
        ubuntu/focal
  Detected architecture:
        arm64
  Installing from channel:
        stable
  Installing commercial components from source:
        latest
  Selected components:
        mender-client
        mender-configure
        mender-connect
        mender-configure-demo
        mender-configure-timezone
        mender-monitor
        mender-monitor-demo
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package apt-transport-https.
(Reading database ... 146320 files and directories currently installed.)
Preparing to unpack .../apt-transport-https_2.0.9_all.deb ...

(中略)

  Setting up mender with options: --quiet --device-type raspberrypi3 --tenant-token eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW5kZXIudGVuYW50IjoiNjFhZDA3MzQzNjFhOTViMTRhMzc1YTE4IiwiaXNzIjoiTWVuZGVyIiwic3ViIjoiNjFhZDA3MzQzNjFhOTViMTRhMzc1YTE4In0.mcBW_FtR2xTO6njMbvDzbSfdvS36UIUF-xz3Af6Hp_n7T5teMIPW7cB3CveELbD9KZrf5mpmPtjKGwKLORRNxz_hcypu_nTwY-oYJlhrx6zI2D0_TqTfcciIqlCqpsYrrADAQhUy6rbToxPrZJ7SHH3obe09qzMAt7_Yi6s4ysTgJ1S34mIIDmjOWrPkoVocKh6HMGq8kdWjG1oHAcsuh63VtGzW7Lg8SH8Xdknvk62T5v8XM1b7ctQK7uWbJAETHul6WhLDkhUV9t_vztXMXXVJnbvIhxO6Gmr2BwB1BQ7pSJPSabl7EY209j2OaC9trUMzGrDqyh-WXIpIURbHsxXUtrGxVdZXLhLwT0ox8X0fuzJ9JhKNm8NYgCsh-kytYzgZS5e7spKsmFdvxvUQT988pg8phqWAOxFGKGOWI9PiSqL8QFK1PDPUPRY_ye7oaqON2mZ5ckrx_zaGXhFO-mZ-1VMBDdYyGcjHfEhOxsUPcqokyxEsrFN0FEo2XrMp --retry-poll 300 --update-poll 1800 --inventory-poll 28800 --hosted-mender
2229 1244
  Success!
  Setting up mender-connect with user 'root' and shell 'bash'
2229 1244
  Success!
nvidia@linux:~$

念のため、 mender-client サービスと mender-connect サービスが起動していることを確認

nvidia@linux:~$ systemctl status mender-client
● mender-client.service - Mender OTA update service
     Loaded: loaded (/lib/systemd/system/mender-client.service; enabled; vendor>
     Active: active (running) since Sun 2022-08-28 12:03:26 PDT; 1min 46s ago
   Main PID: 16454 (mender)
      Tasks: 12 (limit: 36463)
     Memory: 21.6M
     CGroup: /system.slice/mender-client.service
             └─16454 /usr/bin/mender daemon

Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=err>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=war>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=err>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=err>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=war>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=war>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=inf>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=err>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=err>
Aug 28 12:04:28 linux mender[16454]: time="2022-08-28T12:04:28-07:00" level=war>
nvidia@linux:~$ systemctl status mender-connect
● mender-connect.service - Mender Connect service
     Loaded: loaded (/lib/systemd/system/mender-connect.service; enabled; vendo>
     Active: active (running) since Sun 2022-08-28 12:03:27 PDT; 1min 52s ago
   Main PID: 16597 (mender-connect)
      Tasks: 10 (limit: 36463)
     Memory: 7.3M
     CGroup: /system.slice/mender-connect.service
             └─16597 /usr/bin/mender-connect daemon

Aug 28 12:03:27 linux systemd[1]: Started Mender Connect service.
Aug 28 12:03:27 linux mender-connect[16597]: time="2022-08-28T12:03:27-07:00" l>
Aug 28 12:03:27 linux mender-connect[16597]: time="2022-08-28T12:03:27-07:00" l>
nvidia@linux:~$

この状態で mender.io の WebUI / DEVICES から Pending Devices を確認すると、Jetson デバイスの MACアドレスとともに表示されています。

Pending Devices

この行のチェックボックスにチェックを入れると下のように右下に「+」ボタンが表示され、これにマウスオーバーすると「Accept Device」ボタンが現れるので、緑のチェックマーク部分を押します。

Accept Device

これでJetson AGX Orin 開発キットが mender.io 上で接続認証されました。Jetsonデバイスが次回OTAの確認に来ると実際に接続されます。
あるいは、シェル上で sudo systemctl restart mender-client を実行するか、GUI画面の右上の メニューから Power OffRestart としOS再起動すると、すぐに次の リモートターミナルの実行 が実行可能になります。

リモートターミナルを実行

mender-client が接続中には、WebUIの DEVICES画面 からこのデバイスを選んでリモートターミナルを実行可能です。
(詳細は 第8回 : リモートターミナル機能のご紹介 の記事を参照ください)

DEVICES画面で Status: フィルタを accepted に変更すると、これまでに接続承認したデバイスが一覧表示されます。ここからDevice Typeが raspberrypi3 のデバイスから、実際には Jetson AGX Orin 開発キット の行(macアドレスで確認可能です) を見つけてクリックします。

表示されるデバイス詳細画面の一番下にある Launch a new Remote Terminal session をクリックすると、リモートターミナルがブラウザ内で実行開始されます。実行終了するときは CLOSE ボタンを押します。

アプリケーションアップデートを実行 (後日更新予定)

これまでの記事で利用してきた mender-demo-artifact-3.1.0 は Jetson AGX Orin開発キットのアーキテクチャ aarch64 をサポートしていないことがわかりました。

この項目は後日更新します。

コンテナアップデートを実行

Jetsonプラットフォームでは、AIアプリケーションの展開のため dockerdocker-compose を利用する場面があります。また。Nvidia でもこのような用途に利用可能な NGC コンテナレジストリ (docker イメージのデータベース) を運用しています。

上記はデスクトップPC向けのGPUに対する利用も含んでいますが、一部は Jetsonプラットフォームでも利用可能です。Nvidia GPU向けのdocker拡張部分はNvidia側で独自に拡張されており、NVIDIA CONTAINER TOOLKIT として提供されています。

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/overview.html

このNvidia GPU向け docker ソリューションは 3つの世代で実装が異なっており、インターネット上には旧バージョンに関する解説も残っているので注意が必要です。このあたりの歴史は以下の記事を参照ください。

https://medium.com/nvidiajapan/nvidia-docker-って今どうなってるの-20-09-版-558fae883f44

とはいえ、GPUのdocker仮想化を行わない場合のインストール方法は、本連載の 第7回 : コンテナアップデートを実行 と基本同じです。以下のページに Docker CEのインストール方法が再度まとめられているので、参照ください。

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker

  1. hello-world-container-update ARTIFACTを作成

ここでは 第7回 : コンテナアップデートを実行 の回で作成した hello-world-container-update ARTIFACT を利用します。このARTIFACTは "hello-world" dockerイメージをダウンロードして実行するように mender接続中のデバイスに指示します。そのために、Dockerイメージの操作が可能なLinux PCを利用します。

第7回 : コンテナアップデートを実行 の内容をすでに実行済の場合は追加の作業はありません。そうでない場合は 第7回 : コンテナアップデートを実行 の内容を参考に ARTIFACTを作成しmender.io に登録してください。

  1. Jetson AGX Orin 開発キットに Dockerをインストール

Jetson AGX Orin 開発キットのシェルで

sudo docker ps
sudo docker image ls

などがエラーになる場合、Dockerエンジンがインストールされていません。
以下を実行します。

curl https://get.docker.com | sh \
  && sudo systemctl --now enable docker

途中、sudoパスワードを要求されたら入力します。10分程度でインストールが終わります。 (じゅうぶん時間が経過したと思ったら ENTER を押してみてください)

必要に応じて dockerグループへのユーザーの追加など、post-install actions を実行します。

動作確認はいつもの

sudo docker run --rm hello-world

で可能です。 (--rm は docker ps で表示される実行履歴を削除するオプションです)
成功すると、以下のように表示されます。

nvidia@linux:~$ sudo docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete
Digest: sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

nvidia@linux:~$

これを実行すると、hello-world イメージがローカルに保存されるので、この後のOTAの動作確認のためにここで以下のように実行し、ダウンロードしたhello-world の dockerイメージを削除しておいてください。

nvidia@linux:~$ sudo docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    46331d942d63   5 months ago   9.14kB
nvidia@linux:~$ sudo docker image rm hello-world --force
Untagged: hello-world:latest
Untagged: hello-world@sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
Deleted: sha256:46331d942d6350436f64e614d75725f6de3bb5c63e266e236e04389820a234c4
nvidia@linux:~$ sudo docker image ls
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
nvidia@linux:~$
  1. OTA実行

  2. の手順であらかじめ登録した hello-world-container-update ARTIFACT を利用して新規OTAジョブ (DEPLOYMENT) を作成します。

mender.io の WebUIにログインし、DEVICES 画面でJetson AGX Orinデバイスが接続中であることを確認します。次に RELEASES 画面から hello-world-container-update をクリックし、表示される CREATE DEPLOYMENT WITH THIS RELEASE ボタンを押して新規DEPLOYMENTを作成します。 (もし実行途中のDEPLOYMENTSが残っている場合には、あらかじめ実行キャンセルしておいた方がわかりやすいかもしれません)

最初の画面のSelect a device group to targetのみ All Devicesを設定し、残りは特にオプション変更をせずにNEXT を実行し最後に CREATEを押してDEPLOYMENTを作成します。すると(ポーリング間隔設定次第ですが)やがて接続中の Jetson AGX Orin デバイス上で更新が実行されます。

WebUIの以下の画面で DETAILS ボタンを押す

Jetson AGX Orin開発キットで OTAが実行されると、以下のように表示が変化します

また、Jetson AGX Orinデバイスに ssh ログインし、docker ps -aコマンド利用して hello-worldが OTAにより実行されたことが確認できます。このとき実行した dockerイメージがローカル保存されています。

nvidia@linux:~$ sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
28db64c8ba75   hello-world   "/hello"   13 minutes ago   Exited (0) 13 minutes ago             gracious_mendel
nvidia@linux:~$ sudo docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    46331d942d63   5 months ago   9.14kB
nvidia@linux:~$

ここで利用したARTIFACTは hello-worldコンテナを一回だけ実行するものでしたが、より本格的に OTAで dockerコンテナを運用するには、Linuxサービスとしてdockerコンテナが自動起動するような systemctlのエントリをOTA展開と同時に設定することが考えられます。こうすると dockerコマンドの起動オプションをsystemctlエントリ内で自由に設定可能になります。

OTAによるLinuxサービスの登録方法は、いつもの mender-demo-artifact でも利用されています。詳しくは以下の GitHubを確認ください。

https://github.com/mendersoftware/mender-demo-artifact

Device type を変更

MenderのWeb UIに表示される Device type は Menderクライアントの /var/lib/mender/device_type に保存されている以下の設定から取り出されます。

/var/lib/mender/device_type
device_type=raspberrypi3

ここを

/var/lib/mender/device_type
device_type=Jetson

のように変更後、mender-clientサービスを再起動する ( systemctl restart mender-client 等を実行) ことで、mender.io のWebUI上の表示が変化します。

A/B パーティションを利用した OSアップデート

Jetson AGX Orin / AGX Xavier / Xavier NX では L4T上で A/Bパーティション機能をサポート予定です。

https://docs.nvidia.com/jetson/archives/r35.1/DeveloperGuide/text/SD/Bootloader/ABfeatureForDP.html#switching-between-a-b-boot-chains-developer-preview

この機能を利用して、対障害性を高めた OSアップデートを実現可能です。
旧OSバージョンでこの機能を利用する例が紹介されていますので、興味のある方は参照ください。

https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968

この記事のまとめ

Jetson AGX Orin開発キットをMenderサーバーに接続し、リモートターミナル接続やdockerコンテナアップデートが利用可能なことを確認しました。

今後の予定

コードギアでは Menderで始める組み込みOTA のタイトルで以下のZenn記事を公開しています。

以下、Quickstart編

以下、接続編

これ以降の記事も準備中です。ご期待ください。

Discussion