Embedded Linux/Raspberry Pi

라즈베리파이와 PC에서 개발환경을 꾸미는 방법에는 여러가지가 있다.

보통 ssh, scp나 rsync를 사용하는데, 개인적으로는 RSYNC를 사용하는 방법을 선호한다.

ssh나 scp는 target board(라즈베리파이) 에 소스코드를 보관하고 원격에서 접속해서 소스코드를 수정하는 방식이고, rsync는 target board와 host pc 양쪽에 소스코드를 보관하면서 동기화 하는 방식이다.

(Target board) — (Network) — (Windows 10 PC)

PC에서는 보통 VS Code를 사용해서 editing을 하는데, extentions를 활용해서 개발환경을 더 쉽게 꾸밀 수 있다.

rsync를 선호하는 다른 이유는 예전 프로젝트에서 MIPS 아키텍쳐의 target 보드에서 개발했는데, VS Code extentions의 ssh 가 arm과 x86 계열만 지원했기 때문에 rsync에 익숙해져서이기도 하다.

준비

  • Windows PC
    • WSL(Windows Subsystem for Linux)
    • VS Code

VS Code, WSL 설치

여기서 다룰 내용은 아님. Ubuntu 20-04를 설치함.

WSL에 sshpass 설치

PC에서 라즈베리파이로 rsync로 동기화 하려면 ssh를 기본적으로 사용한다. 때문에 라즈베리파이의 username/password 가 필요하다.

물론 인증서 기반으로 할 수도 있겠지만, VS Code에서 자동으로 동기화 하려니까 어떻게 하는지 모르겠다..

설치 방법은 WSL을 실행한 후에 아래 명령을 입력한다.

$ sudo apt install sshpass
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  sshpass
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 10.5 kB of archives.
After this operation, 30.7 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 sshpass amd64 1.06-1 [10.5 kB]
Fetched 10.5 kB in 1s (10.1 kB/s)
Selecting previously unselected package sshpass.
(Reading database ... 32169 files and directories currently installed.)
Preparing to unpack .../sshpass_1.06-1_amd64.deb ...
Unpacking sshpass (1.06-1) ...
Setting up sshpass (1.06-1) ...
Processing triggers for man-db (2.9.1-1) ...

VS Code에 sync-rsync extension 설치

VS Code에서 rsync를 사용하는 방법은 WSL이나 cygwin 을 설치해야한다.

위에서 WSL을 설치 했다.

settings.json 수정

sync-rsync 연결을 위해서 setting.json에 관련 내용을 추가한다.

{
    "sync-rsync.shell": "sshpass -p \"raspberry\" ssh -p 22",
    "sync-rsync.remote": "pi@<ip-address>:/home/pi/work/",
    "sync-rsync.local": "/mnt/c/workspace/", 
    "sync-rsync.onSave": true, 
    "sync-rsync.onSaveIndividual": true, 
    "sync-rsync.exclude": [ 
           ".vscode", 
           ".git", 
           ".gitignore",
           ], 
     // 파일과 디렉토리의 권한 설정 
     "sync-rsync.chmod": "D2775,F664", 
     "sync-rsync.flags": "rlptv", 
     "sync-rsync.useWSL": true, 
 }

위에 처럼 설정하면 라즈베리파이의 "/home/pi/work/" 디렉토리와 PC의 "/mnt/c/workspace" 를 동기화 할 수 있다.

"/mnt/c/" 는 WSL에서 windows의 C 드라이브를 mount 해 놓은 것이다.

파일 동기화 하기

VS Code에서 작업 디렉토리 "/mnt/c/workspace" 를 오픈한 후에 "F1"을 눌러 command 창을 띄운다.

여기서 sync-rsync를 입력하면 몇가지 기능이 나온다.

  • Sync Remote to Local: target(라즈베리파이)의 파일을 PC로 가져와 동기화 한다.
  • Sync Local to Remote: PC의 파일을 target에 동기화 한다.

자동 동기화

파일을 수정하고 저장(Ctrl+S) 하면 자동으로 동기화가 진행된다.

Embedded Linux/OpenWrt

 

OpenWrt에서 네트워크 응용을 운영하다보면 설정에 의해 네트워크 포트 액세스를 허용/제한 설정을 해야 하는 경우가 있다.

 

firewall 에 rule 추가

SNMP 서비스 액세스를 허용/제한 하기 위해 가장 간단하다고 생각하는 방법은 아래와 같다.

root@OpenWrt:~# uci set firewall.snmp=rule 
root@OpenWrt:~# uci set firewall.snmp.name='reject snmp traffic' 
root@OpenWrt:~# uci set firewall.snmp.src='wan' 
root@OpenWrt:~# uci set firewall.snmp.dest_port='161' 
root@OpenWrt:~# uci set firewall.snmp.target='REJECT' 
root@OpenWrt:~# uci set firewall.snmp.enabled='0' 
root@OpenWrt:~# uci commit

 

위에 명령을 입력하면 firewall에 아래처럼 저장된다.

여기서 사용된 option은 아래와 같다. 특정 ip, port, 날짜 지정 등의 옵션을 사용할 수 있지만 사용 목정에 맞게 심플하게 추가했다.

  • src: "zone name"의 형태로 트래픽 소스 zone을 선택한다. zone 은 network 설정에서 선택한다.
  • dest_port: rule을 적용할 port이다. snmp 서비스 액세스를 제어할 거니까 '161'을 설정
  • target: rule 동작 방법 ("ACCEPT", "REJECT". "DROP", "MARK", NOTRACK") 중 "REJECT" 선택
  • enabled: 이 rule을 사용할지 사용 안할지 선택.

 

위 설정에 의해 enabled가 '1'인 경우 SNMP 포트(161)을 REJECT 하고, enabled가 '0' 인 경우 ACCEPT 하는 rule을 생성했다.

 

방화벽 설정
방화벽 설정 방화벽 설정은 /etc/config/firewall에 있습니다. 개요 OpenWrt는 패킷 필터링, NAT 및 mangling을 위해 netfilter를 사용합니다. UCI 방화벽은 iptables system에서 추상화 된 인터페이스를 제공하여 사용자가 필요한 경우 iptables 규칙을 스스로 제공 할 수있게하면서 가장 일반적인 목적에 맞는 단순한 설정 모델을 제공합니다
https://openwrt.org/ko/docs/guide-user/firewall_configuration#rules

 

 

테스트

먼저, enabled option이 0인 경우 (SNMP ACCEPT)시에는 SNMP 요청에 응답하는 것을 볼 수 있다.

 

root@OpenWrt:~# uci set firewall.snmp.enabled='0' 
root@OpenWrt:~# uci commit 
root@OpenWrt:~# /etc/init.d/firewall reload

 

 

 

이후 SNMP REJECT enable option을 1로 바꾸고 firewall을 reload 하면 SNMP 서비스를 제한할 수 있다.

root@OpenWrt:~# uci set firewall.snmp.enabled='1' 
root@OpenWrt:~# uci commit 
root@OpenWrt:~# /etc/init.d/firewall reload

 

  • SNMP요청에 timeout 발생

 

Embedded Linux/Docker

 

Docker에서 python 스크립트를 실행하려고 한다.

1. Docker에 Python 설치

 

(2021-06-03) 기준으로 python.org 에서 release 된 stable 버전은 3.9.5이다.

때문에 docker hub에서 3.9.5 버전의 alpine 버전을 다운로드 받았다.

https://hub.docker.com/_/python

위 링크에서 TAG를 보고 원하는 버전을 선택하면 된다.

docker pull python:3.9-alpine
  • alpine 버전은 alpine 리눅스 기반으로 제작된 이미지라고 한다.
  • 나중에 알게 되었지만, 라즈베리파이에서는 alpine 버전이 동작하지 않았다.
  • python:3.9-slim 으로 다시 설치함

 

2. Docker에서 Python 스크립트 실행

 

Docker build를 해서 custom 컨테이너를 만들고 Python 스크립트를 실행할 예정이다.

python 스크립트

아래처럼 간단하게 python 코드를 작성한다.

print("python app start")

 

우선 잘 동작하나 테스트.

 

 

Dockerfile 작성

 

FROM python:3.9-slim  WORKDIR /home/pi/work/docker COPY . /home/pi/work/docker  CMD ["python", "app.py"]

처음이라 이것저것 넣고 빼고 테스트를 해보았는데, 위에 4개[FROM, WORKDIR, COPY, CMD]가 기본인 듯 하다.

 

이렇게 작성하면 끝

 

Docker build & Run

 

빌드 명령.

docker build -t test1:v3 .

test1은 컨테이너 이름, v3은 태그명 으로 보면 되겠다. 이렇게 빌드하면 아래처럼 확인된다.

 

실행

docker run test1:v3 .

 

 

  • 라즈베리파이에서 python alpine 버전을 사용했을 경우에는 아래처럼 에러가 발생한다.
pi@raspberrypi:~/work/docker $ docker run python:3.9-alpine Fatal Python error: init_interp_main: can't initialize time Python runtime state: core initialized PermissionError: [Errno 1] Operation not permitted  Current thread 0xb6f4b390 (most recent call first): <no Python frame>

 

검색해보니, alpine 버전은 glibc가 아니라 musl libc를 사용해서 C라이브러리 의존성에 문제가 있을 수 있다고 한다.

https://jadehan.tistory.com/58

'Embedded Linux > Docker' 카테고리의 다른 글

Raspberry pi 4에 Docker 설치  (0) 2021.06.03
1 2 3 4 ··· 14
블로그 이미지

IoT 개발자 블로그이고 싶다.

1byte