
일단 도커에서 말하는 볼륨 Volume 무엇인지부터 설명하고 들어가겠습니다.
볼륨은 컨테이너가 사용하는 데이터를 영구 저장하기 위한 외부 저장 공간입니다. 그렇다면 데이터를 왜 영구 저장할 필요가 있을까요?
지난 포스트에서도 설명드렸지만 컨테이너는 업데이트 등이 발생하면 직접 접근해서 업데이트 하는 것 보다 해당 버전의 컨테이너를 종료 및 삭제하고 새 버전의 컨테이너를 생성하고 실행하는 게 좋은 사용 방법이라고 이야기했었습니다.
문제는 컨테이너를 삭제하는 과정에서 데이터가 함께 삭제됩니다. 만약 DB 컨테이너를 업데이트하기 위해 삭제를 했는데 DB 데이터까지 날아가버린다면...? 생각만 해도 무서운 일이 벌어집니다.
그래서 컨테이너가 삭제되어도 데이터를 유지해야할 때 볼륨을 이용해서 데이터를 영구 저장하게 됩니다.보통 볼륨으로 만드는 데이터는 DB, 설정 파일, 로그 등이 있습니다.
즉,
볼륨은 도커가 관리하는 내부 저장 공간이라고 할 수 있습니다.
도커에서 컨테이너는 생성과 삭제가 빈번히 발생하게 되므로 매번 데이터를 외부로 옮겼다가 다시 이식하는 것보다 처음부터 컨테이너 외부에 데이터 저장소를 마련해두고 해당 위치에 접근하여 데이터를 사용하게 됩니다.
이것을 데이터 퍼시스턴시 Data Persistency라고 하며 데이터 퍼시스턴시를 위해 외부에 데이터 저장소를 만들고 컨테이너와 연결하는 행동을 스토리지 마운트라고 부릅니다.
도커는 볼륨 마운트, 바인드 마운트 두 가지 방식을 통해 스토리지 마운트를 수행합니다.
볼륨 마운트는 도커 엔진이 관리하는 볼륨을 컨테이너와 마운트하는 방식입니다.
다음과 같은 특징을 갖습니다.
볼륨 마운트를 위해 먼저 볼륨을 생성합니다.
docker volume create 볼륨이름
그리고 마운트는 docker run -v 명령어 + 옵션을 이용해서 수행합니다. 뒤에서 설명할 바인드 마운트 역시 동일합니다.
docker run -v 볼륨이름:마운트_경로 이미지
docker volume create myvolume docker run -v myvolume:/app/data httpd위와 같이 선언하면 도커는 내부 경로
/app/data에myvolume을 저장합니다. (httpd는 docker run으로 실행할 이미지 대상)
다음과 같이
docker run만 작성하면myvolume이라는 이름의 볼륨이 없는 경우 자동으로 생성하고 실행 및 마운트됩니다.docker run -v myvolume:/app/data httpd
바인드 마운트는 도커 엔진이 관리하지 않는 호스트의 특정 디렉토리를 컨테이너에 마운트하는 방식입니다.
다음과 같은 특징을 갖습니다.
바인드 마운트는 볼륨 생성이 없기 때문에 절차가 더 간단합니다. 단, 경로를 유의해서 작성해주세요.
윈도우 기준
docker run -v 호스트_경로
호스트 경로는 로컬의 아무곳이나 지정하시면 됩니다. (예. C:\User\사용자\mydir 등)
우선 두 방식을 비교 정리 해보겠습니다.
| 항목 | 볼륨 마운트 | 바인트 마운트 |
|---|---|---|
| 관리 | Docker가 관리 | 사용자가 직접 관리 |
| 경로 | Docker가 내부 경로 자동 생성 | 호스트가 지정한 경로 |
| 목적 | 운영, 데이터 지속 | 개발환경의 공유, 실시간 코드 반영 |
| 재사용성 | 여러 컨테이너가 재사용 | 재사용 가능하지만 경로 삽입에 유의 |
| 보안성 | 안전하고 격리된 공간 | 경로 실수 시 덮어쓰기 문제 발생 가능성 |
| 유연성 | 유연하지만 위험부담이 따름 | 안전함 (표준) |
| 사용처 | DB, 설정 파일, 로그 | 개발 환경, 소스 코드 |
안정적인 볼륨 마운트 사용을 기본적으로는 권장하고 있습니다. 그러나 볼륨은 도커(컨테이너)를 이용해서 접근해야하는 불편함이 있어서 데이터에 직접 접근해서 수정할 일이 많다면 절차가 복잡해지기도 합니다.
그래서 데이터를 직접 조작할 일이 많다면 바인드 마운트를 선택하고 그렇지 않은 경우 볼륨 마운트를 선택해서 사용하시면 됩니다.
바인드 마운트는 호스트 지정 경로에 가서 디렉토리를 백업하면 되지만 도커가 관리하는 볼륨 마운트는 살짝 방법이 까다롭습니다.
볼륨을 직접 복사할 수 없기 때문에 (경량)리눅스 컨테이너를 하나 생성하고 볼륨과 마운트한 뒤 볼륨 내용을 압축(.tar.gz) 후 저장하는 방식으로 백업을 하게 됩니다.
docker run --rm -v 볼륨이름:/컨테이너_마운트_경로 -v 백업_디렉토리:/ 리눅스_컨테이너
tar cvzf /백업_디렉토리/백업_파일명.tar.gz -C /컨테이너_마운트_경로 .
가독성 때문에 개행을 했는데 조금 긴 한 줄 짜리 명령어 입니다. 명령어를 하나씩 살펴보면 다음과 같습니다.
docker run --rm: 컨테이너 실행 후 삭제. 실행하게되는 리눅스 컨테이너는 백업을 위한 압축 파일 생성이기 때문에 실행을 한 뒤 바로 삭제하게끔 합니다.-v 볼륨이름:/컨테이너_마운트_경로: 백업 대상 볼륨을 실행한 컨테이너에 마운트-v 백업_디렉토리:/백업_디렉토리: 리눅스 압축파일인 .tar.gz를 저장할 호스트의 경로(로컬)를 컨테이너에 마운트리눅스_컨테이너: alpine, busybox 등 tar 명령을 가지고 있는 기본 리눅스 이미지 사용. 우분투나 CentOS는 무거우니까 언급한 경량 리눅스 이미지를 사용하는 것을 권장드립니다.tar cvzf: 압축 파일을 생성하는 명령어, c: create, v:verbose, z:gzip, f:file/백업_디렉토리/백업_파일명.tar.gz: 결과 파일이 저장될 경로.-C /컨테이너_마운트_경로 .: 볼륨 내 경로로 이동하고 해당 디렉토리 내의 모든 파일 백업. 마지막의 공백과 점을 반드시 작성해야합니다.이렇게 생성된 볼륨 백업 압축 파일은 다음 과정을 통해 압축 해제 및 복원합니다.
docker volume create 복원볼륨명
docker run --rm -v 복원볼륨명:/컨테이너_마운트_경로 -v 백업_디렉토리:/ 리눅스_컨테이너
tar xzf /백업_디렉토리/백업_파일명.tar.gz -C /컨테이너_마운트_경로
역시 한 줄씩 살펴보면 다음과 같습니다.
docker volume create 복원볼륨명: 복원할 볼륨 공간을 미리 생성합니다.tar xzf: 압축 해제 명령, x:extract, z:gzip, f:file-C /컨테이너_마운트_경로: 복원 위치 지정. 압축과 다르게 마지막의 공백과 점이 없습니다.