Using flat‎ > ‎

다커(docker) in SBC

posted Apr 3, 2018, 10:07 AM by Sundew Shin   [ updated Apr 15, 2018, 4:27 AM ]
(이미지 출처: The Robot Academy)


1. 소개

여러분들은 다커(docker)를 들어보셨나요?
다커, 도커, docker. 뭐 어떻게 쓰고 부르던, 활용도가 높은 (서버)자원 가상화 기술로 몇년전부터 리눅스에서 작업하는 개발자들 사이에서 크게 각광 받고 있습니다.

그런 다커가, 얼마전부터 RPi와 기타 여러 SBC ('싱글보드컴퓨터')들의 핵심두뇌격인 ARM CPU코어(armhf)를 공식 지원하면서, 이제 우리 카페 같은 국내 SBC 커뮤니티들 곁으로도 바싹 다가왔습니다.


2. 장점

혹시 VMware 사용해 보셨나요?
그 메뉴중에는 가상머신의 현재 상태를 떠 놓는 '스넵샷' (snapshot) 이라는 기능이 있지요.
모든걸 완벽(!)하게 만들어 놓고 야심차게 첫번째로 떠놓는 스넵샷의 이미지는 가상머신 전체 파일크기와 같았습니다.
Windows XP 경우, 1GB, 뭐 이런식으로 말입니다.
그런데 얼마후 작업을 더하다가 두번째로 만드는 스넷샷의 파일크기는 그 보다는 훨씩 작았습니다. 100, 200MB, 이렇게 말이죠. 그것은 처음 스넵샷으로부터 더해지거나 변경된 데이터만을 포함하고 있기 때문입니다. (=incremental backup)

그런데, 다커에는 그 첫번째 가상머신 스넵샷에 해당하는것이 scratch라는 이름으로 처음부터 설치파일과 함께 배포 됩니다. 그래서 그 (Linux subsystem) 위에서 추가 작업을 한 결과물을 다른 머신으로 옮길 때는, 동일한 CPU core에서, 호환도 쉽고 파일크기도 작아지게 되는것이지요. 그런데 사실 여기까지는 VMware로도 비슷하게 따라 할 수 있습니다.

진짜 재미는 이제 부터 입니다.
MS윈도우즈와 달리 그 내부 운영 사정이 투명한 리눅스 기반이기 때문에, 다커는 우리가 수작업으로 했던 이 스넵샷 만드는 일을, 자동으로 더 세분화 해서 모든 변경점마다 만들고 색인(index hash)을 붙여 클라우드 저장소(docker registry)에 올려 통합 관리하는 것을 현실화 시켰습니다.
작업이 웹서버거나, 아니면 DB서버 구축이던지간에, 같은 목적을 위해 사람이 하는 일은 모두 거기서 거기이기 때문에, A에서 작업한 것을 B로 옮길 때 이제는 정말 천하유일(unique)한 컨텐츠만 옮기면 되니 그 파일크기는 더욱 작아 지고, 색인 가능해진 중간 스텝샷들 덕분에, 또한, 이어지는 작업들의 업무효율을 크게 높일 수 있게 되었습니다.

알듯 말듯하신가요?
일단, 이미 있는 RPi로 간단히 따라해 볼수 있으니, 남아있는 설치에서 맛보기 까지 꼭 한번 해보시기를 추천 드립니다.
참고로 이 글의 모든 설정 작업을 반영한 라즈비안 OS 이미지를 배포하고 있으니 그것을 사용 해 주셔도 좋습니다. 


3. 설치 (docker)

설치과정은 통합 인스톨러가 있어 아주 간단합니다. 

- 설치전에 먼저 환경업데이트를 합니다.
sudo apt-get update && sudo apt-get upgrade -y

- 설치파일을 받아 실행 시킵니다.
curl -sSL https://get.docker.com | sh​​

- 마지막으로 사용자 'pi'가 다커 작업을 할 수 있도록 해줍니다.
sudo usermod -aG docker pi​

모든 과정이 에러 없이 끝나면 명령줄에 'docker version'을 넣고 실행되는지 확인합니다.
아래 그림처럼 나오면 설치 완료.


참고로, 이 'docker'라는 실행명령은 Client에 해당하는 것이고, 파트너인 Server에 해당하는 것은 'dockerd'로, 이것은 설치 후미에 데몬(daemon)으로 실행되어 뒤에서 동작하고 있는데, 그것과 통신 해서 얻은 버젼정보를 이처럼 같이 인쇄해 주고 있는것입니다, 그래서, 위 명령을 쳤을 때 'Client' 버젼정보만 나온다면 어떤 이유에서인지 dockerd 데몬이 정상 실행되지 못한 것이니 더 진행에 앞서 먼저 그 문제를 해결 하셔야만 합니다.


4. 설치 (docker-compose)

조금만 사용하다보면 매번 명령줄에서 파라미터를 기억하고 바꾸는 작업이 쉽지 않다고 깨닿게 됩니다.
이런 작업을 설정파일에서 하도록 돕는것이 docker-compose 툴입니다.
저는 pip을 사용해서 설치 해 보겠습니다.

- pip을 최신버젼으로 맞춰 줍니다.
​​sudo apt-get install python-setuptools
​​sudo easy_install -U pip

- docker-compose를 설치 합니다.
​​sudo ​​pip install docker-compose

'docker-compose version' 명령으로 설치를 확인 합니다.



그러면 이제, 이 다커를 가지고 놀 준비가 모두 끝났습니다.


5. 맛보기: 워드프레스

RPi에 워드프레스를 설치 해 보겠습니다.
우리가 보통 어떻게 작업을 하는지 일반적인 설치 방법을 먼저 살펴 봅니다. 이 작업은 눈으로만 봐주세요.
1. AMP (Apache, MySQL, PHP) 환경을 먼저 만듭니다.
sudo apt-get update && apt-get install apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt php5-gd

2. 'mysql-server' 설정화면에서 root 암호를 정해 준다음,

3. 워드프레스를 최신버젼으로 설치 합니다.
sudo unzip -q latest.zip -d /var/www/html/
sudo chown -R www-data:www-data /var/www/html/wordpress
sudo mv /var/www/html/wordpress/* /var/www/html && sudo rm /var/www/html/wordpress -r
sudo chmod -R 755 /var/www/html
sudo mkdir -p /var/www/html/wp-content/uploads
sudo chown -R www-data:www-data /var/www/html/wp-content/uploads
cd /var/www/html
sudo cp wp-config-sample.php wp-config.php

3. 웹브라우져에서 http://[RPi IP]로 접속 해 봅니다.

4. 보통 웹화면에서 설치를 진행하면서 터미널에서는 'wp-config.php'파일을 수정하는데,
  - DB 사용자 접속이 안되는 문제가 생기면 2번단계로 가서 다시 작업을 하고요,
  - 설정 저장이 안되는 문제가 생기면 파일접근권한 문제이니 3번 단계에서 했던 작업들을 되짚어 봅니다.

(그러면서 괴로운 생각들에 휩싸입니다... '매번 설치할 때마다 격는 이 어려움은, 나의 한계인 것인가 아니면 7400만 웹사이트에서 사용하고있는 워드프레스의 문제인 것인가..')
자, 이번에는 다커로 해 보겠습니다. 이 작업은 직접 따라 해 주세요.

1. 명령줄에 다음을 넣고 실행 합니다.
docker run -d -p 88:80 joaquindlz/rpi-docker-wordpress

이런 내용입니다. 뒤에서 부터 명령 옵션을 읽어보면:
- (cloud에 있는) 다커 이미지, 'joaquindlz/rpi-docker-wordpress'를 사용해서,
- 다커 내부포트 (TCP)80을 외부에는 88로 포워딩해서,
  (저는 80이 사용중이라 88로 넘겼습니다. 아닌 경우는 '80:80'으로 하시면 됩니다.)
- 실행(웹서비스)이 백그라운드에서 유지되도록 데몬으로 돌린다.

이렇게 해서 만들어 지는 결과물(instance) 프로세스를 다커 컨테이너('container')라고 부릅니다. 그리고 아래와 같은 화면이 전개되어 나오는데요, 이것도 해설을 드리면:
'Pull complete'으로 끝나는 한줄 한줄은, 우리가 앞서 이야기 했던, 다커에서는 레이어('layer')라고 부르는 머쉰의 변경점마다 스넵샷을 만들어 놓은 이미지들이고요, 제일 앞에 '27256d35347a' 같이 붙는것이 바로 각 스넷샷을 찾아 재활용 할 수 있도록 붙은 키(hash)의 처음 12자 입니다. 이것들에는 다시 사람이 기억하기 쉽도록 테그('tag')를 붙일 수 있는데, 앞서 'joaquindlz/rpi-docker-wordpress'라고 하는 것도 그와 같은 특정 이미지에 붙은 테그중 하나 입니다.



2. 남은 일은 웹브라우져로 접속하고 나머지 사이트 설정을 진행하는 일입니다.



위에서 다커로 워드프레스를 RPi에 설치 해서 로그인까지 나오는데에, 저는 이 글을 쓰면서 했지만, 10분이 채 안걸린 것 같습니다. 여러분들은 얼마나 걸리셨는지 댓글로 남겨 주세요. 아쉽게도 1등을 위한 사은품은 준비되어 있지 않습니다.


6. docker-compose 사용

앞에서 워드프레스 컨테이너를 명령줄에서 직접 'docker' 명령으로 실행시켰었습니다.
하지만 동시에 여러개의 컨테이너를 운영할때는 일일이 명령줄에서 줬던 파라미터들을 실수없이 기억해 낸다는게 여건 번거러운게 아닙니다. 이 문제를 해결하기 위해 나온것이 위에서 설치 해 뒀던 docker-compose입니다. 똑같은 작업을 이번에는 이 docker-compose를 써서 해 보겠습니다.

- 편한 작업 위치로 이동합니다.
cd ~/

- 문서편집기로 'docker-compose.yaml' 파일을 만듭니다.
nano docker-compose.yaml

- 다음의 내용을 넣고 저장하고 나옵니다.
wordpress:
  container_name: wordpress
  image: joaquindlz/rpi-docker-wordpress
  ports:
    - 88:80  #또는 80:80
- 명령줄에서 다음과 같이 실행 합니다.
docker-compose up -d

이렇게 하면 docker-compose가 같은 이름의 yaml 파일을 읽어 들여서 그 안에 정의되어 있는 다커 컨테이너들을 연속적으로 배치(batch) 생성합니다.

자 그럼 퀴즈입니다.
아래와 같이 파일을 만들어 실행하면 어떻게 될까요?
wordpress:
  container_name: wordpress
  image: joaquindlz/rpi-docker-wordpress
  ports:
    - 88:80

wordpress:
  container_name: wordpress2
  image: joaquindlz/rpi-docker-wordpress
  ports:
    - 89:80

wordpress:
  container_name: wordpress3
  image: joaquindlz/rpi-docker-wordpress
  ports:
    - 90:80

바로 답을 말씀드리겠습니다.

그러면 아파치서 부터 MySQL DB까지, 3개의 완전히 격리된 워드프레스 사이트가 만들어 지게 됩니다.
이렇게라면 100개의 사이트도 순식간에 만들 수 있겠지요. 게다가 모두 같은 'joaquindlz/rpi-docker-wordpress' 이미지 파일을 공유하고 있어서 추가로 이미지를 다운로드하는 과정도 사라지게 됩니다.

물론 한 머쉰상에서 비효율적으로 100개의 개별 웹/DB서버 프로세스를 운용하는 일은 드문 일일것입니다. 하나의 컨테이너(예:DB)를 여러개의 컨테이너가 공유하는 방법도 나중에 알게 되실 것입니다.

그래도 아직 이러한 작업들을 모두 명령줄상에서 한다는것이 여간 부담 스러운 일이 아닙니다. 선택가능한 어떤 옵션들이 더 있는지도 한눈에 보기 어렵구요. 

7. 다커 in SBC

다커 활용에 또 한가지 주목할 만한 점은 프로그램 설치, 사용, 삭제가 간편하다는 것입니다. 아무리 복잡한 프로그램의 설치도 폴더 하나가 생기고 지워지는 정도로 단순해 졌기 때문입니다. (==containerized) 
리눅스에서 패키지나 라이브러리 등 공유자원 관리가 MS윈도우즈에 비할 바 아니게 간편하지만, 그렇다고 해도 프로그램 설치/삭제를 반복하다보면 점점 더 파일들이 쌓여가게 되고 일일이 찾아서 삭제 한다는 것이, 중급 수준의 사용자들에게도 결코 간단한 일이 아닙니다. 한편, MS윈도우즈상에서 일부 순정주의자(?)들은 C-드라이브가 거의 최초 설치 상태를 유지 하도록 포터블앱스(PortableApps.com)의 툴들을 애용하기도 하는데 다커의 휴대성(portability)은 그것과 일맥 통하는 바가 있습니다. 이 점은 RPi 등 싱글보드컴퓨터('SBC')를 사용하는 것에도 고려 해 볼 내용입니다.

예를 들어 하나의 RPi를 '웹서버->로봇제어->OpenCV개발->토런트->3D프린터서버->AI비서->아두이노개발->DB서버' 등, 이런 식으로 시간을 달리해서 다양하게 활용한다고 생각 해 봅시다. 필요한 일부 프로그램들은 깔끔하게 apt-get으로 'install/remove' 되지만, 나머지는 npm, cpan, pip, gpm 등 각종 언어별 패키지 메니져를 사용하거나, 그도 없으면 직접 소스코드를 찾아 컴퍼일 하게되고, 컴파일에 필요한 라이브러리는 또 사용자가 알아서 찾아다가 재위치에 먼저 놓아두어야 하는 수고가 따릅니다. 누군가가 실제로 설치/삭제 작업을 반복하며 단일 RPi의 용도를 이렇게 바꿔 나간다고 한다면 아마도 시작하고 나서 첫번째로 부딫이는 도움을 구할 수 없는 어려움에서 어디서부터 다시 시작 해야할지 망막하게 되기 쉬울 것입니다. 
아마 제일 확실한 방법은 여러개의 SD카드를 운영하는 것일텐데, 이것도 용도마다 SD카드를 새로 플래싱하고 터미널로 접속해서 기본 설정작업을 반복하는 일이 여간 번거러운 것이 아닙니다.

그럼 다커는 어떤가요.
docker run .. [실행 옵션 들] ..... --name=lamp wednus/rpi-lamp  # 웹서버(APM) 를 설치 합니다.
<개발 활동>
docker rm lamp    # 웹서버를 삭제 합니다.
docker rmi wednus/rpi-lamp    # 더이상 필요하지 않은 이미지를 삭제합니다.

docker run .... --name=opencv wednus/rpi-opencv    #OpenCV 개발 환경(!)을 구축 합니다.
<개발 활동>
docker rm opencv    # OpenCV를 삭제 합니다.
docker rmi wednus/rpi-opencv
.
.  <중략>
.
docker run ... --name=db wednus/rpi-mysql
docker rm db
docker rmi wednus/rpi-mysql
맨마지막 명령 실행을 마치면 RPi의 시스템상태는 다시 이 모든 작업을 하기 이전의 상태와 같아집니다.
이런면을 잘 생각 해 보면, 다커와 같은 리눅스 컨테이너 기술의 최대 수해자는 다름 아닌 SBC들일수도 있겠다는 생각이 들기 시작 합니다.


8. '플렛'

프로젝트 플렛('flat') 을 소개 합니다.
다커 활용을 돕기 위해 'Team 플렛'이 개발 하고 있는 웹GUI로 현재 ARM기반 SBC(RPi2, RPi3)를 지원하고 있습니다.
잘 알려진 포테이너(portainer) 소스에서 포킹(forking) 하여, SBC 지원을 위한 변경/기존 버그 수정작업들이 진행 되고 있습니다

포테이너와의 차이점은 무엇일까요?
짧은 답을 먼저 드리면, Portainer에서 되는 것은 플렛에서 모두 되고, 반대로 플렛에서만 되는 것들은 다음과 같습니다:
- GPIO, USB, serial, I2C, PiCam/webcam, 등 호스트 장치 연결
- arm전용 템플릿 (RPi에서는 Portainer의 기본 템플릿들을 사용할 수 없습니다: arm vs. amd)

이제 플렛이 시작 된 배경을 말씀 드리겠습니다.
다커 자체가, web/db/proxy/load balancing/security 등, 웹서비스를 제공하는 컨테이너 운영에 초점이 맞춰져 있습니다. 다커가 주목을 받는 이유도 클라우드 컴퓨팅이 대세가 되면서 그런것들을 조율하는 작업을 효율적으로 할수 있기 때문입니다.
그런데 이 모든 서비스들의 공통점은 호스트 서버(메인프레임)로 부터 SW적인 가상 리소스만 할당 받으면 된다는 것입니다. TCP/UDP 포트나 볼륨, 바인팅 타겟 같은 것들 말입니다.
그 때문에 포테이너를 포함한 지금까지 모든 관리툴들은 그런 가상리소스 매핑에 필요한 인터페이스와 그것들을 위한 내부작업만 되어 있습니다.
하지만, RPi를 비롯한 SBC들은, 다커 활용에 있어 이 모든것들 위에 더 필요한 것들이 있습니다. 즉 호스트에 연결된 물리 장치들을 직접 사용(access)하는데 필요한 준비들 말입니다. 가격/덩치는 작지만 개념적으로는 훨씬 더 큰 것이지요. 전통적인 컴퓨팅이 이제 'physical 컴퓨팅'으로 넘어가게 되는 것과 일맥 통하는 이야기 입니다.

앞으로 모든 업데이트는 '팀.플렛' 게시판에서 확인 하실 수 있습니다.



9. 도약

여기까지 저와 함께 해 주신 여러분들은 지금쯤 궁금한 것들이 많이 생기셨을것 같아요.
이 요술같은 일이 어떻게 가능할 수 있을까요? 
역시 그 뒤에는 많은 내용들이 있습니다만 그 모두를 여기에 다 담을 수는 없고, 이제부터 스스로 해답을 찾으려 노력하시는 분들의 몫으로 남겨 두겠습니다.

대신, 이 글에서 던지고 싶은 화두는 이런 것입니다:
지금까지 RPi나 다른 SBC로 했던 어렵고 힘들었던 작업들을 떠 올려 보세요.
그리고 상상합니다. '그 작업이 이미 되어 있는 다커 이미지가 있었다면, 또,
내가 만들어 다른 사람에게 나눈다면 어떨까.'
저는 이것이 아주 멋진 사건의 시작일 것이다라고 생각 하고 있습니다.
Comments