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

1. 소개

26b7f4f6b3ea0700.png

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

스레드 사양은 홈 애플리케이션을 위한 IPv6 기반의 안정적이고 안전하며 저전력 무선 기기 간 통신 프로토콜을 정의합니다. OpenThread는 IPv6, 6LoWPAN, MAC 보안이 적용된 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 - IP 경로 추가와 같은 네트워크 관련 작업을 실행할 수 있는 NET_ADMIN 기능을 사용 설정합니다.

컨테이너에 들어가면 다음과 비슷한 프롬프트가 표시됩니다.

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 라디오 에뮬레이션 (포트 = 9000 + 파일 설명자)을 위해 UDP 포트에 바인딩할 때도 사용됩니다. 이 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 = 링크-로컬로 시작

메시 로컬 주소 유형은 다음과 같이 추가로 분류됩니다.

  • ff:fe00 = 라우터 로케이터 (RLOC) 포함
  • ff:fe00 = 엔드포인트 식별자 (EID)가 포함되지 않음

콘솔 출력에서 EID를 확인하고 나중에 사용할 수 있도록 기록해 둡니다. 위 샘플 출력에서 EID는 다음과 같습니다.

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. 노드 2 시작

새 터미널을 열고 현재 실행 중인 Docker 컨테이너에서 bash 셸을 실행하여 Node 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 |

0x5800의 노드 2 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

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

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

factoryreset 명령어를 실행한 후 > 프롬프트를 다시 표시하려면 enter를 몇 번 눌러야 할 수도 있습니다. Docker 컨테이너를 종료하지 마세요.

또한 노드 1을 초기화하고 종료합니다.

> factoryreset
>
> exit
root@c0f3912a74ff:/#

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

4. 커미셔닝으로 노드 인증

이전 연습에서는 시뮬레이션된 기기 두 개로 스레드 네트워크를 설정하고 연결을 확인했습니다. 하지만 이렇게 하면 인증되지 않은 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. 커미셔너 역할 시작

Node 1에 있는 동안 커미셔너 역할을 시작합니다.

> commissioner start
Done

J01NME 조이너 사용자 인증 정보가 있는 모든 조이너 (* 와일드 카드 사용)가 네트워크에 커미셔닝되도록 허용합니다. 조이너는 인간 관리자가 커미셔닝된 스레드 네트워크에 추가한 기기입니다.

> commissioner joiner add * J01NME
Done

3. 조이너 역할 시작

두 번째 터미널 창의 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 데몬으로 네트워크 관리

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

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

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

Docker

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

ot-daemon 사용

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

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

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-daemon 시작

두 번째 터미널 창에서 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)를 위임하지 않았습니다. 이때 ot-ctl가 사용됩니다. ot-ctl는 OpenThread CLI 앱과 동일한 CLI를 사용합니다. 따라서 다른 시뮬레이션된 스레드 기기와 동일한 방식으로 ot-daemon 노드를 제어할 수 있습니다.

세 번째 터미널 창을 열고 기존 컨테이너를 실행합니다.

$ docker exec -it codelab_otsim_ctnr bash

컨테이너에 들어가면 ot-ctl를 시작합니다.

root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl
>

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

> state
disabled
Done

특정 조이너에 대한 참여를 제한하기 위해 노드 2의 eui64를 가져옵니다.

> eui64
18b4300000000001
Done

노드 1 (첫 번째 터미널 창)에서 커미셔너를 시작하고 해당 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 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에 제공된 명령어에 따라 루트 사용자로 Docker를 실행하고 있는지 확인하세요. 이 Codelab에서는 루트 권한 없는 모드로 Docker를 실행하는 것을 지원하지 않습니다.

7. 축하합니다.

OpenThread를 사용하여 첫 번째 스레드 네트워크를 시뮬레이션했습니다. 좋습니다.

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

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

스레드와 OpenThread에 대해 자세히 알아보려면 다음 참고 자료를 살펴보세요.

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