볼륨이 무엇이며
어떻게 사용하는 것일까?
볼륨 (Volume)
--
볼륨은
도커에서 컨테이너와 호스트 간의 데이터들을 공유하거나
데이터를 영구적으로 저장하기 위해 사용되는 저장소이다.
도커에서 컨테이너는 Stateless 하기 때문에
컨테이너가 삭제 또는 재시작이 되면 기존에 사용했던 모든 데이터가
컨테이너를 시작하기 이전인 이미지의 상태로 초기화가 된다.
즉, 컨테이너가 실행된 이후에 모든 동작 기록은 컨테이너 레이어에 쌓이게 되는데
이 컨테이너 레이어는 컨테이너 삭제 or 재시작이 되면 없어진다.
하지만 서버를 운영을 하다보면 쌓인 데이터를 계속 유지해야 하는 경우가 존재한다.
또는 트래픽을 분배하기 위해 로드밸런싱을 사용하여 여러 개의 동일한 서버를 운영해야 되며
이렇게 동일한 서버에서 일관성있는 데이터를 주고받기 위해
도커의 볼륨 기능을 사용한다.
로드밸런싱이란?
네트워크 트래픽을 여러 서버나 리소스 간에 고르게 분해하도록하여 성능, 신뢰성, 가용성을 최적화하는 기술이다.
즉, 한 서비스의 트래픽을 여러 대의 서버로 분산시키는 네트워크 기술이다.
일반적으로 컨테이너를 운영하는 환경에서는 같은 역할을 하는 서버가 여러 개로 운영된다. 이러한 구조를 서버가 이중화되어 있다고 표현한다. 최소 두 대 이상의 서버가 있어야 한 대의 서버에서 문제가 발생했을 때 다른 한 대의 서버가 요청을 처리할 수 있다. 그리고 트래픽이 늘어날 때마다 해당 서버의 개수를 증가시켜서 트래픽을 분해해서 처리할 수 있어야 한다.
위 그림의 구조를 보면
데이터베이스 컨테이너들은 모두 같은 이미지를 컨테이너로 실행했기 때문에 동일한 기능을 제공하며
클라이언트의 요청은 로드밸런싱을 통해서 container1, 2, 3에 랜덤하게 트래픽이 전달된다.
여기서 container1, 2, 3이 서로 동일한 데이터를 가지고 있어야 어느 컨테이너에 접근을 하든 간에 동일한 데이터를 요청 및 응답을 할 수 있다.
즉, container1, 2, 3은 서로 데이터를 공유해야 어느 container에 접근을 하던간에 동일한 데이터를 제공할 수 있다.
사용자 A가 container1에 접근하여 특정 상품의 가격을 10,000원에서 20,000원으로 수정했고
사용자 B가 container2에 접근하여 해당 상품을 구매하려고 하면 변경되지 않은 가격 10,000원에 구매하게 된다.
container1에서는 데이터를 수정했지만 container2에서는 수정을 하지 않았기 때문이다.
그래서 container1, 2, 3 모두 데이터를 공유해야 정상적인 서비스로 동작할 수 있다.
그리고 컨테이너는 Stateless하기 때문에 영속성이 필요한 데이터를 저장할 공간이 필요하다.
즉, Database container가 없어져도 그동안 쌓여있던 데이터들은 없어지지 않고 별도의 저장소에 담겨 있어야 한다.
영속성(Persistence)은 IT 쪽에서 데이터를 영구적으로 저장 및 관리하는 능력을 의미
영속성 데이터 저장 공간의 문제를 해결하기 위해
도커에서는 도커 볼륨(Volume) 기능을 제공한다.
도커 볼륨을 사용하면 컨테이너가 데이터를 외부에 저장하고 다른 컨테이너들과도 공유할 수 있다.
도커 볼륨은
컨테이너의 모든 데이터를 저장하는 것이 아닌
컨테이너의 특정 폴더를 공유용 폴더로 만들어서 외부에 저장한다.
컨테이너는 자체적으로 상태를 가지지 않지만
상태가 필요한 데이터는 외부 공유 저장소로 저장해 둔다.
그리고 해당 외부 공유 저장소를 다른 컨테이너들과 공유가 가능하다.
이러한 동작을 컨테이너의 폴더를 볼륨에 마운트(Mount)한다고 표현한다.
--
마운트 (Mount)
--
마운트는
컴퓨터의 특정 디렉터리를 외부 저장소와 연결한다는 것을 의미한다.
USB를 PC에 연결하면 저장 공간인 새로운 드라이브가 만들어지고 이 드라이브에 데이터들을 저장할 수 있다.
이렇게 데이터가 저장된 USB는 다른 PC에 연결하여 데이터를 공유할 수도 있다.
이 USB와 동일한 역할을 하는 것이 네트워크 파일 시스템 (NFS)이다.
USB는 물리적으로 연결하여 데이터를 저장하는 저장소이고
NFS는 네트워크를 통해 데이터를 저장하는 메커니즘이다.
USB와 달리 NFS는
동시에 많은 PC를 연결할 수 있다.
PC의 특정 폴더를 NFS에 연결하는 것을 NFS에 마운트 시킨다고 한다.
즉, 마운트를 하면
특정 디렉터리를 외부 저장소로 대체하여 사용하는 것을 의미하고
이 외부 저장소는 다른 PC들과 공유해서 사용이 가능하다.
간단하게 말하면 특정 디렉토리를 다른 PC들과 공유하여 사용하는 것이다.
위 그림을 보면
container1, 2, 3은 "/data" 디렉토리를 동일한 경로의 도커 볼륨에 마운트 하여
container1, 2, 3는 데이터를 공유하여 동일한 데이터를 제공할 수 있게 된다.
데이터베이스 PostgreSQL 컨테이너를 실행하면
해당 컨테이너 내부에 "/var/lib/postgresql/data"라는 경로에 실제로 데이터가 저장된다.
그래서 container를 삭제한다고 해도 데이터는 볼륨에 그대로 남아있게 되어서
새로운 container를 생성한다고 한들 해당 데이터가 담겨 있는 볼륨에 마운트만 한다면 데이터를 공유받은 상태로
사용할 수 있게 된다.
--
도커 볼륨 관련 명령어 및 볼륨에 마운트 하는 방법
--
볼륨 생성 명령어 형식
docker volume create {볼륨명}
볼륨 삭제 명령어 형식
docker volume rm {볼륨명}
컨테이너에 마운트 되어있는 볼륨은 삭제가 불가능하다.
실제로 해당 볼륨을 사용하는 컨테이너가 없을 경우에만 삭제가 가능하다.
도커가 관리하는 볼륨 리스트 조회 명령어 형식
docker volume ls
특정 볼륨의 상세 정보 조회 명령어
docker volume inspect {볼륨명}
컨테이너의 디렉터리를 도커 볼륨에 마운트 하는 방법은
컨테이너를 실행할 때 도커 볼륨에 등록하는 옵션을 추가하면 된다.
컨테이너를 실행할 때 컨테이너의 특정 디렉토리를 도커의 볼륨에 마운트하는 명령어 형식
docker run [-v 볼륨명:컨테이너의 디렉토리 경로]
옵션 설명
-v | volume의 약어로 마운트할 컨테이너의 특정 디렉토리를 볼륨에 마운트를 하는 옵션이다. |
컨테이너의 "/data" 디렉토리를 "volume1"이라는 볼륨에 마운트하는 명령어
docker run -v volume1:/var/lib/postgresql/data
일반적으로 마운트 할 경로를 작성할 때에는 위 명령어처럼 "/var/lib/postgresql/data"로 평소처럼 작성하지만
Windows OS의 git bash환경에서는
경로의 처음에 작성된 "/"가 한 개만 있으면 윈도우가 자체적으로 C드라이브의 경로로 자동 변환하기 때문에
"//var/lib/postgresql/data" 처럼 슬래시를 두 개 작성해줘야 한다.
전체적인 명령어
"postgres:13" 이미지를 가지고 "my-postgres"라는 이름으로 컨테이너를 실행하는데
해당 컨테이너 내부에 있는 "/var/lib/postgresql/data" 디렉터리를 "mydata"라는 볼륨에 마운트 하는 명령어
docker run -d --name my-postgres -e POSTGRES_PASSWORD=password -v mydata://var/lib/postgresql/data postgres:13
이렇게 실행한 컨테이너의 상세 정보를 조회하는 명령어
docker container inspect my-postgres
이렇게 마운트에 대한 정보들을 확인할 수 있다.
데이터베이스 컨테이너에서 생성되는 데이터들은
Destination에 작성된 컨테이너의 "/var/lib/postgresql/data" 경로에 저장되고
실제로 해당 데이터가 저장되는 경로는
Source에 작성된 "/var/lib/docker/volumes/mydata/_data" 경로에 저장된다.
"Driver" 필드는
도커 볼륨의 유형을 지정하는 필드이다.
"local"은 기본 볼륨 드라이버로 도커 호스트의 로컬 파일 시스템을 사용
"NFS"는 NFS 드라이버를 사용하여 네트워크를 통해 사용하는 파일 시스템을 사용
"AWS EFS"는 AWS에서 제공하는 관리형 파일 시스템을 사용
등 다양한 유형이 존재한다.
컨테이너와 볼륨 관계도
컨테이너의 "/usr/share/nginx/html" 경로의 디렉터리는 도커 볼륨 "volume1"에 연결되고
실제로 "volume1"에 저장되는 데이터들은 호스트 OS에 있는 "/volumes/volume1" 경로에 저장된다.
그리고 볼륨들의 데이터를 저장하고 있는 호스트 OS의 볼륨 디렉토리는 도커가 관리한다.
--
바인드 마운트 (Bind Mounts)
--
일반적으로 볼륨을 마운트 할 때에는 도커의 볼륨명을 지정하여 마운트 하는데
위에서 호스트 OS에 데이터를 저장하는 경로를 "volumes"라고 했지만
실제로는
도커가 경로를 자동으로 관리하고 도커가 실행되는 가상머신 안에서 저장되기 때문에
볼륨이 저장하는 경로에 사용자가 직접 접근하기에는 어려움이 있다.
그래서 호스트 OS에서 데이터를 직접 접근을 해보고 싶을 때
바인드 마운트 기능을 사용한다.
바인드 마운트하는 명령어 형식
docker run [-v 마운트할 호스트OS 경로:컨테이너 내부 경로]
위 그림처럼
마운트 할 때 볼륨명 대신 직접 저장할 호스트OS의 경로를 지정하면 된다.
다만 이러한 경우 볼륨이 만들어지지 않기 때문에 도커가 관리하지 않게 된다.
그래서 사용자가 직접 관리를 해야 한다.
일반적으로 볼륨을 통해서 관리하는 것이 일반적이기 때문에
바인드 마운트는 직접 디렉터리의 내용을 관찰해야 하는 디버깅 같은 상황에서 유용하게 활용할 수 있다.
--
참고 및 출처
'Docker' 카테고리의 다른 글
이미지 빌드시 캐싱 활용하기 (0) | 2024.06.30 |
---|---|
이미지 레이어 관리하기 (0) | 2024.06.29 |
Docker의 가상 네트워크 (+명령어) (0) | 2024.06.27 |
docker 가상 네트워크 포트포워딩과 도커 DNS (+명령어) (0) | 2024.06.26 |
Vue.js, Spring Boot, PostgreSQL 컨테이너 구성 및 연결하여 애플리케이션 구현하기 (+실습) (0) | 2024.06.25 |