완벽한 IT 인프라 구축을 위한 Docker

isbn: 9788956747903

서버를 다시 설정하는 과정 중 Docker가 어떤 물건인지 이해하려 책을 선택했다. 초판이 2016년 출판 되었는데, it와 거리가 있어 보이는 일본 작가가 책을 썼다. 지금이야 사람들이 많이 docker를 사용하여 인터넷에서 많은 정보를 쉽게 찾는데, 2016년에 docker 가능성을 보고 어렵게 정보를 수집, 정리하여 책을 낸 저자 판단이 시대를 읽었다 본다. 너무도 파판화딘 리눅스 인프라 구축에 많은 고통을 받았다 본다.

처음 접하는 사람도 쉽게 읽을 수 있게 책을 썼다. Dockerfile로 빌드 정도는 할 수 있지만, 네트웍 설정, 볼륨 설정 등 복잡한 내용이 많다. entrypoint, cmd 활용 예시만 이해해도 책을 읽을 가치가 있다. 인터넷을 한없이 찾기보다, 이런 저자가 쓴 쉽게 읽히는 책을 읽는 게 더 빠르다. cmd와 entrypoint로 옵션을 전달하는 방법은 신박하다.

파편화된 리눅스 생태계에서 docker가 삶을 편한하게 한다. 아 내 두달치 기록. docker로 설정했으면 아직도 살아 있을지도…

sensehat 온도 + LED matrix(2)

제한된 화면에 온도, 습도를 어떻게 표시할까 고민하다, 디바이스를 2개를 만들로 했다. 사용자가 디바이스 개수를 제한 없이 만들 수 있는 점이 좋다. 2개를 만들어 온도로 한 개, 습도로 한 개를 할당 했다.

위 그림에서 사용자가 rs-tmpre1를 읽어(read) module이 저장한 HTS221 온도 관련 레지스터 값을 얻는다. 사용자가 받은 값으로 온도를 계산한 후 LED Matrix를 빨강으로 설정하고, 커널로 쓴다(write). 사용자가 rs-tempre2를 읽어(read) module이 저장한 HTS221 습도 관련 레지스터 값을 얻는다. 역시 받은 값으로 습도를 계산하고, LED Matrix를 녹색으로 설정, 커널로 쓴다(write). 사용자 프로그램이 일정 주기로 계속한다.

LED Matrix가 숫자를 보여주는 방식이 너무 촌스럽다. 좀 개선해야 겠다.

  1. 부팅
  2. 내가 만든 모듈 로딩
  3. 사용자 프로그램 실행

1 ~ 3번을 자동으로 하고 싶었다. 이게 좀 까다롭다. 처음에는 간단하게 crontab으로 @reboot로 설정했으나, 실패했다. 모듈이 올라가기 전에 사용자 프로그램이 실행된다. 찾던 중 udev가 이벤트를 감지(디바이스 추가, 삭제)하여 사용자 정의 행동을 한다고 알았다.

udev에 등록하려면 디바이스 정보를 알아야 된다. 왜 class로 추가하는지 느꼈다. 인터넷 검색으로 다음과 같이 알아냈다.

pi@raspberrypi:~ $ udevadm info /dev/rs-tmpre1
P: /devices/virtual/rpi-sensehat/rs-tmpre1
N: rs-tmpre1
L: 0
E: DEVPATH=/devices/virtual/rpi-sensehat/rs-tmpre1
E: DEVNAME=/dev/rs-tmpre1
E: DEVMODE=0666
E: MAJOR=235
E: MINOR=0
E: SUBSYSTEM=rpi-sensehat

pi@raspberrypi:~ $ udevadm info /dev/rs-tmpre2
P: /devices/virtual/rpi-sensehat/rs-tmpre2
N: rs-tmpre2
L: 0
E: DEVPATH=/devices/virtual/rpi-sensehat/rs-tmpre2
E: DEVNAME=/dev/rs-tmpre2
E: DEVMODE=0666
E: MAJOR=235
E: MINOR=1
E: SUBSYSTEM=rpi-sensehat

pi@raspberrypi:/dev $ udevadm info -a -n /dev/rs-tmpre1

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/virtual/rpi-sensehat/rs-tmpre1':
    KERNEL=="rs-tmpre1"
    SUBSYSTEM=="rpi-sensehat"
    DRIVER==""
    ATTR{power/control}=="auto"
    ATTR{power/runtime_active_time}=="0"
    ATTR{power/runtime_status}=="unsupported"
    ATTR{power/runtime_suspended_time}=="0"

아래 스크립트와 같이 사용자 정의 rules를 만들면 전원이 들어가면서 실행됨을 확인 했다.

pi@raspberrypi:/etc/udev/rules.d $ pwd
/etc/udev/rules.d
pi@raspberrypi:/etc/udev/rules.d $ cat 100-sensehat.rules 
ACTION=="add", SUBSYSTEM=="rpi-sense-tmpre", KERNEL=="rs-tmpre2", RUN+="/bin/sensehat_display"

아쉽게도 udev로 등록한 프로세가 오래 못산다. 이벤트가 끝나면 process가 죽는다. systemctl로 서비스 형식으로 등록해야 한다. 참조하여 아래와 같이 설정했다. 잘 된다. 이제 LED matrix를 어떻게 해 봐야겠다.

pi@raspberrypi:/etc/systemd/system $ cat sensehat_display.service 
[Unit]
Description=SenseHat Temperatur & Humidity Monitor

[Service]
Type=simple
ExecStart=/usr/bin/sensehat_display

[Install]
https://github.com/now0930/sensehat_toy

참조 사이트

sensehat 온도 + LED matrix(1)

온도를 LED Matrix에 표시하기

나름 쓸만한 디바이스를 만들기 위해 온도계를 구상해 봤다. 지마켓에서 온도, 습도, 시각을 측정하는 디바이스를 5,400원에 구매할 수 있다. 라즈베리 파이 + sensehat = 120,000원 정도 하려나? 약 20배 비싸지만 인터넷에 연결되어 싸다고 세뇌시키고 있다. ^^! 그런데, sensehat에 있는 hts221이 보드에 붙어 있다. 실내 온도를 측정하지 않고 보드 온도를 측정 하고 있다.

HTS221로 받은 온도를 LED matrix에 표시했다. 숫자를 바로 LED matrix에 표시할 수 없어, 각 숫자에 맞춰 8 * 8 * 3가지 색을 정의 해야 한다. 이게 참 시간을 잡아먹는다. 왜 frame buffer를 써야 되는지 알 만했다.

기본 설정으로는 온도를 바로바로 측정할 수 없다. 02h 레지스터 ODR을 1Hz로 설정해야 바로 측정할 수 있다. 12.5Hz로 측정하면 왜 안되는지 잘 모르겠다.

kernel에서 float 형식을 사용할 수 없다. 모든 데이터를 받아 사용자 영역에서 float 형식으로 온도를 계산해야 할 듯 하다. 지금은 user program이 led matrix를 써 주면 바로 표시하지만, timer나 workqueue를 추가하여 필요할 때 표시하게 수정할 것 이다. 아니면 습도도 받아 그래프로 표시하던가. 온도, 습도를 표시하려면 그래프가 좋아 보인다.

코드

참조 사이트

https://github.com/ControlEverythingCommunity/HTS221/blob/master/C/HTS221.c

sensehat i2c led2472g(2)

pixel 제어하기

8 * 8 LED matrix 색, 위치를 개별 제어하려면 픽셀 주소, 색을 알아야 한다. 가로 8, 세로 8, 1 점 당 rgb 3개 = 192개 주소가 rgb 값을 갖는다. 여러 삽질과 인터넷 검색으로 아래 정보를 확인 했다. 개별 소자를 다음과 같이 제어할 수 있다.

$>i2cset 1(i2c 채널 번호) 0x47?(노드 번호) 0x1(점 주소) 0x10(색 값)

각 점별 최대 0x63을 입력할 수 있다. 0x63을 넘어가면 다른 픽셀에 영향을 미치는지 깜박였던 것 같다. python으로 작성한 LED matrix display 코드를 그대로 사용해도 된다. 각 좌표에서 1을 빼야 된다.

픽셀로 제어하다 보니 폰트, 그림 이런 거 없다. 왜 frame buffer로 제어했는지 이제 이해간다!!

참조 사이트

sensehat i2c led2472g

I2C에 연결된 LED Matrix 밝기 제어

sensehat 모듈에 LED matrix가 i2c로 설치, 연결되어 있다. LED2472G가 각 연결된 LED를 제어하는데, AVR이 i2c로 라즈베리 파이와 LED2472G 를 중계한다. LED를 제어한다고 LED2472G datasheet를 찾으면 별 도움이 안된다. AVR로 led를 어떻게 제어하는지 잘 공개되지 않은 듯 하다. 아무리 찾아도 c로 작성한 코드를 찾을 수 없다. i2c 0x46에 0~191까지 밝기를 전송하면 led 밝기를 제어할 수 있다. 아래 game of life python 코드를 보면 대충 어떻게 돌아가는지 알 수 있다.

shell로 i2cset으로 한 개씩 램프를 껐다. 0x46번은 LED matrix 노드 번이고, 0 ~ 191까지 led 램프 위치를 말하는 듯 하다. 뒤에 255, 0은 밝기다. 컬러 코드를 넣는 방법이 있는데, 아직 잘 모르겠다.

pi@raspberrypi:~/rasp/sense_temperature $ i2cset 1 0x46 1 255
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-1, chip address 0x46,
data address 0x01, data 0xff, mode byte.
Continue? [Y/n] y
pi@raspberrypi:~/rasp/sense_temperature $ i2cset 1 0x46 1 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-1, chip address 0x46,
data address 0x01, data 0x00, mode byte.
Continue? [Y/n] y
pi@raspberrypi:~/rasp/sense_temperature $ i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x08-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- 46 -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- 5f 
60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                   

shell로 0부터 191까지 해보면 led가 꺼지지 않는데 루프를 만들어 돌리면 한 번에 꺼진다. 구매 5일만에 led를 껐다.

고수는 frame buffer를 만들어서 하는 것 같은데, 아직 잘 모르겠다. 정말 필요한지도 모르겠다.

참조 사이트