일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- filewriter filereader
- 스레드 제어와 생명 주기
- Thread
- 컨테이너
- 쓰레드
- 자료구조
- Docker
- Kubernetes
- 알고리즘
- 인프런
- container
- java network
- 쿠버네티스
- 도커
- 시작하세요 도커 & 쿠버네티스
- 자바
- java socket
- 김영한
- Java IO
- 스레드
- 동시성
- 자바 입출력 스트림
- java
- 리스트
- 도커 엔진
- 멀티 쓰레드
- Collection
- 실전 자바 고급 1편
- 자바 io 보조스트림
- LIST
- Today
- Total
쌩로그
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 볼륨 본문
목차
- 포스팅 개요
- 본론
- 요약
1. 포스팅 개요
이 포스팅은 위키북스 출판사의 '시작하세요! 도커/쿠버네티스'의 제 2장 도커 엔진에서 도커 볼륨
에 대한 부분을 학습하며 기록한 포스팅이다.
참고
윈도우를 사용한다면 커맨드(CMD)보단 WSL 을 사용하자.
또한 학습하다보면 디렉터리를 확인할 수 있다고 하는 부분이 있는데,
윈도우에서는 아무리 찾아도 확인하려는 디렉터리를 찾아볼 수 없는 경우가 있었다.
2. 본론
도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며,
컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존한다.
예를 들면 위에서 생성했던 mysql 컨테이너는 mysql:5:7
이라는 이미지로 생성됐지만 워드프레스 블로그를 위한 데이터베이스 등의 정보는 컨테이너가 갖고 있다.

- 생성된 이미지는 어떠한 경우로도 변경되지 않는다.
- 컨테이너 계층에 원래 이미지에서 변경된 파일시스템 등을 저장한다.
예를 들면 이미지에 mysql을 실행하는데 필요한 애플리케이션 파일이 들어있다면 컨테이너 계층에는 워드프레스에서 쓴 로그인 정보나 게시글 등과 같은 데이터베이스를 운용하면서 쌓이는 데이터가 저장된다.
단점(치명적)
mysql 컨테이너 삭제시 컨테이너 계층에 저장돼있던 데이터베이스의 정보도 삭제된다.
도커의 컨테이너는 생성과 삭제가 매우 쉽기 때문에 실수로 컨테이너를 삭제하면 데이터를 복구할 수 없다.
위와 같은 이유로 컨테이너의 데이터를 영속적(Persistent) 데이터로 활용할 수 있는 방법이 있는데, 그중 가장 활용하기 쉬운 방법이 볼륨을 활용하는 것이다.
볼륨을 활용하는 방법
- 호스트와 볼륨을 공유할 수 있다.
- 볼륨 컨테이너를 활용할 수 있다.
- 도커가 관리하는 볼륨을 생성할 수 있다.
호스트와 볼륨을 공유하는 방법
※주의 : 가급적 WSL을 이용하자.
$ docker run -d --name wordpressdb_hostvolume -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -v /home/wordpress_db:/var/lib/mysql mysql:5.7
$ docker run -d -e WORDPRESS_DB_PASSWORD=password --name wordpress_hostvolume --link wordpressdb_hostvolume:mysql -p 80 wordpress
위 명령어로 mysql 데이터베이스 컨테이너와 워드프레스 웹 서버 컨테이너를 생성했다.
중간에 -v
옵션이 있는데,(-v /home/wordpress_db:/var/lib/mysql
) 해당 값을 /home/wordpress_db:/var/lib/mysql
로 설정한 것이다.
이는 **호스트의 home/wordpress_db
와 컨테이너의 /var/lib/mysql
디렉터리를 공유하는 것이다.
[호스트의 공유 디렉터리]:[컨테이너의 공유 디렉터리]
형태이다.
참고로 미리 호스트에 /home/wordpress_db
디렉터리를 호스트에 생성하지 않았어도 도커는 자동으로 이를 생성한다.
(윈도우에선 이 경로가 없다.)
아래 경로에서 데이터베이스 관련 파일이 있는지 확인할 수 있다.
$ ls /home/wordpress_db/
auto.cnf ca.pem client-key.pem ib_logfile0 ibdata1 mysql performance_schema public_key.pem server-key.pem wordpress
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 ibtmp1 mysql.sock private_key.pem server-cert.pem sys
mysql을 구동하는 데 필요한 각종 파일이 공유된 것이다.
mysql, performance schema, sys, wordpress 디렉터리는 mysql에 존재하는 실제 데이터베이스에 대응된다.
컨테이너를 삭제해서 데이터베이스의 데이터가 보존되는지 확인해보자.
$ docker stop wordpress_hostvolume wordpressdb_hostvolume
$ docker rm wordpress_hostvolume wordpressdb_hostvolume
# 삭제 후 ls
$ ls /home/wordpress_db/
auto.cnf ca.pem client-key.pem ib_logfile0 ibdata1 mysql.sock private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 mysql performance_schema public_key.pem server-key.pem wordpress
그래도 남아있는 것을 볼 수 있다.
-V
옵션을 써서 컨테이너의 디렉터리를 호스트와 공유한 것을 그림으로 나타내면 다음과 같다.
컨테이너의 /var/lib/mysql
디렉터리는 호스트의 /home/wordpress_db
디렉터리와 동기화되는 것이 아니라 완전히 같은 디렉터리이다.

참고
참고로 디렉터리 단위의 공유뿐 아니라 단일 파일 단위의 공유도 가능하며, 동시에 여러 개의 -V 옵션을 쓸 수 있다.
$ echo hello >> /home/hello && echo hello2 >> /home/hello2
$ docker run -i -t --name file_volume -v /home/hello:/hello -v /home/hello2:/hello2 ubuntu:latest
# cat /hello && cat /hello2
hello
hello2
원래 호스트에는 /home/wordpress_db 디렉터리가 존재하지 않았다.-v
옵션을 사용함으로써 호스트에 /home/wordpress_db
디렉터리가 생성되면서 해당 디렉터리에 파일이 공유됐다.
컨테이너의 파일이 호스트로 복사된 것이다.

만약 호스트에 이미 디렉터리와 파일이 존재하고 컨테이너에도 존재할 때 두 디렉터리를 공유 하면 어떻게 될까?
이를 확인하기 위해 alicek106/volume_test
라는 이미지를 활용한다.
이 이미지의 /home
디렉터리에는 testdir_2
라는 디렉터리가 있고, test
라는 파일이 있다.
아래 명령어로 컨테이너를 생성해서 /home/testdir_2
라는 디렉터리를 확인하면 파일이 있는 것을 알 수 있다.
$ docker run -i -t --name volume_dummy alicek106/volume_test
# ls /home/testdir_2
test
컨테이너를 빠져나온 뒤 -v
옵션으로 컨테이너를 생성하자.-v
옵션의 값인 /home/testdir_2
디렉터리를 확인하면 원래 있던 test
파일이 없어지고 호스트에서 공유된 파일이 존재하는 것을 확인할 수 있다.
즉 원래 이미지에 존재하던 디렉터리에 호스트의 볼륨을 공유하면 컨테이너의 디렉터리 자체가 덮어씌어진다.
-v
옵션을 통한 호스트 볼륨 공유는 호스트의 디렉터리를 컨테이너 디렉터리에 마운트한다.
$ docker run -i -t --name volume_overide -v /home/wordpress_db:/home/testdir_2 alicek106/volume_test
# ls /home/testdir_2
auto.cnf ca.pem client-key.pem ib_logfile0 ibdata1 mysql.sock private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 mysql performance_schema public_key.pem server-key.pem wordpress
볼륨 컨테이너를 활용하는 방법
볼륨을 사용하는 두 번째 방법은 -v
옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것이다.
컨테이너를 생성할 떄 --volumes-from
옵션을 설정하면 -v
또는 --volume
옵션을 적용한 컨테이너의 볼륨 디렉터리를 공유할 수 있다.
사실은 직접 볼륨을 공유하는 것이 아닌 -v
옵션을 적용한 컨테이너를 통해 공유하는 것이다.
(참고로 아래 예시는 위의 예시로부터 계속 진행한다.)
아래의 예는 앞에서 생성한 volume_overide
컨테이너에서 볼륨을 공유받는 경우다.
앞에서 생성한 volume_overide
컨테이너는 /home/testdir_2
디렉터리를 호스트와 공유하고 있으며, 이 컨테이너를 볼륨 컨테이너로서 volumes_from_container
컨테이너에 다시 공유한다.
$ docker run -i -t --name volums_from_container --volumes-from volume_overide ubuntu
# ls /home/testdir_2
auto.cnf ca.pem client-key.pem ib_logfile0 ibdata1 mysql.sock private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 mysql performance_schema public_key.pem server-key.pem wordpress
--volumes-from
옵션을 적용한 컨테이너와 볼륨 컨테이너 사이의 관계는 다음과 같다.

여러 개의 컨테이너가 동일한 컨테이너에 --volumes-from
옵션을 사용함으로써 볼륨을 공유해
사용할 수 있다.
이를 활용하면 호스트에서 볼륨만 공유하고 별도의 역할을 담당하지 않는 볼륨 컨테이너
로 활용하는 것도 가능하다.
즉, 볼륨을 사용하려는 컨테이너에 -V
옵션 대신 --volumes-from
옵션을 사용함으로 볼륨 컨테이너에 연결해 데이터를 간접적으로 공유받는 방식이다.
도커 볼륨
볼륨을 활용하는 세 번째 방법은 docker volume
명령어를 사용하는 것이다.
도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수도 있다.
볼륨을 다루는 명령어는 dokcer volume
으로 시작하고, docker volume create
명령어로 볼륨을 생성한다.
# myvolume이라는 볼륨 생성
$ docker volume create --name myvolume
# 생성된 볼륨 확인하기
$ docker volume ls
DRIVER VOLUME NAME
...
...
local myvolume
참고로 볼륨을 생성할 때 플러그인 드라이버를 설정해 여러 종류의 스토리지 백엔드를 쓸 수 있다.
지금은 기본적으로 제공되는 드라이버인 local
을 사용한다.
이 볼륨은 호스트에 저장되며 도커 엔진에 의해 생성되고 삭제된다.
다음 명령어를 입력하여 myvolume
이라는 볼륨을 사용하는 컨테이너를 생성한다.
호스트와 볼륨을 공유할 때 사용한 -v
옵션의 입력과는 달리 다음처럼 입력해야한다.
[볼륨의 이름]:[컨테이너의 공유 디렉터리]
아래의 예시에서 생성되는 컨테이너는 볼륨의 컨테이너의 /root/
디렉터리에 마운트하므로 /root
디렉터리에 파일을 쓰면 해당 파일이 볼륨에 저장된다.
$ docker run -i -t --name myvolume_1 -v myvolume:/root/ ubuntu
# echo hello, volume! >> /root/volume
/root
디렉터리에 volume 이라는 파일을 생성했다.
다른 컨테이너도 myvolume 볼륨을 사용하면 볼륨을 활용한 디렉터리에 volume 파일이 존재할 것이다.
컨테이너에서 호스트로 빠져나온 뒤 컨테이너를 생성해 확인해보자.
$ docker run -i -t --name myvolume_2 -v myvolume:/root/ ubuntu
# cat /root/volume
hello, volume!
위와 같이 같은 파일인 volume이 존재한다.docker volume
명령어로 생성한 볼륨은 아래 그림과 같은 구조로 활용된다.
도커 볼륨도 여러 개의 컨테이너에 공유되어 활용될 수 있다.

볼륨은 디렉터리 하나에 상응하는 단위로서 도커 엔진에서 관리한다.
도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요는 없다.
docker inspect
명령어를 사용하면 myvolume
볼륨이 실제로 어디에 저장되는지 알 수 있다.docker inspect
명령어는 컨테이너, 이미지, 볼륨 등 도커의 모든 구성 단위의 정보를 확인할 때 사용되며, 정보를 확인할 종류를 명시하기 위해 --type
옵션에 image
, volume
등을 입력하는 것이 좋다.
다음 명령은 이름이 myvolume인 볼륨의 정보를 출력한다.
$ docker inspect --type volume myvolume
[
{
"CreatedAt": "2025-02-19T22:12:22Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
"Name": "myvolume",
"Options": null,
"Scope": "local"
}
]
참고
도커의 모든 명령어는 docker 접두어 다음에 container, image, volume 등을 명시함으로써 특정 구성 단위를 제어하는 명령어를 사용할 수 있다. 예를 들어, docker container inspect는 컨테이너의 정보를, docker volume inspect는 볼륨의 정보를 출력한다.
위의 json 이 나타내는 정보는 다음과 같다.
- Driver: 볼륨이 쓰는 드라이버
- Label: 볼륨을 구분하는 라벨
- Mountpoint: 해당 볼륨이 실제로 호스트의 어디에 저장했는지를 의미
- 볼륨을 쓰는 사용자 입장에서 Mountpoint를 알 필요는 없다.
해당 디렉터리의 파일을 보면 컨테이너에서 사용했던 파일이 남아있다.
$ ls /var/lib/docker/volumes/myvolume/_data
volume
$ cat /var/lib/docker/volumes/myvolume/_data/volume
hello, volume!
고 한다.
후.. 잠시 푸념 좀 하고 간다.
지금 내가 학습하고 있는 윈도우 환경에서 WSL을 통해 위의 경로를 찾아본 결과 나오지 않는다.
디렉터리가 존재하지 않는다고 나온다...
눈을 씻고 쳐다 봐도 없다.. 안 보인다...
근데 분명히 도커에서는 myvolume 이라는 volume 정보가 나오긴한다...
난 이게 너무 궁금했다...
존재는 하긴 해! 이렇게 보면 확인할 수 있다고 한다..!
근데 왜 나는 안 보이냐고!!!
있는데 못 보는 건 홍길동이 호부호형하지 못했던 것과 무게는 다르지만 똑같은 거 아닌가...
해서 집요하게 찾은 결과 이렇게 나온다.
GUI로 찾은 경로는 다음과 같다.

\\wsl.localhost\docker-desktop\mnt\docker-desktop-disk\data\docker
여기서 확인했다.
위는 회사 컴퓨터이고, 집에 있는 노트북에서는 다음 경로에 있다.
\\wsl.localhost\docker-desktop-data\data\docker\volumes\myvolume\_data

후... 잠시 푸념 좀 했다.
내가 이 경로가 안 나와서 다른 사람들은 나오나 싶어서 구글링을 해봤는데, 죄다 그냥 책 내용 복붙이다...
물론 실제로 나오는 사람도 있었지만, 그냥 책 내용 냅다 가져다 쓴 분들이 많다....
아쉬움 + 속은 느낌이다...
나는 학습하더라도 결과를 좀 보여줘야겠다.
docker volume create
명령을 별도로 입력하지 않아도 -v
옵션을 입력할 때는 이를 수행하도록 설정할 수 있다.
다음과 같이 컨테이너에서 공유할 디렉터리의 위치를 -v
옵션에 입력하면 해당 디렉터리에 대한 볼륨을 자동으로 생성한다.
$ docker run -i -t --name volume_auto -v /root ubuntu
#
컨테이너를 생성한 뒤 호스트로 빠져나와 docker volume ls
명령어로 확인하면 이름이 무작위의 16진수 형태인 볼륨이 자동으로 생성된 것을 볼 수 있다.
$ docker volume ls
DRIVER VOLUME NAME
local 8d18991f076b3a0b27640d97e940a69ad90abfce815c9e7caea4acd4252918a3
local 08adc4f29790468cfb5f21f72a253b57c1fe640284fe8b8c0ec0411f47de25fb
...
...
local myvolume
생성된 volume_auto
컨테이너가 위의 8d18991f076b3…
볼륨을 사용하는지 확인하려면 docker container inspect
명령어를 이용하면 된다.docker container inspect
명령어는 컨테이너의 상세한 정보를 출력하는데. 그중 볼륨 마운트에 대한 정보도 포함돼 있다.
$ docker container inspect volume_auto
......
"Mounts": [
{
"Type": "volume",
"Name": "db847d8b39fa1093062239ebc996a3b5e22e38094868232a043429245dfcd2ff",
"Source": "/var/lib/docker/volumes/db847d8b39fa1093062239ebc996a3b5e22e38094868232a043429245dfcd2ff/_data",
....
inspect
명령어는 너무 많은 정보를 출력해서 대부분 생략했다.
여기서 주목할 정보는 "Source” 항목에 정의된 디렉터리인 /var/lib/…
이 volume_auto
컨테이너에 마운트돼 볼륨으로 쓰고 있다는 것이다.
이렇게 도커 볼륨을 생성하고 삭제하다 보면 불필요한 볼륨들이 남아있을 때가 있다.
도커 볼륨을 사용하고 있는 컨테이너를 삭제해도 볼륨이 자동으로 삭제되지는 않기 때문이다.
사용되지 않는 볼륨을 한꺼번에 삭제하려면 docker volume prune
명령어를 사용하면 된다.
$ docker volume prune
docker volume prune
WARNING! This will remove anonymous local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
dc343321b819a26dc9486dcb07816bda3fb95fae2b52344013e667012a0ac1da
...
Total reclaimed space: 934.6MB
지금까지 볼륨 공유를 통한 데이터 저장에 대해 살펴봤다.
컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것을 스테이트리스(stateless)하다고 한다.
- 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받는다.
- 컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할 때 매우 바람직한 설계다.
반대로 컨테이너가 데이터를 저장하고 있어 상태가 있는 경우 스테이트풀(stateful)하다고 말한다.
- 스테이트풀한 컨테이너 설계는 컨테이너 자체에서 데이터를 보관하므로 지양하는 게 좋다.
참고
-v
옵션 대신 --mount
옵션을 사용할 수 있다.
두 옵션의 기능은 같지만, 볼륨의 정보를 나타내는 방법이 다르기 때문에 둘 중 사용하기 편한 옵션을 사용하면 된다.
예를 들어 --mount
옵션으로 myvolume
이라는 이름의 도커 볼륨을 컨테이너 내부의 /root
에 공유하는 명령어는 아래와 같다.
$ docker run -i -t --name mount_option_1 --mount type=volume,source=myvolume,target=/root ubuntu
호스트의 디렉터리를 컨테이너 내부에 마운트하는 경우에는 type
을 bind
로 지정하면 된다.
이때 source
의 값은 호스트의 디렉터리 경로를 지정한다.
$ docker run -i -t --name mount_option2 --mount type=bind,source=/home/wordpress_db,target=/home/testdir ubuntu
3. 요약
도커 볼륨을 통해서
- 호스트와 볼륨을 공유할 수 있다.
- 볼륨 컨테이너를 활용할 수 있다.
- 도커가 관리하는 볼륨을 생성할 수 있다.
'Deploy > Docker' 카테고리의 다른 글
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 컨테이너 자원 할당 제한 (0) | 2025.03.03 |
---|---|
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 컨네이너 로깅 (0) | 2025.03.03 |
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 네트워크 (1) | 2025.02.28 |
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진_컨테이너 다루기(명령어 및 애플리케이션 구축) (0) | 2025.02.27 |
[Docker] 시작하세요! 도커 & 쿠버네티스 - 01_도커란 (0) | 2025.02.27 |