1. はじめに
Google がリリースした OpenThread は、Thread ネットワーク プロトコルのオープンソース実装です。Google Nest は、Google Nest 製品で使用されている技術を広くデベロッパーに提供し、スマートホーム製品の開発を加速させるために、OpenThread をリリースしました。
Thread 仕様は、ホーム アプリケーション向けの、IPv6 ベースの、信頼性が高く、安全で、低電力のワイヤレス デバイス間通信プロトコルを定義しています。OpenThread は、IPv6、6LoWPAN、IEEE 802.15.4 を含むすべての Thread ネットワーク レイヤ、MAC セキュリティ、メッシュリンクの確立、メッシュ ルーティングを実装します。
この Codelab では、Docker を使用して、エミュレートしたデバイスで Thread ネットワークをシミュレートする方法について説明します。
学習内容
- OpenThread ビルド ツールチェーンの設定方法
- Thread ネットワークをシミュレートする方法
- Thread ノードを認証する方法
- OpenThread Daemon を使用して Thread ネットワークを管理する方法
必要なもの
- Docker
- Linux、ネットワーク ルーティングの基礎知識
2. Docker の設定
この Codelab は、Linux、Mac OS X、または Windows マシンで Docker を使用するように設計されています。推奨される環境は Linux です。
Docker のインストール
任意の OS に Docker をインストールします。
Docker イメージを pull する
Docker をインストールしたら、ターミナル ウィンドウを開いて openthread/environment
Docker イメージを pull します。このイメージには OpenThread と OpenThread Daemon があらかじめ組み込まれていて、この Codelab で使用できる状態になっています。
$ docker pull openthread/environment:latest
ダウンロードが完了するまでに数分かかることがあります。
ターミナル ウィンドウで、イメージから Docker コンテナを起動し、bash
シェルに接続します。
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
--rm
オプションは、コンテナを終了するとコンテナを削除します。コンテナが削除されないようにする場合は、このオプションを使用しないでください。
この Codelab に必要なフラグに注意してください。
--sysctl net.ipv6.conf.all.disable_ipv6=0
- コンテナ内で IPv6 を有効にします。--cap-add=net_admin
- NET_ADMIN 機能を有効にします。これにより、IP ルートの追加など、ネットワーク関連の操作を実行できます。
コンテナに入ると、次のようなプロンプトが表示されます。
root@c0f3912a74ff:/#
上記の例では、c0f3912a74ff
はコンテナ ID です。Docker コンテナのインスタンスのコンテナ ID は、この Codelab のプロンプトに表示される ID とは異なります。
Docker の使用
この Codelab は、Docker の基本的な使い方を理解していることを前提としています。この Codelab 全体で Docker コンテナを使用してください。
3. Thread ネットワークをシミュレートする
この Codelab で使用するサンプル アプリケーションは、基本的なコマンドライン インターフェース(CLI)を介して OpenThread 構成と管理インターフェースを公開する、最小限の OpenThread アプリケーションのデモを行います。
この演習では、エミュレートしている Thread デバイス間で、エミュレートした Thread デバイスへの ping に必要な最小限の手順を実施します。
次の図は、Thread の基本的なネットワーク トポロジを示しています。この演習では、緑色の丸で囲まれた 2 つのノード(Thread Leader と Thread Router 間の接続)をエミュレートします。
ネットワークを作成する
1. ノード 1 を起動します
まだ行っていない場合は、ターミナル ウィンドウで Docker コンテナを起動し、bash
シェルに接続します。
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
Docker コンテナで、ot-cli-ftd
バイナリを使用して、エミュレートした Thread デバイスに対する CLI プロセスを生成します。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
このバイナリは OpenThread デバイスを実装しています。IEEE 802.15.4 無線ドライバは UDP 上に実装されます(IEEE 802.15.4 フレームは UDP ペイロードで渡されます)。
1
の引数は、エミュレートしたデバイスの「ファクトリ割り当て」された IEEE EUI-64 の最下位ビットを表すファイル記述子です。この値は、IEEE 802.15.4 無線エミュレーション(ポート = 9000 + ファイル記述子)の UDP ポートにバインドする場合にも使用されます。この Codelab でエミュレートする Thread デバイスのインスタンスでは、それぞれ異なるファイル記述子を使用します。
注: この Codelab で説明したように、1
以上のファイル記述子は、エミュレートしたデバイスのプロセスを生成する場合にのみ使用してください。0
のファイル記述子は他の用途用に予約されています。
新しいオペレーショナル データセットを作成し、アクティブなデータセットとして commit します。オペレーショナル データセットは、作成する Thread ネットワークの構成です。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 20 Channel Mask: 07fff800 Ext PAN ID: d6263b6d857647da Mesh Local Prefix: fd61:2344:9a52:ede0/64 Network Key: e4344ca17d1dca2a33f064992f31f786 Network Name: OpenThread-c169 PAN ID: 0xc169 PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
数秒待ってから、デバイスが Thread リーダーになりました。リーダーは、ルーター ID の割り当てを管理するデバイスです。
> state leader Done
ノード 1 のスレッド インターフェースに割り当てられた IPv6 アドレスを表示します(出力は異なります)。
> ipaddr fd61:2344:9a52:ede0:0:ff:fe00:fc00 fd61:2344:9a52:ede0:0:ff:fe00:5000 fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 fe80:0:0:0:94da:92ea:1353:4f3b Done
特定の IPv6 アドレスの種類に注意してください。
- 先頭が
fd
= メッシュローカル fe80
= link-local で始まる
メッシュローカルのアドレスタイプはさらに分類されます。
ff:fe00
= Router ロケーター(RLOC)を含む- 次を含まない:
ff:fe00
= エンドポイント識別子(EID)
コンソール出力で EID を特定し、後で使用するためにメモしておきます。上の出力例の EID は次のとおりです。
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. ノード 2 を起動します。
新しいターミナルを開き、現在実行している Docker コンテナで bash
シェルを実行して、ノード 2 に使用します。
$ docker exec -it codelab_otsim_ctnr bash
この新しい bash
プロンプトで、引数 2
を指定して CLI プロセスを生成します。2 つ目のエミュレートされた Thread デバイスです。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
ノード 1 の運用データセットと同じ値を使用して、Thread ネットワーク キーと PAN ID を構成します。
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
デバイスは自身を子として初期化します。Thread Child は、親デバイスとのみユニキャスト トラフィックを送受信する Thread デバイスに相当します。
> state child Done
2 分以内に、状態が child
から router
に切り替わります。Thread ルーターは、Thread デバイス間でトラフィックをルーティングできます。保護者とも呼ばれます。
> state router Done
ネットワークを確認する
ルーター ネットワークを確認すると、メッシュ ネットワークを簡単に確認できます。
1. 接続を確認する
ノード 2 で RLOC16 を取得します。RLOC16 は、デバイスの RLOC IPv6 アドレスの最後の 16 ビットです。
> rloc16 5800 Done
ノード 1 のルーター テーブルでノード 2 の RLOC16 を確認します。ノード 2 がルーターの状態に切り替わっていることを確認します。
> router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+--------+-------+---+--------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
表にノード 2 の RLOC 0x5800
があり、それがメッシュに接続されていることを確認します。
2. ノード 1 からノード 2 に対して ping を実行する
2 つのエミュレートされた Thread デバイス間の接続を確認します。ノード 2 で、ノード 1 に割り当てられた EID を次のように作成します。ping
> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 > 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms
enter
を押すと、>
CLI のプロンプトに戻ります。
ネットワークをテストする
エミュレートした 2 つの Thread デバイス間で正常に ping が通ったので、1 つのノードをオフラインにしてメッシュ ネットワークをテストします。
ノード 1 に戻ってスレッドを停止します。
> thread stop Done
ノード 2 に切り替えて、状態を確認します。2 分以内にノード 2 によってリーダー(ノード 1)がオフラインであることが検出され、ノード 2 がネットワークの leader
に切り替わるはずです。
> state router Done ... > state leader Done
確認したら、Thread を停止し、ノード 2 を出荷時の設定にリセットしてから、Docker bash
プロンプトに戻ります。この演習で使用した Thread ネットワーク認証情報が次の演習に引き継がれるように、出荷時設定にリセットされています。
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
factoryreset
コマンドの後に >
プロンプトに戻るには、enter
を数回押す必要がある場合があります。Docker コンテナを終了しないでください。
また、ノード 1 を出荷時の設定にリセットして終了します。
> factoryreset > > exit root@c0f3912a74ff:/#
利用可能なすべての CLI コマンドについては、OpenThread CLI リファレンスをご覧ください。
4. コミッショニングでノードを認証する
前の演習では、シミュレートされた 2 つのデバイスと確認済みの接続を備えた Thread ネットワークをセットアップしました。ただし、これでデバイス間で未認証の IPv6 リンクローカル トラフィックしか通過できなくなります。ノード間(および Thread ボーダー ルーター経由のインターネット)でグローバル IPv6 トラフィックをルーティングするには、ノードを認証する必要があります。
認証するには、1 台のデバイスがコミッショナーとして機能する必要があります。コミッショナーは、現在選択されている新しい Thread デバイス用の認証サーバーであり、デバイスがネットワークに接続するために必要なネットワーク認証情報を提供する承認者です。
この演習では、前と同じ 2 ノードのトポロジを使用します。Thread リーダーは認証の際、コミッショナーとして機能し、Thread Router は Joiner として機能します。
Docker
残りの演習では、各ノード(ターミナル ウィンドウ)で OpenThread ビルドを使用して Docker コンテナを実行していることを確認します。前の演習の続きを行う場合も、同じ Docker コンテナ内に 2 つの bash
プロンプトがすでに開いているはずです。そうでない場合は、Docker のトラブルシューティングの手順を参照するか、Thread ネットワークをシミュレートする演習をやり直します。
1. ネットワークの作成
ノード 1 で CLI プロセスを生成します。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
新しいオペレーショナル データセットを作成し、それをアクティブなデータセットとして commit して、スレッドを開始します。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 12 Channel Mask: 07fff800 Ext PAN ID: e68d05794bf13052 Mesh Local Prefix: fd7d:ddf7:877b:8756/64 Network Key: a77fe1d03b0e8028a4e13213de38080e Network Name: OpenThread-8f37 PAN ID: 0x8f37 PSKc: f9debbc1532487984b17f92cd55b21fc Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
数秒待ってから、デバイスが Thread リーダーになったことを確認します。
> state leader Done
2. コミッショナーのロールを開始する
ノード 1 で、コミッショナーのロールを開始します。
> commissioner start Done
J01NME
ジョイナー認証情報を持つ任意のジョイナーが、*
ワイルドカードを使用してネットワークへのコミッションを許可します。Joiner は、人間が管理者によって追加された Thread ネットワークに追加されるデバイスです。
> commissioner joiner add * J01NME Done
3. Joiner のロールを開始する
第 2 のターミナル ウィンドウで、Docker コンテナ内で新しい CLI プロセスを生成します。これはノード 2 です。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
ノード 2 で、J01NME
Joiner Credential を使用して Joiner ロールを有効にします。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、デバイス(ノード 2)はコミッショナー(ノード 1)で自己認証され、Thread ネットワーク認証情報を受信しました。
ノード 2 が認証されたら、Thread を起動します。
> thread start Done
4. ネットワーク認証を検証する
ノード 2 の state
で、ネットワークに接続されたことを確認します。ノード 2 は 2 分以内に child
から router
に移行します。
> state child Done ... > state router Done
5. 構成をリセット
次の演習の準備として、構成をリセットします。各ノードで、Thread を停止し、出荷時の設定にリセットして、エミュレートした Thread デバイスを終了します。
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
factoryreset
コマンドの後に >
プロンプトに戻るには、enter
を数回押す必要がある場合があります。
5. OpenThread Daemon を使用してネットワークを管理する
この演習では、1 つの CLI インスタンス(1 つの組み込み SoC スレッド デバイス)と 1 つの Radio Co-Processor(RCP)インスタンスをシミュレートします。
ot-daemon
は、OpenThread Posix アプリのモードであり、UNIX ソケットを入力および出力として使用するため、OpenThread コアはサービスとして実行できます。クライアントは、OpenThread CLI をプロトコルとして使用してソケットに接続することで、このサービスと通信できます。
ot-ctl
は、RCP を管理および構成するために ot-daemon
によって提供される CLI です。これを使用して、RCP が Thread デバイスによって作成されたネットワークに接続されます。
Docker
この演習では、ノード(ターミナル ウィンドウ)ごとに、OpenThread ビルドを使用して Docker コンテナを実行していることを確認します。前の演習を続けると、同じ Docker コンテナ内で 2 つの bash
プロンプトがすでに開いているはずです。そうでない場合は、Docker のトラブルシューティングの手順をご覧ください。
ot-daemon を使用する
この演習では、次の 3 つのターミナル ウィンドウを使用します。
- シミュレートされた Thread デバイスの CLI インスタンス(ノード 1)
ot-daemon
プロセスot-ctl
CLI インスタンス
1. ノード 1 を起動します
最初のターミナル ウィンドウで、エミュレートした Thread デバイスに対して CLI プロセスを生成します。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
新しいオペレーショナル データセットを作成し、それをアクティブなデータセットとして commit して、スレッドを開始します。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 13 Channel Mask: 07fff800 Ext PAN ID: 97d584bcd493b824 Mesh Local Prefix: fd55:cf34:dea5:7994/64 Network Key: ba6e886c7af50598df1115fa07658a83 Network Name: OpenThread-34e4 PAN ID: 0x34e4 PSKc: 38d6fd32c866927a4dfcc06d79ae1192 Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
ノード 1 のスレッド インターフェースに割り当てられた IPv6 アドレスを表示します。
> ipaddr fd55:cf34:dea5:7994:0:ff:fe00:fc00 fd55:cf34:dea5:7994:0:ff:fe00:d000 fd55:cf34:dea5:7994:460:872c:e807:c4ab fe80:0:0:0:9cd8:aab6:482f:4cdc Done >
Thread ネットワークをシミュレートするのステップで説明したように、1 つのアドレスはリンクローカル(fe80
)で、3 つのアドレスはメッシュローカル(fd
)です。EID は、アドレスに ff:fe00
を含まないメッシュローカル アドレスです。このサンプル出力では、EID は fd55:cf34:dea5:7994:460:872c:e807:c4ab
です。
ipaddr
出力から特定の EID を特定します。この EID は、ノードとの通信に使用されます。
2. ot-daemon を起動する
第 2 のターミナル ウィンドウで、tun
デバイスノードを作成し、読み取り/書き込み権限を設定します。
root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200 root@c0f3912a74ff:/# chmod 600 /dev/net/tun
このデバイスは、仮想デバイスでのパケットの送受信に使用されます。デバイスがすでに作成されている場合は、エラーが発生することがありますが、これは正常であり、無視してかまいません。
RCP ノード(ノード 2 と呼びます)の ot-daemon
を起動します。-v
詳細フラグを使用すると、ログ出力を表示して実行中かどうかを確認できます。
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty:///openthread/build/examples/apps/ncp/ot-rcp?forkpty-arg=2'
成功すると、詳細モードの ot-daemon
では次のような出力が生成されます。
ot-daemon[31]: Running OPENTHREAD/297a880; POSIX; Feb 1 2022 04:43:39 ot-daemon[31]: Thread version: 3 ot-daemon[31]: Thread interface: wpan0 ot-daemon[31]: RCP version: OPENTHREAD/297a880; SIMULATION; Feb 1 2022 04:42:50
このターミナルは開いたまま、バックグラウンドで実行したままにします。コマンドは入力しません。
3. ot-ctl を使用してネットワークに接続する
まだノード 2(ot-daemon
RCP)をどの Thread ネットワークにもコミッショニングしていません。ここで ot-ctl
の出番です。ot-ctl
は OpenThread CLI アプリと同じ CLI を使用するため、シミュレートされた他の Thread デバイスと同じ方法で ot-daemon
ノードを制御できます。
第三のターミナル ウィンドウを開き、既存のコンテナを実行します。
$ docker exec -it codelab_otsim_ctnr bash
コンテナで ot-ctl
を起動します。
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl >
この 3 つ目のターミナル ウィンドウで ot-ctl
を使用し、2 つ目のターミナル ウィンドウで ot-daemon
を使用して開始したノード 2(RCP ノード)を管理します。ノード 2 の state
を確認します。
> state disabled Done
ノード 2 の eui64
を取得して、参加を特定の Joiner に制限します。
> eui64 18b4300000000001 Done
ノード 1(最初のターミナル ウィンドウ)で、コミッショナーを起動して参加をその eui64 のみに制限します。
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
第 3 のターミナル ウィンドウで、Node 2 のネットワーク インターフェースを表示し、ネットワークに参加します。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、RCP(ノード 2)はコミッショナー(ノード 1)で自己認証され、Thread ネットワーク認証情報を受信しました。
次に、ノード 2 を Thread ネットワーク(3 番目のターミナル ウィンドウで再び)に参加させます。
> thread start Done
4. ネットワーク認証を検証する
第 3 のターミナルでは、ノード 2 の state
を調べて、ネットワークに接続されたことを確認します。ノード 2 は 2 分以内に child
から router
に移行します。
> state child Done ... > state router Done
5. 接続の検証
第三のターミナル ウィンドウで、Ctrl+D または exit
コマンドを使用して ot-ctl
を終了し、コンテナの bash
コンソールに戻ります。このコンソールから、EID を使用して ping6
コマンドを使用してノード 1 に対して ping を実行します。ot-daemon
RCP インスタンスが正常に Thread ネットワークに参加して通信している場合、ping は成功します。
root@c0f3912a74ff:/# ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms --- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms
6. Docker のトラブルシューティング
Docker コンテナを終了した場合
bash
プロンプト実行されている場合は、必要に応じて、再起動 / 再入力を行ってください。--rm
オプションを使用しない方法で作成した Docker コンテナが引き続き存在します。
実行中の Docker コンテナを表示するには:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
すべての Docker コンテナ(実行中と停止の両方)を表示するには:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
いずれかの docker ps
コマンドの出力にコンテナ codelab_otsim_ctnr
が表示されない場合は、再度実行します。
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
--rm
オプションは、コンテナの終了時にコンテナを削除する場合にのみ使用してください。
コンテナが停止している場合は(docker ps -a
にあり、docker ps
には表示されない)、再起動します。
$ docker start -i codelab_otsim_ctnr
Docker コンテナがすでに実行されている場合は(docker ps
を参照)、各ターミナルでコンテナに再接続します。
$ docker exec -it codelab_otsim_ctnr bash
「許可されていないオペレーション」エラー
新しい OpenThread ノード(mknod
コマンドを使用)の作成時に Operation not permitted
エラーが発生した場合は、この Codelab で提供されるコマンドに従って root ユーザーとして Docker を実行していることを確認してください。この Codelab では、rootless モードでの Docker の実行はサポートされていません。
7. 完了
OpenThread を使用して最初の Thread ネットワークが正常にシミュレートされました。でも使用できます。
この Codelab では、以下について学びました。
- OpenThread Simulation Docker コンテナを起動して管理する
- Thread ネットワークをシミュレートする
- Thread ノードを認証する
- OpenThread Daemon を使用して Thread ネットワークを管理する
Thread と OpenThread について詳しくは、以下のリファレンスをご覧ください。
- openthread.io の Thread Primer
- スレッドの仕様
- OpenThread GitHub リポジトリ
- OpenThread CLI リファレンス
- OpenThread Docker の追加サポート
または、Docker コンテナで OpenThread ボーダー ルーターを使用してください。