エッジデバイスでアプリケーションを開発する際に以下の課題を感じたことはありませんか?
・アプリケーションを実行するために必要なライブラリーのインストールが多くて管理が煩雑
・アプリケーションを入れ替えたくてもすぐに対応が難しい
・OS、ライブラリー、アプリケーションのバージョン互換性の維持が難しい
NVIDIA® Jetson AGX Orin™ 開発者キット(以下、AGX Orinとする)を最大限活用するために、様々なアプリケーションを試したいというお声をいただきます。その場合、クラウドネイティブ技術の代表格である「コンテナ」や「Kubernetes」を活用するのがおすすめです。
本記事では、AGX Orin上でコンテナやKubernetesを活用したアプリケーション開発を体験する方法をご紹介します。
第1章 構築体験できるシステムは「音声によるロボット操作」
第2章 エッジデバイスでKubernetesを活用する際のアプリケーション構成を理解する
第3章 コンテナ/Kubernetesを活用したアプリケーション開発の流れを理解する
第4章 レッドハットMicroShiftを用いてKubernetesを活用したシステム構築を実践する
第1話では第1章から第2章まで解説します。第3章以降はこちら
第1章 構築体験できるシステムは「音声によるロボット操作」
本記事では、以下に示される「音声でロボットを操作するユースケース」の実装を目指します。
・AGX OrinにてRiva APIサーバを実行し、マイク入力で音声認識
・音声認識結果に応じて、ロボットへ動作指示
・ロボットが指示を受けて動作
ロボットは、SunFounder社のPiCar-Vを使用しますが、PiCar-Vでなく他のロボットでも、同様の考え方で構築できます。
このユースケースを通じて、エッジデバイスでコンテナやKubernetesを活用すると、大きく以下の3つのメリットを体験できます。
ホストOSの構成をシンプルに
OSに直接インストールされたソフトウェア構成をシンプルに保つことができます。故に、OSのプロビジョニングも自動化しやすい構成にすることが可能です。
アプリケーションの展開・入れ替え・更新作業をシンプルに
エッジデバイスに一つずつsshログインしなくても、アプリケーションの展開(デプロイと言います)や入れ替え、更新を遠隔からワンコマンドで実行できます。アプリケーションの更新はローリングアップデートが適用され、アップデートの仕組みを標準化することにつながります。また、新たなエッジデバイスに同じシステムを横展開したい際は、同様の手順でアプリケーションをデプロイすることで容易に再現することが可能です。
アプリケーション間連携をシンプルに
アプリケーション同士の連携やエッジデバイス同士の連携を疎結合にし、アプリケーションの追加や更新による影響を極小化する保守性の高いシステムを構築できます。
なお、本記事では扱いませんが、エッジデバイスの台数が増大した状態でも複数のKubernetesをまとめて管理する技術も存在するため、一元的なオペレーションにより、オペレーションの簡素化や自動化が可能です。
第2章 エッジデバイスでKubernetesを活用する際のアプリケーション構成を理解する
エッジデバイスでKubernetesを活用する際は、ハードウェアと用途を切り離し、標準化することが大切です。従来のエッジデバイスを用いたアプリケーション開発では、用途がハードウェアに紐付き専用機扱いで開発されることが一般的でした。そして、アプリケーションの使用するリソースに対して必要最低限のハードウェアリソースを配備し、コストを極力抑えてプロダクト化することが求められてきました。しかし、その場合、プロダクトへ新たな付加価値として機能追加をしたくても、新製品の提供まで新機能をリリースすることができません。また、ハードウェアやOSの構成が用途ごとに異なる形になり、OSのプロビジョニングや構成の自動化がしづらく、オペレーションが非効率になりやすい課題が生まれます。
一方で、Kubernetesを用いる場合は、OSとアプリケーションを水平分離するアーキテクチャーとなります。つまり、特定のエッジデバイスにアプリケーションが紐づかず、ハードウェアを汎用的に扱うことが可能です。これにより、ハードウェアやOSの構成を標準化でき、自動化への対応ハードルも低減されます。
ただし、全てのアプリケーションが水平分離できるかというと必ずしもそうではありません。GPUなどのドライバーとアプリケーションが連携する必要がある場合、Kubernetesを活用する場合においても、垂直統合のレイヤーは生まれます。
基本的な考え方として、「ハードウェア連携が伴うアプリケーション」か「ハードウェア連携が伴わないアプリケーション」かで、エッジデバイスへのアプリケーション収容の設計が変わります。ハードウェア連携が伴うアプリケーションの場合、各エッジデバイスにデーモンのようにアプリケーションが常駐する形とする必要があります。一方で、ハードウェア連携が伴わないアプリケーションは、どのハードウェアでも実行可能な状態とします。
次に、ハードウェア連携が伴うアプリケーションと伴わないアプリケーションの機能追加や更新に伴うリリース頻度を考慮します。ハードウェア連携が伴うアプリケーションは、推論アプリケーションのようなデータ変化に弱いアプリケーションはともかく、それ以外の多くはPLCからのデータ収集やロボットの制御など、ハードウェアレベルで変更が起こらない限り更新が発生しないことが想定されます。そのため、リリース頻度はハードウェア連携が伴わないアプリケーションの方が明らかに高いと言えます。
アプリケーション間連携の手法は、リクエスト・レスポンスの同期型の手法と、イベントハブを介した非同期型の連携があります。
同期型のアプリケーション間連携では、アプリケーション間の境界にロードバランサを設けて、アプリケーションを互いに連携させず、またアプリケーションの負荷が高い時に容易にスケールアウトできるように考慮します。一方、非同期型のアプリケーション間連携の実現方法として、あるアプリケーションの処理結果やデータの変化を「イベント」として扱い、イベントの発生を契機にアプリケーションが自律的に実行される「イベント駆動型」の構成があります。イベント駆動型のアプリケーションは、「イベントハブ」と呼ばれる、イベントを流通させるコンポーネントをアプリケーションの間に設けて、アプリケーションはイベントハブを介してイベントをやり取りする構成をとります。
同期型の連携方法は実装が容易でリアルタイム性が高いメリットがある一方で、複数のアプリケーションを連携させて一つのトランザクションを構成するようなステートフルなユースケースには不向きです。その場合は、非同期型の連携方法を採用することで、機能追加や更新などの変更容易性を高めることが可能です。ただし、リアルタイム性は同期型よりも損なわれます。
たとえば、本記事で対象としているユースケースでは実装難易度を下げるため、以下の同期型の連携方法で実装しています。GPUを必要とするRiva APIサーバはAGX Orinへ、モーターの制御にI2Cを使用するPiCar-Vの制御プログラムはRaspberry Piに常駐させます。Riva APIサーバーは、マイクから入力された音声データを受信すると音声認識を行います。そして、その認識結果を踏まえて、PiCar-Vへ走行指示が出され、音声入力によるPiCar-Vの操作を実現します。