최근에 쿠버네티스를 공부할 일이 있어서 보고 있는데, 쿠버네티스 자체가 도커(Docker) 오케스트레이션을 해주는 툴이라 도커에 대한 개념이 없으니, 공부하기가 힘들었습니다. 그래서 이렇게 급하게 책을 사서 공부하면서 내용을 정리하고자 합니다.

해당 내용은 위키북스에서 나온 시작하세요! 도커 책을 보면서 정리한 내용입니다. 책의 내용이 매우 좋아서 강추합니다.

도커의 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이라 쓰기가 불가능합니다. 그렇기에 컨테이너 계층에 변화되는 데이터들이 저장이 되는데, 이럴 경우, 컨테이너가 삭제가 되면 그동안 저장된 운용데이터들이 함께 삭제가 됩니다. 이렇게 되면, 복구도 불가능해지기 때문에, 컨테이너의 데이터를 영속적 데이터로 활용할 수 있는 방법에 대해서 알아보도록 하겠습니다.


호스트 볼륨 공유

첫번째 방법으로는 호스트(내 컴퓨터)와 저장장소를 공유하는 방법입니다.

$ docker run -d \                                  # -d : 컨테이너를 백그라운드에서 동작하는 어플리케이션으로 실행하도록 합니다.
> --name wordpressdb_hostvolume \                  # --name : 컨테이너 이름은 wordpressdb_hostvolume 
> -e MYSQL_DATABASE=wordpress \                    # -e : 환경변수 설정, MySQL Database는 wordpress
> -e MYSQL_ROOT_PASSWORD=password \                # -e : 환경변수 설정, MySQL 비밀번호는 password 
> -v /Users/jungwoon/wordpress_db:/var/lib/mysql \ # -v : 공유할 디렉토리 설정, -v [호스트 디렉토리]:[컨테이너 디렉토리]
> mysql:5.7                                        # 이미지는 mysql:5.7

a2ed0209e4796f1aa8bf2aa6734b4e4bfaaf232fbe0370b7413487ea539ed11a

위에서 핵심은 -v 옵션으로 공유할 호스트 디렉토리컨테이너 디렉토리를 설정합니다.

$ docker run -d \                       # -d : 컨테이너를 백그라운드에서 동작하는 어플리케이션으로 실행하도록 합니다.
> --name wordpress_hostvolume \         # --name : 컨테이너 이름은 wordpress_hostvolume 
> -e WORDPRESS_DB_PASSWORD=password \   # -e : 환경변수 설정, Wordpress DB 패스워드는 password
> --link wordpressdb_hostvolume:mysql \ # --link : wordpressdb_hostvolume 컨테이너를 mysql라는 이름으로 접근하겠다고 설정 
> -p 80 \                               # -p : 80 번 포트를 포트 포워딩 하겠다는 의미입니다.
> wordpress                             # wordpress 이미지를 사용합니다.

91dba38bf769cde94571f761687c6bdba47ed3b3712b56fa44c39616e27dc4a2

실제 호스트에서 wordpress_db의 내용을 보면 새로 생성이 되면서 컨테이너와 동일한 파일이 생길걸 확인할 수 있습니다.

$ ls -al wordpress_db
total 387152
drwxr-xr-x@  20 jungwoon  staff       640  1 13 17:23 .
drwxr-xr-x+  65 jungwoon  staff      2080  1 13 17:27 ..
-rw-r-----    1 jungwoon  staff        56  1 13 17:22 auto.cnf
-rw-------    1 jungwoon  staff      1679  1 13 17:22 ca-key.pem
-rw-r--r--    1 jungwoon  staff      1107  1 13 17:22 ca.pem
-rw-r--r--    1 jungwoon  staff      1107  1 13 17:22 client-cert.pem
-rw-------    1 jungwoon  staff      1679  1 13 17:22 client-key.pem
-rw-r-----    1 jungwoon  staff      1342  1 13 17:23 ib_buffer_pool
-rw-r-----    1 jungwoon  staff  50331648  1 13 17:23 ib_logfile0
-rw-r-----    1 jungwoon  staff  50331648  1 13 17:22 ib_logfile1
-rw-r-----    1 jungwoon  staff  79691776  1 13 17:23 ibdata1
-rw-r-----    1 jungwoon  staff  12582912  1 13 17:23 ibtmp1
drwxr-x---   77 jungwoon  staff      2464  1 13 17:22 mysql
drwxr-x---   90 jungwoon  staff      2880  1 13 17:22 performance_schema
-rw-------    1 jungwoon  staff      1679  1 13 17:22 private_key.pem
-rw-r--r--    1 jungwoon  staff       451  1 13 17:22 public_key.pem
-rw-r--r--    1 jungwoon  staff      1107  1 13 17:22 server-cert.pem
-rw-------    1 jungwoon  staff      1679  1 13 17:22 server-key.pem
drwxr-x---  108 jungwoon  staff      3456  1 13 17:22 sys
drwxr-x---    3 jungwoon  staff        96  1 13 17:23 wordpress

이 경우에는 이제 wordpressdb_hostvolume컨테이를 지워도 호스트에는 데이터가 남게 되어 데이터를 보존할 수 있습니다.

그럼 호스트에 있는 wordpress_db를 다시 새로운 컨테이너를 만들면서 -v옵션을 설정하면 어떻게 될까요?

$ docker run -i -t \                             # -i : 인터렉티브, -t : tty 설정
--name volume_override \                         # --name : 컨테이너 이름
-v /home/jungwoon/wordpress_db:/home/test        # -v : 볼륨을 공유 [호스트 볼륨]:[컨테이너 볼륨]
sampleimage                                      # 이미지 이름

이 경우에는 wordpress_db/host/test를 덮어버리게 됩니다.


볼륨 컨테이너

볼륨을 사용하는 또 다른 방법으로는 -v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것입니다.

컨테이너 생성시 --volumes-from 옵션을 사용하면 -v 옵션이 적용된 컨테이너의 볼륨 디렉토리를 공유할 수 있습니다.

$ docker run -i -t \
> --name volumes_from_container \          # --name : 컨테이너 이름
> --volumes-from wordpressdb_hostvolume \  # --volumes-from [컨테이너 이름] : -v가 설정된 컨테이너의 볼륨을 같이 공유
> wordpress                                # 이미지 이름

그럼 다음과 같은 상태가 됩니다.


도커 볼륨

세번째 방법은 docker volume 명령어를 이용하여, 도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수도 있습니다.

docker volume create 명령어로 도커 볼륨을 생성해보도록 하겠습니다.

$ docker volume create --name myvolume  # --name : myvolume 이름의 볼륨 생성
myvolume

다음 명령어로 생성된 볼륨을 확인합니다.

$ docker volume ls
DRIVER              VOLUME NAME
local               myvolume

tip) 볼륨 생성시 여러 플러그인을 이용하여 다양한 종류의 백엔드도 사용할 수 있습니다.

위에서 만들어진 볼륨(=myvolume)을 이용하여 컨테이너를 생성해보겠습니다.

$ docker run -i -t --name myvolume \   # --name : 이름을 지정하는 옵션으로, 컨테이너의 이름은 movolume
> -v myvolume:/root/ \                 # -v [볼륨의 이름]:[컨테이너의 공유 디렉토리], 볼륨과 컨테이너의 /root/를 공유
> ubuntu:14.04                         # 이미지 이름

이제 변화를 보기 위해서 컨테이너에서 파일을 만들어 보겠습니다.

root@bede36093185:/# echo hello, volume! >> /root/volume

그 다음 동일한 볼륨(=myvolume)을 공유하는 다른 컨테이너를 생성해보겠습니다.

$ docker run -i -t --name another_myvolume \  # 이름만 another_myvolume으로 위와 동일
> -v myvolume:/root/ \
> ubuntu:14.04

/root/를 확인해보면 위에서 만든 volume이 있는걸 확인할 수 있습니다.

root@c5236c3f68b6:/# cat /root/volume
hello, volume!

이렇게 동일한 볼륨을 공유함으로써 데이터를 공유할 수 있게 됩니다.


stateless vs stateful

  • stateless : 위와 같이 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계 방식
  • stateful : 컨테이너가 데이터를 저장하는 설계방식