이 문서는 64 비트 컴퓨터에 docker 를 설치하고 이를 활용한 것에 대한 체험을 기술한 문서입니다. 

다음 사이트를 참조하면 도움이 될지 모릅니다. 

Docker 초보 요약 설명 - 심플 하고 좋다.  http://blog.iolo.kr/m/post/510
Docker 명령어 도움말   http://docs.docker.com/reference/commandline/cli/
Docker 기본 사용법  http://pyrasis.com/Docker/Docker-HOWTO
도커(Docker) 튜토리얼 : 깐 김에 배포까지  http://blog.nacyot.com/articles/2014-01-27-easy-deploy-with-docker/
Docker란 무엇인가? http://bcho.tistory.com/805
docker 를 이해하기 위하여 #1  http://judekim.tistory.com/15
오픈소스 슈퍼루키 Docker 이해 하기 
http://opennaru.tistory.com/m/post/entry/2013%EB%85%84-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EC%8A%88%ED%8D%BC%EB%A3%A8%ED%82%A4-Docker-%EC%9D%B4%ED%95%B4-%ED%95%98%EA%B8%B0
독커  http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/12/docker
Docker 치트 시트  https://gist.github.com/nacyot/8366310
docker getting started: 왕초보를 위한 docker 입문  http://blog.iolo.kr/510
Linking containers together - 네트워크 전략  http://blog.jongsunkim.pe.kr/archives/2288
(**) 관련 파일 시스템 

AUFS
devicemapper

 
(**) 시험 작업 환경 

pc : 우분투 12.04 64 비트  8 core 8G 메모리
host server : 192.168.10.61

(**) 왜?

저는 호기심이 많은지 이런 저런 것들을 하면서  설치하고 지우고 하는 패키지들이 많습니다.
이런 과정을 항상 문서로 남기는 편인데..
이때 가급적 초기 환경에서 설명하고 싶을 경우가 많습니다.
문제는 이전에 깔린 상태에 영향을 많이 받는 경우가 많다는 것입니다 .
그렇다고 virualbox 같은 것을 사용하는 것이 생각보다 무겁고 귀찮고
대부분 패키지 의존성인 경우가 많습니다. 
그래서 chroot 를 이용하는 방법을 썼는데..
몇가지 한계가 존재하는 것이 단점이었습니다. 
특히 최근에 웹 관련 설치나 환경 구축에서 더 심각합니다.
그런 와중에 docker 라고 하는 것을 발견하였습니다. 
칭찬이 자자한 놈인데..
회사에서도 동일 서버에 다양한 환경을 테스트 해보고 싶을 경우 유용할 듯 싶었습니다.
일단 설치와 간단한 테스트를 해 보기로 했습니다. 

(**) Docker 홈페이지

홈페이지는 다음에 있습니다.

https://www.docker.com/
(**) 참고 문서

이 글은 다음 사이트에 있는 글을 보고 진행하고 있습니다. 
http://pyrasis.com/Docker/Docker-HOWTO
http://blog.nacyot.com/articles/2014-01-27-easy-deploy-with-docker/
http://bcho.tistory.com/805
http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/12/docker
복 받으시라..

(**) 작업 환경 

다음과 같은 환경에서 시작했습니다. 
pc : 우분투 12.04 64 비트  8 core 8G 메모리
host server : 192.168.10.61
작업 디렉토리 : /home/frog/docker/
(**) 설치 

Docker는 리눅스 배포판 종류를 자동으로 인식하여 패키지를 설치해주는 스크립트를 제공합니다.
다음과 같이 수행 합니다.
$ cd ~/docker/
$ sudo wget -qO- https://get.docker.io/ | sh
작업 시간 : 14:20 - 14:22 : 2 분 소요
 
맙소사 정말 간단하게 설치가 끝났습니다. 
다음과 같이 동작을 확인 합니다. 
$ docker -v
Docker version 1.2.0, build fa7b24f

(**)  Docker 가 사용하는 포트 처리 

Docker 는 다음 포트를 사용하여 무언가 하게 됩니다. 
4243/tcp
만약 방화벽 관리를 하고 있다면 다음과 같은 명령으로 해당 포트를 열어 줍니다. 
$ sudo ufw allow 4243/tcp
규칙 갱신`됨
규칙 갱신됨(v6)

(**) sudo 명령 안 사용하게 하기 

Docker에서 행하는 많은 것들이 시스템을 건들기 때문에 sudo 를 대부분 사용하게 됩니다.
이거 귀찮으므로 현재 유저를 docker 구룹에 포함 합니다. 
다음과 같이 처리 하면 됩니다. 
$ sudo groupadd docker
$ sudo gpasswd -a ${USER} docker
$ sudo service docker restart
이제 재 로그인 합니다. 

이렇게 처리하면 docker group은 root와 같은 권한 가지고 있다는 꼭 기억하시고 
관련된 보안에 대한 고민을 하시기 바랍니다. (뭔 고민?)
(**) 온라인 Docker 명령어 도움말 

Docker 명령어에 대한 도움말을 영문이나마 얻고 싶다면 
다음을 방문 하시면 됩니다. 
http://docs.docker.com/reference/commandline/cli/

(**) 설치된 Docker 가 사용하는 데이터들은 어디에서 관리 되고 있나. 

수행중인 Docker 는 다음 위치에서 다양한 실행 데이터들을 관리 하고 있습니다. 
/var/lib/docker/
(**). 공식 저장소에 있는 이미지 정보 사이트

Docker 를 사용하기 위해서는 실행 이미지가 필요 합니다. 
여러분이 알고 있는 우분투나 레드햇 센트OS 같은 배포판 이미지입니다. 
물론 배포판과 다릅니다. 
시스템을 설치하고자 할때 쓰는 것이 아니고 
Docker 에서 사용하고자 하는 운영체제 이미지죠..
이런 이미지를 찾아야 하는데 공식적으로 이런 이미지들을 운영하고 
어떤 것이 있는지를 검색하는 곳이 다음 입니다. 
https://registry.hub.docker.com/
특정 이미지를 찾는 것은 이 웹 페이지를 이용하는 게 편합니다.
(**). 명령 창에서 이미지 검색 
만약 어떤 키워드를 이용해서 명령행에서 찾고 싶다면 다음과 같은 형식의 명령을 찾으면 됩니다. 
예를 들어 우분투 와 관련된 것을 찾고 싶다면
$ docker search ubuntu

이렇게 치면 되는데 

약간의 찾는 시간이 걸리고 나오더라도 엄청나게 많은 사람들이 올린 것 까지 모두 나와서 ㅠㅠ
어렵습니다. 

그냥 웹에서 검색하는 것이 좋습니다. 
(**). 우분투 이미지 12.04 받기 
전 12.04 우분투 패키지를 좋아 합니다. (지금 이글을 쓰는 시점에서는 14.04 로 갈아 탔습니다. ^^; )
그래서 공식적으로 지원되는 이미지를 받아 보기로 하겠습니다. 
보통 개인이 올린 것은 각 개인의 이름을 디렉토리 처럼 구분해서 쓰는데
공식적으로 지원되는 것은 이미지 이름만 지정하고 버전을 지정하면 됩니다. 
다음과 같은 방법으로 이미지를 받습니다. 
$ docker pull ubuntu:12.04
작업 시간 : 14:58  - 15:00 : 2 분 소요
진짜 이미지 빨리 받죠?
(**) 시스템에 설치된 이미지 리스트 보기 

아마도 이런 저런 이미지들을 받게 될지 모릅니다. 
이때 설치된 이미지들의 목록을 보고 싶다면 다음과 같이 명령을 치면 됩니다. 
$ docker images
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              12.04               c17f3f519388        9 days ago          106.7 MB
hello-world         latest              565a9d68a73f        9 weeks ago         922 B

어라 ?

설치된 이미지가 두개나 되네요?
이중 hello-world 는 처음 docker 를 인스톨 할때 딸려서 설치된 놈입니다. 
(**) 설치된 이미지 제거 

hello-world 는 뭐.. 굳이 사용하지 않을 가능성이 높으니 제거 하기로 하죠..
이미 설치된 이미지를 제거 하려면 다음 명령을 사용합니다. 
$ docker rmi  hello-world
참고로 지우려고 하는 이미지가 사용중에 있다면 제대로 지워지지 않는 점 꼭! 기억하세요
보통 이미지를 사용하는 컨테이너가 있을 경우인데.. 컨테이너는 다음 설명에서 알 수 있습니다.
(**) 설치된 우분투 이미지 실행하기 

자 이제 새로 설치된 우분투에서 무언가 하고 싶지 않습니까?
앞에까지 진행된 과정에서 제 시스템에는 두 가지 우분투가 있습니다. 
원래 시스템에 설치된 우분투 ..
그리고 이제 우분투 안에서 마치 다른 기계에서 동작하는 듯한 우분투 
Docker 에서는 우분투 이미지가 있으면 이 이미지를 이용해서 
독립적인 우분투 시스템을 동작 시킬 수 있죠..
여기서 이렇게 Docker 에 의해서 동작하는 우분투 시스템을 컨테이너라고 합니다. 
이 컨테이너는 한개의 이미지 당 하나만 동작하는 것이 아니고 여러 개를 동작 시킬 수 있습니다. 
이 각각의 컨테이너는 별도의 시스템 처럼 동작 합니다. 
서로 간섭하지 않죠..
자세한 개념의 설명은 귀찮고 
그냥 각 컨테이너는 하나의 프로그램이고 이 프로그램이 별도의 프로그램을 동작 시키는 개념이라고 
보아도 큰 무리가 없습니다. 
자 일단 시작 시키고 나서 생각해 봅시다. 
다음과 같이 시작 시킵니다. 
$ docker run -i -t --name test_ubuntu ubuntu:12.04 /bin/bash
root@167987439c33:/#
이 명령을 실행하면 바로 배쉬 쉘로 떨어 집니다. 
뭐 이게 Docker 에 의해서 설치된 우분투죠.. 
이 설치된 우분투는 최소한의 설치이기 때문에 할 수 있는게 별로 없습니다. 
ping 명령을 한번 실행해 보면 당장 알 수 있습니다. 
root@167987439c33:/# ping 127.0.0.1
bash: ping: command not found

이제 다른 쉘로 접속해서 원래 시스템 우분투로 접속 해서 진행해야 합니다. 
그전에 위 명령의 의미를 살펴 봅시다. 
특정 컨테이너를 실행하기 위해서는 docker run 명령을 사용합니다. 
이때 형식은 보통 다음과 같게 됩니다. 
docker run <옵션> <이미지 이름> <실행할 파일>
여기서 옵션에는 여러가지가 있지만 위에서 사용한 옵션은 
-i : 표준 입력 stdin 을 연 상태로 시작합니다. 사용자 입력을 허가 하는 옵션입니다. 
-t : 의사 터미널을 사용하는 것을 허가 하는 옵션입니다. 
--name : 컨테이너의 이름을 지정하기 위한 옵션입니다. 
 생성된 컨테이너의 ID 보다 이 이름으로 관리하는 것이 편하죠..
 
(**). 동작 중인 컨테이너 목록 보기 

현재 시스템에 동작 중인 컨테이너의 목록을 보기 위해서는 ps 란 명령을 사용합니다. 
$ docker ps 
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
167987439c33        ubuntu:12.04        "/bin/bash"         8 minutes ago       Up 8 minutes                            test_ubuntu

각각의 의미는 다음과 같습니다.

CONTAINER ID : docker 가 부여한 컨테이너 프로그램 ID
IMAGE : 컨테이너가 사용한 이미지 
COMMAND : 컨테이너가 실행한 명령
CREATED : 컨테이너 생성 시점
STATUS : 컨테이너 현재 동작 상태
PORTS : 컨테이너가 사용중인 포트 수 
NAMES : 컨테이너 이름
이 명령을 -a 을 주지 않으면 정지된 컨테이너는 표출되지 않는다는 점 주의 하세요
(**). 컨테이너 동작 중지 

컨테이너의 동작을 중지 시키는 방법에는 두가지가 있습니다. 
컨테이너가 수행을 요구했던 프로그램을 종료 하는 것과 
외부에서 docker 명령으로 중지 시키는 방법입니다. 
우선 실행된 컨테이너 창에서 exit 를 수행합니다. 
그러면 원래 시스템의 설치된 우분투의 쉘 로 돌아 오게 됩니다. 
하지만 이때 컨테이너 목록을 다음과 같이 보면 컨테이너는 살아 있음을 알 수 있습니다. 
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS               NAMES
167987439c33        ubuntu:12.04        "/bin/bash"         19 minutes ago      Exited (127) About a minute ago                       test_ubuntu

STATUS 이 Exited 되었다고 나옵니다. 
(**) 컨테이너 삭제 
컨테이너를 삭제 하고자 할때는 다음과 같은 명령을 사용하면 됩니다. 
$ docker rm test_ubuntu
test_ubuntu

이제 목록을 보면 컨테이너가 완전히 삭제 됨을 알수 있습니다.
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
(**). 동작 중인 컨테이너를 삭제 한다면?

다음과 같이 경고가 나오면서 실패 합니다. 
반드시 컨테이너를 중지 시킨 후 삭제 해야 합니다.
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
84fd809005cb        ubuntu:12.04        "/bin/bash"         2 minutes ago       Up 2 minutes                            test_ubuntu

$ docker rm test_ubuntu
Error response from daemon: You cannot remove a running container. Stop the container before attempting removal or use -f
2014/09/14 15:41:46 Error: failed to remove one or more containers
(**) 외부에서 강제 중지 

이제 외부에서 동작 중인 컨테이너를 중지 시켜 보겠습니다. 
$ docker stop test_ubuntu
약간의 시간이 걸리면서 실행 했던 창에서 시스템 우분투 쉘로 복귀 되고 
컨테이너 목록을 보면 중지 상태 임을 알 수 있습니다. 
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
84fd809005cb        ubuntu:12.04        "/bin/bash"         6 minutes ago       Exited (-1) 56 seconds ago                       test_ubuntu
(**). 다시 시작 및 재 진입

이제 중지된 컨테이너를 다시 시작 시켜 보겠습니다. 
$ docker start test_ubuntu
test_ubuntu

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
84fd809005cb        ubuntu:12.04        "/bin/bash"         7 minutes ago       Up 16 seconds                           test_ubuntu
시작은 했지만 원래 동작만 되었지 무언가 변화는 없습니다. 

여기에 실행했던 컨테이너 쉘로 들어가 볼까요?
$ docker attach test_ubuntu

엔터를 한번 치시면 # 쉘로 떨어지고 진입하는 것을 알수 있습니다. 
/bin/bash를 실행했기 때문에 명령을 자유롭게 입력할 수 있지만, 
DB나 서버 어플리케이션을 실행하면 입력은 할 수 없고 출력만 보게 됩니다.

Bash Shell에서 exit 또는 Ctrl+D를 입력하면 컨테이너가 정지됩니다. 
Ctrl+P, Ctrl+Q를 차례대로 입력하면 컨테이너를 정지하지 않고, 컨테이너에서 빠져나올 수 있습니다.

start  와 같은 명령으로 restart  가 있는데 
restart 는 리부팅과 같은 효과를 나타냅니다. 
다음과 같은 형태로 사용할 수 있습니다 .
$ docker restart test_ubuntu
(**). 변경된 상황은 컨테이너를 삭제하기 전까지만 보관된다. 

컨테이너는 삭제 전까지 내부에 있는 내용 들이 보존됩니다.  
언제까지 보존 될까 ?
다음과 같은 시험을 통해서 알아 보시죠. 

이제 컨테이너를 삭제하고 새로 시작해 보겠습니다.  
( 아래 실행 결과들은 이 문서를 작성하면서 여러 번 수행한 상태라서 일치 하지 않습니다. 
 그냥 이런식으로 나온다는 정도로 이해해 주기 바랍니다.)
동작 중인 컨테이너를 중지하고 지웁니다. 
root@167987439c33:/# exit
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS               NAMES
be184e8826ac        ubuntu:12.04        "/bin/bash"         2 minutes ago       Exited (127) About a minute ago                       test_ubuntu
$ docker rm test_ubuntu

여기서 다음 디렉토리를 보겠습니다.
$ sudo ls -al /var/lib/docker/containers
합계 8
drwx------ 2 root root 4096  9월 15 16:58 .
drwx------ 9 root root 4096  9월 15 16:58 ..
아무것도 없음을 알 수 있습니다.
이제 다시 컨테이너를 실행해 봅니다. 
$ docker run -i -t --name test_ubuntu ubuntu:12.04 /bin/bash
oot@6a3cfee58b20:/#
이 창에서는 컨테이너의 배쉬 쉘이 수행된 상태이므로 다른 창으로 로긴하여 

수행 상태를 봅니다. 
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
6a3cfee58b20        ubuntu:12.04        "/bin/bash"         About a minute ago   Up About a minute                       test_ubuntu
이제 /var/lib/docker/containers 디렉토리를 다시 봐 보면...

$ sudo ls -al /var/lib/docker/containers
합계 12
drwx------ 3 root root 4096  9월 15 17:00 .
drwx------ 9 root root 4096  9월 15 17:00 ..
drwx------ 2 root root 4096  9월 15 17:00 6a3cfee58b2071bd8e64cbc39820412d7b1e6653c1c6f6f62992650ec7b6e585

디렉토리가 하나 생겼는데 컨테이너 ID 와 매칭되는 디렉토리 임을 알 수 있습니다. 

즉 컨테이너 하나를 실행하면 이곳에 관련 컨테이너 정보에 해당하는 디렉토리가 생성되고 관리 됩니다.. 
이제 컨테이너 쉘에서 exit 명열을 통해 중지해 보죠. 
root@6a3cfee58b20:/# exit
exit
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
6a3cfee58b20        ubuntu:12.04        "/bin/bash"         3 minutes ago       Exited (0) 5 seconds ago                       test_ubuntu

컨테이너는 중지된 상태로 나오게 됩니다. 
/var/lib/docker/containers 디렉토리를 다시 봐 보겠습니다.

$ sudo ls -al /var/lib/docker/containers
합계 12
drwx------ 3 root root 4096  9월 15 17:00 .
drwx------ 9 root root 4096  9월 15 17:00 ..
drwx------ 2 root root 4096  9월 15 17:00 6a3cfee58b2071bd8e64cbc39820412d7b1e6653c1c6f6f62992650ec7b6e585

역시 관리되고 있음을 알 수 있습니다. 
이 상태에서 시스템을 재 부팅한 후 
정상적으로 로긴 후 컨테이너를 재 시작 시키고 들어 갈 수 있는지 확인해 보겠습니다. 
먼저 시스템을 리부팅 시키고 
정상적으로 로그인 하여 쉘로 들어 간 후 
$ docker start test_ubuntu
test_ubuntu
$ docker attach test_ubuntu
root@6a3cfee58b20:/#

정상적으로 들어 갈 수 있음을 알수 있습니다. 
앞에서 했던 것 처럼 컨테이너를 제거 해 보겠습니다.

root@6a3cfee58b20:/# exit
exit
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
6a3cfee58b20        ubuntu:12.04        "/bin/bash"         11 minutes ago      Exited (0) 6 seconds ago                       test_ubuntu
$ docker rm test_ubuntu
test_ubuntu
$ sudo ls -al /var/lib/docker/containers
합계 8
drwx------ 2 root root 4096  9월 15 17:12 .
drwx------ 9 root root 4096  9월 15 17:12 ..
깔끔하게 지워짐을 알 수 있습니다.

(**). 패키지 설치 및 보존 관계 확인 

앞에서 가져온 우분투 12.04 이미지는 ping 명령이 설치 되어 있지 않습니다. 
다음과 같은 과정을 통해서 설치해 보겠습니다.
$ docker run -i -t --name test_ubuntu ubuntu:12.04 /bin/bash
root@497f3090b20d:/# apt-get update
Get:1 http://archive.ubuntu.com precise Release.gpg [198 B]
Get:2 http://archive.ubuntu.com precise-updates Release.gpg [198 B]
Get:3 http://archive.ubuntu.com precise-security Release.gpg [198 B]
:
:
Get:38 http://archive.ubuntu.com precise-proposed/main i386 Packages [230 kB]
Get:39 http://archive.ubuntu.com precise-proposed/restricted i386 Packages [649 B]
Fetched 29.0 MB in 11s (2422 kB/s)
Reading package lists... Done
root@497f3090b20d:/# apt-get install iputils-ping
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
 iputils-ping
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 56.1 kB of archives.
After this operation, 143 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB]
Fetched 56.1 kB in 1s (36.3 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package iputils-ping.
(Reading database ... 7551 files and directories currently installed.)
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ...
Setting up iputils-ping (3:20101006-1ubuntu1) ...
root@497f3090b20d:/# ping www.google.co.kr
PING www.google.co.kr (173.194.127.127) 56(84) bytes of data.
64 bytes from hkg03s12-in-f31.1e100.net (173.194.127.127): icmp_req=1 ttl=50 time=82.4 ms
64 bytes from hkg03s12-in-f31.1e100.net (173.194.127.127): icmp_req=2 ttl=50 time=84.6 ms
^C
--- www.google.co.kr ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 82.437/83.542/84.648/1.142 ms
root@497f3090b20d:/#
이제 exit 로 나가서 중지 시키고 다시 시작해서 정상적으로 ping 이 되는지 확인하여 
패키지 설치가 보존 되었는지를 확인해 보겠습니다. 
root@497f3090b20d:/# exit
exit
$ docker start test_ubuntu
test_ubuntu
$ docker attach test_ubuntu

root@497f3090b20d:/# ping www.google.co.kr
PING www.google.co.kr (173.194.127.111) 56(84) bytes of data.
64 bytes from hkg03s12-in-f15.1e100.net (173.194.127.111): icmp_req=1 ttl=50 time=85.0 ms
64 bytes from hkg03s12-in-f15.1e100.net (173.194.127.111): icmp_req=2 ttl=50 time=82.8 ms
64 bytes from hkg03s12-in-f15.1e100.net (173.194.127.111): icmp_req=3 ttl=50 time=85.2 ms
^C
--- www.google.co.kr ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 82.880/84.387/85.276/1.097 ms
root@497f3090b20d:/#

잘되죠?

오늘은 여기까지 헉헉....