(**). docker volume

컨테이너에서 동작하는 응용 프로그램이 파일에 데이터를 쓰면 
이 데이터는 컨테이너가 삭제 되기 전 까지는 보존 됩니다. 
그런데...
컨테이너를 삭제한다면?
예 변경된 내용이 모두 소실 됩니다. 
이것을 막는 방법은 commit 를 이용해서 이미지화 하는 방법이 있지만.. 
이런식으로 이미지화 하여 이용한 데이터는 
매 컨테이너가 실행 될 때마다 이미지화 한 상태부터 시작할 것이고 
한 컨테이너에서 변경된 내용은 다른 컨테이너에서는 이용이 불가능합니다. 
또한 이미지로 만드는 방법은 데이터를 만드는 방법으로는 너무 느린 방법이죠
또 호스트와 데이터 교환에도 문제가 있습니다. 
어쨌든 ...
1) 호스트의 특정 디렉토리와 docker 컨테이너의 디렉토리를 연동 시킬때 
2) 컨테이너와 컨테이너의 디렉토리를 연동 시킬떄 
이런 문제들을 해결 하려면 docker 의 volume 을 사용할 수 있어야 합니다. 
만약 2) 번째에서 컨테이너끼리만 연동 하고 호스트와 연동하지 않을 경우에는 
다음 강좌에서 설명할 볼륨 컨테이너라는 개념을 이용하게 될 겁니다. 
이번 강좌는 이 호스트 특정 디렉토리와 
컨테이너의 디렉토리를 연동하고자 하는 방법에 대하여 알아 봅니다. 
(**)  busybox 이미지 

여기서 잠깐 유명한 docker 의 유명한 이미지 중에서 busybox 라는 이미지를 사용해 봅시다. 
보통 쉘 명령을 처리 하거나 간단한 프로그램을 수행할 때 
필요한 유틸리티를 다 담고 있으면서 크기가 정말 작은 이미지가 없을까?
하고서 만든 것이 이 busybox  입니다. 
busybox 는 원래 임베디드에서 작은 메모리와 작은 파일 시스템 장치의 크기 때문에 나온 프로젝트죠
이걸 이런식으로 이미지에 핵심 구성 요소로 지정하고 동작 할 수 있게 만든 겁니다. 
이미지를 받아 보죠?
$ docker pull busybox  
크기와 종류를 알아 봅시다. 

$ docker images
:
:
busybox             buildroot-2013.08.1   d200959a3e91        3 months ago        2.489 MB
busybox             ubuntu-14.04          37fca75d01ff        3 months ago        5.609 MB
busybox             ubuntu-12.04          fd5373b3d938        3 months ago        5.455 MB
busybox             buildroot-2014.02     a9eb17255234        3 months ago        2.433 MB
busybox             latest                a9eb17255234        3 months ago        2.433 MB
우선 종류 많죠? 크기를 볼까요? 거의 6M 안쪽이죠? 진짜 작죠?

그래도 이 이미지에 필요한 것들은 다 있답니다. 
자 간단하게 컨테이너 동작을 시험해 볼까요?

$ docker run -i -t --name s busybox
/ #
/ # ls -al
total 60
drwxr-xr-x   29 root     root          4096 Sep 18 09:29 .
drwxr-xr-x   29 root     root          4096 Sep 18 09:29 ..
-rw-------    1 root     root             7 Sep 18 09:29 .ash_history
-rwxr-xr-x    1 root     root             0 Sep 18 09:29 .dockerenv
-rwxr-xr-x    1 root     root             0 Sep 18 09:29 .dockerinit
drwxrwxr-x    2 root     root          4096 May 22 23:24 bin
drwxr-xr-x    4 root     root           360 Sep 18 09:29 dev
drwxr-xr-x    6 root     root          4096 Sep 18 09:29 etc
drwxrwxr-x    4 root     root          4096 May 22 23:25 home
drwxrwxr-x    2 root     root          4096 May 22 23:24 lib
lrwxrwxrwx    1 root     root             3 May 22 23:02 lib64 -> lib
lrwxrwxrwx    1 root     root            11 May 22 23:22 linuxrc -> bin/busybox
drwxrwxr-x    2 root     root          4096 Feb 27  2014 media
drwxrwxr-x    2 root     root          4096 Feb 27  2014 mnt
drwxrwxr-x    2 root     root          4096 Feb 27  2014 opt
dr-xr-xr-x  278 root     root             0 Sep 18 09:29 proc
drwx------    2 root     root          4096 Feb 27  2014 root
lrwxrwxrwx    1 root     root             3 Feb 27  2014 run -> tmp
drwxr-xr-x    2 root     root          4096 May 22 23:24 sbin
dr-xr-xr-x   13 root     root             0 Sep 18 09:29 sys
drwxrwxrwt    3 root     root          4096 May 22 23:24 tmp
drwxrwxr-x    6 root     root          4096 May 22 23:24 usr
drwxrwxr-x    4 root     root          4096 May 22 23:25 var
특별한 명령이 없어도 쉘로 바로 떨어 집니다.
앞으로 실험은 이걸로 하겠습니다. ^^
(**)  -v 옵션 

-v 옵션 사용은 

-v [호스트 절대 경로]:[컨테이너 절대 경로] 
이런식으로 지정하게 되어 있습니다. 
예를 들면 
호스트의 /test 란 디렉토리를 컨테이너에는 /app 란 디렉토리로 지정한다고 하면 

다음과 같이 지정하면 됩니다. 
-v /test:/app
(**) 호스트의 디렉토리와 컨테이너간의 디렉토리의 연동 

먼저 다음과 같은 디렉토리를 하나 만듭니다. 
$ sudo mkdir /test
그리고 다음과 같이 한번 컨테이너를 실행해 봅시다. 
$ docker run -i -t --name s -v /test:/test busybox
그리고 컨테이너에서 다음 명령을 이용해서  파일을 만듭니다.
/ # echo "hello" > /test/t.txt
그리고 다른 호스트에서 /test 디렉토리를 봅니다. 
$ ls -al /test/
합계 12
drwxr-xr-x  2 root root 4096  9월 18 18:55 .
drwxr-xr-x 27 root root 4096  9월 18 18:39 ..
-rw-r--r--  1 root root    6  9월 18 18:55 t.txt

컨테이너에서 /test/ 디렉토리의 변경 사항이 호스트의 /test 에 반영 되는 것을 볼 수 있습니다. 
그럼 다른 컨테이너를 만들고 이 디렉토리의 변화를 볼까요?
$ docker run -i -t --name d -v /test:/test busybox
/ # ls -al /test/
total 12
drwxr-xr-x    2 root     root          4096 Sep 18 09:55 .
drwxr-xr-x   30 root     root          4096 Sep 18 10:03 ..
-rw-r--r--    1 root     root             6 Sep 18 09:55 t.txt
역시 ... 
이 d 컨테이너에서 파일을 하나 더 만들고 s 컨테이너와 호스트 측에서
변경되는지를 보죠..
/ # echo "ok" > /test/t2.txt
s 컨테이너에서 내용을 보면 변경되어 있고 
/ # cat /test/t2.txt
ok
/ #

호스테에서도 변경되어 있음을 알 수 있습니다. 
$ cat /test/t2.txt
ok

(**)  -v 옵션을 컨테이너 디렉토리를 내부에 이미 있는 디렉토리를 지정해도 될까요?

일단 현재 까지 생성된 컨테이너를 모두 지우고 시작합시다. 

busybox 컨테이너안에는 여러 디렉토리가 있습니다.  
이중에 /var/www 디렉토리를 이용해 보죠..
다음과 같이 s 컨테이너를 실행합니다.
$ docker run -i -t --name s -v /test:/var/www busybox
이제 컨테이너 안에 있는 /var/www 디렉토리의 내용을 봅니다. 
/ # ls -al /var/www
total 16
drwxr-xr-x    2 root     root          4096 Sep 18 10:04 .
drwxrwxr-x    4 root     root          4096 May 22 23:25 ..
-rw-r--r--    1 root     root             6 Sep 18 09:55 t.txt
-rw-r--r--    1 root     root             3 Sep 18 10:04 t2.txt
보시다 시피 잘 마운트 됩니다.

우리가 알고 있는 마운트 동작 방식에서 벗어 나지 않습니다. 
컨테이너에서 수정하면 반영될까요?
다음과 같이 수정해 봅니다. 
/ # echo "hello 2" > /var/www/t.txt
이제 호스트에서 수정되었나 봅시다. 

$ cat /test/t.txt
hello 2

수정된 것을 확인 할 수 있습니다. 
(**)  -v 옵션을 여러개 써 도 될까요?

필요에 따라서 볼륨을 여러개 지정하고 싶을 때 가 있죠..
그렇다면 -v 옵션을 여러개 쓸 수 있을 까요?
시험을 위해서 이전 컨테이너는 모두 지우시고 
다음과 같은 디렉토리를 하나 더 만들죠..
$ sudo mkdir /test2/
그리고 파일을 다음과 같이 만듭니다. 

$ sudo echo "hello test2" > /test2/data.txt
$ sudo chmod 777 /test2
$ echo "hello test2" > /test2/data.txt
이제 다음과 같이 s 컨테이너를 실행합니다. 
$ docker run -i -t --name s -v /test:/var/www -v /test2:/test busybox

디렉토리가 어떻게 지정되어 있는지 확인해 보죠..
/ # ls /var/www
t.txt   t2.txt
/ # ls /test/
data.txt
/ #
마지막으로 마운트가 어떻게 되어 있는지 볼까요?
/ # mount
rootfs on / type rootfs (rw)
none on / type aufs (rw,relatime,si=42d1b5e4227238f8)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,mode=755)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /var/www type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /test type ext4 (rw,relatime,errors=remount-ro,data=ordered)
devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime)
tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755)

컨테이너 내부에 다음과 같이 마운트 되어 있음을 알 수 있죠..
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /var/www type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/disk/by-uuid/afe15eb9-807a-408e-98c0-9b079a1f7557 on /test type ext4 (rw,relatime,errors=remount-ro,data=ordered)
뭐 깊이 있기 들어가 보지는 맙시다. 
나중에 시간내면 분석해 드리죠.. ( 보장 할수는 없지만 ㅎㅎ )