Docker에서 OpenThread를 사용하여 스레드 네트워크 시뮬레이션

1. 소개

26b7f4f6b3ea0700.png

Google에서 출시한 OpenThreadThread 네트워킹 프로토콜의 오픈소스 구현입니다. Google Nest는 Nest 제품에 사용되는 기술을 개발자가 커넥티드 홈용 제품 개발을 가속화할 수 있도록 하기 위해 OpenThread를 출시했습니다.

스레드 사양은 홈 애플리케이션을 위한 IPv6 기반 안정성, 보안, 저전력 무선 기기 간 통신 프로토콜을 정의합니다. OpenThread는 MAC 보안, 메시 링크 설정, 메시 라우팅을 포함하는 IPv6, 6LoWPAN, IEEE 802.15.4를 비롯한 모든 스레드 네트워킹 레이어를 구현합니다.

이 Codelab에서는 Docker를 사용하여 에뮬레이션된 기기에서 스레드 네트워크를 시뮬레이션하는 방법을 안내합니다.

학습할 내용

  • OpenThread 빌드 도구 모음 설정 방법
  • 스레드 네트워크를 시뮬레이션하는 방법
  • 스레드 노드를 인증하는 방법
  • OpenThread Daemon으로 스레드 네트워크를 관리하는 방법

필요한 항목

  • Docker
  • Linux, 네트워크 라우팅에 관한 기본 지식

2. Docker 설정

이 Codelab은 Linux, Mac OS X 또는 Windows 시스템에서 Docker를 사용하도록 설계되었습니다. Linux가 권장됩니다.

Docker 설치

선택한 OS에 Docker를 설치합니다.

Docker 이미지 가져오기

Docker가 설치되면 터미널 창을 열고 openthread/environment Docker 이미지를 가져옵니다. 이 이미지에는 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. 스레드 네트워크 시뮬레이션

이 Codelab에서 사용할 애플리케이션 예시는 기본 명령줄 인터페이스 (CLI)를 통해 OpenThread 구성 및 관리 인터페이스를 노출하는 최소한의 OpenThread 애플리케이션을 보여줍니다.

이 실습에서는 에뮬레이션된 스레드 기기에서 다른 에뮬레이션된 스레드 기기를 핑하는 데 필요한 최소한의 단계를 안내합니다.

아래 그림은 기본 스레드 네트워크 토폴로지를 설명합니다. 이 연습에서는 녹색 원 안에 두 개의 노드, 즉 단일 리더가 연결된 스레드 리더와 스레드 라우터를 에뮬레이션합니다.

6e3aa07675f902dc.png

네트워크 만들기

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 바이너리를 사용하여 에뮬레이션된 스레드 기기의 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 무선 에뮬레이션에 대해 UDP 포트에 바인딩할 때도 사용됩니다 (포트 = 9000 + 파일 설명자). 이 Codelab에서 에뮬레이션된 스레드 기기의 각 인스턴스는 다른 파일 설명자를 사용합니다.

참고: 에뮬레이션된 기기의 프로세스를 생성할 때는 이 Codelab에 설명된 대로 1 이상의 파일 설명자만 사용하세요. 0의 파일 설명자는 다른 용도로 예약되어 있습니다.

새 작업 데이터 세트를 만들고 활성 데이터 세트로 커밋합니다. 운영 데이터 세트는 생성 중인 스레드 네트워크의 구성입니다.

> 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

이 데이터 세트를 활성 데이터 세트로 커밋합니다.

> dataset commit active
Done

IPv6 인터페이스를 불러옵니다.

> ifconfig up
Done

스레드 프로토콜 작업을 시작합니다.

> thread start
Done

잠시 기다린 후 기기가 스레드 리더가 되었는지 확인합니다. 리더는 라우터 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로 시작 = Mesh-local
  • fe80로 시작 = link-local

메시-로컬 주소 유형은 추가로 분류됩니다.

  • 포함 ff:fe00 = 라우터 위치 검색기 (RLOC)
  • ff:fe00 제외 = 엔드포인트 ID (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 프로세스를 생성합니다. 다음은 두 번째로 에뮬레이션된 스레드 기기입니다.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2

참고: 이 명령어를 실행한 후 > 메시지가 표시되지 않으면 enter를 누릅니다.

노드 1의 운영 데이터 세트와 동일한 값을 사용하여 스레드 네트워크 키와 PAN ID를 구성합니다.

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

이 데이터 세트를 활성 데이터 세트로 커밋합니다.

> dataset commit active
Done

IPv6 인터페이스를 불러옵니다.

> ifconfig up
Done

스레드 프로토콜 작업을 시작합니다.

> thread start
Done

기기가 자동으로 하위 요소로 초기화됩니다. 스레드 하위 요소는 상위 기기로만 유니캐스트 트래픽을 전송하고 수신하는 스레드 기기인 최종 기기와 같습니다.

> state
child
Done

2분 내에 상태가 child에서 router로 전환됩니다. 스레드 라우터는 스레드 기기 간에 트래픽을 라우팅할 수 있습니다. 상위 항목이라고도 합니다.

> 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의 0x5800 RLOC가 표시되어 메시에 연결되었음을 확인합니다.

2. 노드 2에서 노드 1 핑

에뮬레이션된 두 스레드 기기 간의 연결을 확인합니다. 노드 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 프롬프트로 돌아갑니다.

네트워크 테스트

이제 에뮬레이션된 두 스레드 기기 간에 핑할 수 있으므로 한 노드를 오프라인으로 전환하여 메시 네트워크를 테스트합니다.

노드 1로 돌아가서 스레드를 중지합니다.

> thread stop
Done

노드 2로 전환하고 상태를 확인합니다. 2분 내에 노드 2가 리더 (노드 1)가 오프라인 상태임을 감지하면 노드 2가 네트워크의 leader이 되도록 전환됩니다.

> state
router
Done
...
> state
leader
Done

확인되면 Docker bash 프롬프트로 돌아가기 전에 스레드를 중지하고 노드 2를 초기화합니다. 이 실습에서 사용한 스레드 네트워크 사용자 인증 정보가 다음 실습으로 전달되지 않도록 초기화합니다.

> thread stop
Done
> factoryreset
>
> exit
root@c0f3912a74ff:/#

factoryreset 명령어 뒤에 > 프롬프트를 다시 표시하려면 enter를 몇 번 눌러야 할 수도 있습니다. Docker 컨테이너를 종료하지 않습니다.

노드 1도 초기화하고 종료합니다.

> factoryreset
>
> exit
root@c0f3912a74ff:/#

사용 가능한 모든 CLI 명령어를 살펴보려면 OpenThread CLI 참조를 확인하세요.

4. 수수료로 노드 인증

이전 연습에서는 시뮬레이션된 기기 2개와 확인된 연결을 사용하여 스레드 네트워크를 설정합니다. 하지만 이 방법을 사용하면 기기 간에 인증되지 않은 IPv6 링크-로컬 트래픽만 전달할 수 있습니다. 전역 IPv6 트래픽을 스레드 간에 그리고 스레드 보더 라우터를 통해 인터넷으로 라우팅하려면 노드를 인증해야 합니다.

인증하려면 한 대의 기기가 감독자 역할을 해야 합니다. 감독자는 현재 새 스레드 기기에 대해 선택한 인증 서버이며, 기기가 네트워크에 참여하기 위해 필요한 네트워크 사용자 인증 정보를 제공하는 승인자입니다.

이 연습에서는 이전과 동일한 2노드 토폴로지를 사용합니다. 인증을 위해 스레드 리더는 감독자 역할을 하며 스레드 라우터는 조이너 역할을 합니다.

D6a67e8a0d0b5dcb.png

Docker

나머지 연습에서 각 노드 (터미널 창)의 경우 OpenThread 빌드로 Docker 컨테이너를 실행 중인지 확인합니다. 이전 실습을 진행했다면 동일한 Docker 컨테이너 내에 bash 메시지 두 개가 아직 열려 있어야 합니다. 그렇지 않은 경우 Docker 문제 해결 단계를 참조하거나 스레드 네트워크 시뮬레이션 실습을 다시 실행하면 됩니다.

1. 네트워크 만들기

노드 1에서 CLI 프로세스를 생성합니다.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1

참고: 이 명령어를 실행한 후 > 메시지가 표시되지 않으면 enter를 누릅니다.

새 작업 데이터 세트를 만들어 활성 데이터 세트로 커밋하고 스레드를 시작합니다.

> 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

이 데이터 세트를 활성 데이터 세트로 커밋합니다.

> dataset commit active
Done

IPv6 인터페이스를 불러옵니다.

> ifconfig up
Done

스레드 프로토콜 작업을 시작합니다.

> thread start
Done

몇 초 동안 기다린 후 기기가 스레드 리더가 되었는지 확인합니다.

> state
leader
Done

2. 위원 역할 시작

노드 1에서 다음과 같이 수수료자 역할을 시작합니다.

> commissioner start
Done

* 와일드 카드를 사용하여 J01NME 연결자 사용자 인증 정보로 모든 조인터를 네트워크에 커밋하도록 허용합니다. 조이너는 인간이 위탁한 스레드 네트워크에 추가하는 기기입니다.

> commissioner joiner add * J01NME
Done

3. Joiner 역할 시작

두 번째 터미널 창의 Docker 컨테이너에서 새 CLI 프로세스를 생성합니다. 노드 2입니다.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2

노드 2에서 J01NME 연결자 사용자 인증 정보를 사용하여 연결자 역할을 사용 설정합니다.

> ifconfig up
Done
> joiner start J01NME
Done

... 확인을 위해 잠시 기다립니다 ...

Join success

연결자인 기기 (노드 2)는 감독자 (노드 1)를 통해 자체 인증을 완료하고 스레드 네트워크 사용자 인증 정보를 받았습니다.

이제 노드 2가 인증되었으므로 스레드를 시작합니다.

> thread start
Done

4. 네트워크 인증 검사

노드 2에서 state를 확인하여 이제 네트워크에 연결되었는지 확인합니다. 2분 내에 노드 2가 child에서 router로 전환됩니다.

> state
child
Done
...
> state
router
Done

5. 구성 재설정

다음 실습을 준비하려면 구성을 재설정합니다. 각 노드에서 스레드를 중지하고 초기화한 후 에뮬레이션된 스레드 기기를 종료합니다.

> thread stop
Done
> factoryreset
>
> exit
root@c0f3912a74ff:/#

factoryreset 명령어 뒤에 > 프롬프트를 다시 표시하려면 enter를 몇 번 눌러야 할 수도 있습니다.

5. OpenThread Daemon으로 네트워크 관리

이 연습에서는 CLI 인스턴스 (삽입된 단일 SoC 스레드 기기) 하나와 라디오 공동 프로세서 (RCP) 인스턴스 하나를 시뮬레이션해 보겠습니다.

ot-daemon는 UNIX 소켓을 입력 및 출력으로 사용하는 OpenThread Posix 앱의 모드이므로 OpenThread 코어를 서비스로 실행할 수 있습니다. 클라이언트는 OpenThread CLI를 프로토콜로 사용하여 소켓에 연결하여 이 서비스와 통신할 수 있습니다.

ot-ctl는 RCP를 관리하고 구성하기 위해 ot-daemon에서 제공하는 CLI입니다. 이를 사용하여 스레드 기기에서 생성된 네트워크에 RCP를 연결합니다.

Docker

이 실습의 각 노드 (터미널 창)에서 OpenThread 빌드로 Docker 컨테이너를 실행 중인지 확인합니다. 이전 실습을 진행했다면 동일한 Docker 컨테이너 내에 bash 프롬프트 두 개가 이미 열려 있어야 합니다. 그렇지 않은 경우 Docker 문제 해결 단계를 참조하세요.

ot-daemon 사용

이 연습에서는 다음에 해당하는 세 개의 터미널 창을 사용합니다.

  1. 시뮬레이션된 스레드 기기의 CLI 인스턴스 (노드 1)
  2. ot-daemon 프로세스
  3. CLI 인스턴스 ot-ctl

1. 노드 1 시작

첫 번째 터미널 창에서 에뮬레이션된 스레드 기기의 CLI 프로세스를 생성합니다.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1

참고: 이 명령어를 실행한 후 > 메시지가 표시되지 않으면 enter를 누릅니다.

새 작업 데이터 세트를 만들어 활성 데이터 세트로 커밋하고 스레드를 시작합니다.

> 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

이 데이터 세트를 활성 데이터 세트로 커밋합니다.

> dataset commit active
Done

IPv6 인터페이스를 불러옵니다.

> ifconfig up
Done

스레드 프로토콜 작업을 시작합니다.

> 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
>

스레드 네트워크 시뮬레이션 단계에서 설명한 대로, 하나의 주소는 링크-로컬 (fe80)이고 세 개의 주소는 메시-로컬 (fd)입니다. EID는 주소에 ff:fe00을 포함하지 않는 메시-로컬 주소입니다. 이 샘플 출력에서 EID는 fd55:cf34:dea5:7994:460:872c:e807:c4ab입니다.

노드와 통신하는 데 사용할 ipaddr 출력에서 특정 EID를 식별합니다.

2. ot-demon 시작

두 번째 터미널 창에서 tun 기기 노드를 만들고 읽기/쓰기 권한을 설정합니다.

root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200
root@c0f3912a74ff:/# chmod 600 /dev/net/tun

이 기기는 가상 기기의 패킷 전송 및 수신에 사용됩니다. 기기가 이미 생성되었다면 오류가 발생할 수 있습니다. 이는 정상적인 현상이며 무시해도 됩니다.

노드 2를 호출하는 RCP 노드의 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)를 의뢰한 적이 없습니다. 여기에 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
>

세 번째 터미널 창에서 ot-ctl를 사용하여 두 번째 터미널 창에서 시작한 노드 2 (RCP 노드)를 ot-daemon로 관리합니다. 노드 2의 state를 확인합니다.

> state
disabled
Done

특정 Joiner로 조인을 제한하려면 Node 2의 eui64를 가져옵니다.

> eui64
18b4300000000001
Done

노드 1 (첫 번째 터미널 창)에서 Commissioner를 시작하고 해당 eui64로만 조인합니다.

> commissioner start
Done
> commissioner joiner add 18b4300000000001 J01NME
Done

세 번째 터미널 창에서 노드 2의 네트워크 인터페이스를 열고 네트워크에 연결합니다.

> ifconfig up
Done
> joiner start J01NME
Done

... 확인을 위해 잠시 기다립니다 ...

Join success

조인러로서 RCP (노드 2)가 수수료 (노드 1)로 성공적으로 인증되고 스레드 네트워크 사용자 인증 정보를 받았습니다.

이제 노드 2를 스레드 네트워크에 조인합니다 (다시 세 번째 터미널 창에서).

> thread start
Done

4. 네트워크 인증 검사

세 번째 터미널에서 노드 2의 state를 확인하여 이제 네트워크에 연결되었는지 확인합니다. 2분 내에 노드 2가 child에서 router로 전환됩니다.

> state
child
Done
...
> state
router
Done

5. 연결 확인

세 번째 터미널 창에서 Ctrl+D 또는 exit 명령어를 사용하여 ot-ctl를 종료하고 컨테이너의 bash 콘솔로 돌아갑니다. 이 콘솔에서 ping6 명령어와 함께 EID를 사용하여 노드 1을 핑합니다. ot-daemon RCP 인스턴스가 성공적으로 조인되어 스레드 네트워크와 통신하면 핑이 성공합니다.

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 노드를 만들 때 Operation not permitted 명령어를 사용하는 경우 (mknod 명령어 사용) 이 Codelab에서 제공하는 명령어에 따라 Docker를 루트 사용자로 실행해야 합니다. 이 Codelab에서는 루트리스 모드에서 Docker 실행을 지원하지 않습니다.

7. 축하합니다.

OpenThread를 사용하여 첫 번째 스레드 네트워크를 성공적으로 시뮬레이션했습니다. 사용하든,

이 Codelab을 통해 학습한 내용은 다음과 같습니다.

  • OpenThread 시뮬레이션 시뮬레이션 컨테이너 시작 및 관리
  • 스레드 네트워크 시뮬레이션
  • 스레드 노드 인증
  • OpenThread Daemon으로 스레드 네트워크 관리

Thread와 OpenThread에 관해 자세히 알아보려면 다음 참조를 살펴보세요.

또는 Docker 컨테이너의 OpenThread Border Router를 사용해 보세요.