Docker&K8s

CH_3_5_영속성 데이터 사용법

dding-shark 2025. 7. 25. 20:10
728x90

3.5 영속성 데이터 사용법

컨테이너는 기본적으로 상태가 없는(Stateless) 특성을 가집니다. 컨테이너가 실행되는 동안 생성되거나 변경된 파일은 컨테이너가 중지되고 파기될 때 함께 사라집니다. 이는 컨테이너의 핵심적인 장점인 이식성과 확장성을 유지하는 데 도움이 됩니다.

하지만 데이터베이스나 파일 서버처럼 상태를 가져야 하는(Stateful) 애플리케이션을 컨테이너로 운영해야 할 때가 있습니다. 이런 경우, 컨테이너가 재시작되거나 새로운 버전으로 업데이트되더라도 데이터를 잃지 않고 유지해야 합니다. 즉, 데이터의 영속성(Persistence)을 보장해야 합니다.

Stateless 애플리케이션과 비교해 Stateful 애플리케이션은 데이터 영속성, 백업, 복제 등 고려해야 할 점이 많아 운영 난이도가 높습니다. 그래서 많은 경우 AWS RDS나 Google Cloud SQL 같은 매니지드 서비스를 사용하는 것이 현실적인 대안이 되기도 합니다.

하지만 우리는 능력 있는 개발자 및 아키텍트가 되기 위해, 도커 환경에서 영속성 데이터를 다루는 핵심적인 방법인 볼륨(Volume)에 대해 자세히 알아보겠습니다.

 

 

 


 

3.5.1 볼륨의 종류와 특징

도커에서 영속성 데이터를 다루는 가장 일반적인 방법은 볼륨을 사용하는 것입니다. 볼륨은 컨테이너의 특정 파일 시스템 경로를 호스트 머신에 마운트하여 데이터를 컨테이너의 생명주기와 분리하는 기술입니다. 볼륨은 크게 두 가지 종류로 나뉩니다.

 

 

1. 바인드 마운트 (Bind Mounts) / Data Volume

바인드 마운트는 호스트 머신의 특정 디렉터리나 파일을 컨테이너 안으로 직접 연결(마운트)하는 방식입니다.

  • 사용법
    -v 또는 --mount 옵션을 사용하여 호스트_경로:컨테이너_경로 형식으로 지정합니다.
# docker container run [options] -v /path/on/host:/path/in/container repository:tag

    # 예시: 호스트의 현재 디렉터리 아래의 html 폴더를 Nginx 컨테이너의 웹 루트로 마운트
    docker container run -d -p 8080:80 -v ${PWD}/html:/usr/share/nginx/html nginx
  • 장점: 호스트에서 파일을 직접 수정하면 즉시 컨테이너에 반영되므로, 개발 환경에서 소스 코드를 마운트하여 실시간으로 변경 사항을 확인하는 데 매우 유용합니다.
  • 단점: 호스트의 파일 시스템 구조에 강하게 의존하게 됩니다. 만약 다른 환경의 호스트에 동일한 경로의 디렉터리가 없다면 컨테이너를 실행할 수 없어 이식성이 떨어집니다. 또한, 컨테이너가 호스트의 파일 시스템에 직접 접근하므로 보안상 위험이 있을 수 있습니다.

 

 

 

2. DataVolume 컨테이너

DataVolume 컨테이너 (이름 있는 볼륨)은 도커가 직접 관리하는 데이터 영역을 생성하여 컨테이너에 연결하는 방식입니다. 데이터는 호스트의 특정 경로(_**/var/lib/docker/volumes**_ 디렉터리 하위)에 저장되지만, 사용자는 구체적인 경로 대신 볼륨의 이름을 통해 데이터를 관리합니다.

 

앞서 설명한 -v 옵션을 사용하여 Data Volume을 공유하게 하는것도 방법이지만, Data Volume Container를 사용하는 방법도 있습니다.


이는 앞서 설명한 방법과는 다르게 컨테이너간에 디렉토리를 공유하게 합니다.

 

DataVolumeContainer는 이름 그대로, 데이터만을 위한 컨테이너 입니다. 앞에서 컨테이너가 파기되어도 데이터는 남아 있는걸 볼 수 있었는데,


DataVolumeContainer는 이특성을 활용하여, 디스크에 유지되는 컨테이너각 갖는 영속석데이터의 일부는 Volume으로 다른 컨테이너에게 공유 할 수 있도록 한 것이 DataVolumeContainer입니다.


(일종에 파티션을 나눈후, 그 부분만 공유 하는 거라고 이해 )

 

 

호스트와 컨테이너간 DavaVolume은 호스트의 특정 디렉토리에 의존하는 특성을 갖습니다.

하지만 Volume 컨테이너의 Volume은 도커의 관리영역인 호스트이 /var/lib/docker/volumes에 위치하며, Data Volume컨테이너 방식은 도커가 관리하는 디렉토리에만 영향을 줍니다.

 

따라서 호스트와 애플리케이션 컨테이너간의 중개역할을 하는 컨테이너를 둠으로써 이 둘의 의존성을 분리할 수 있어 Application Container와 Data Volume 컨테이너의 교체 및 마이그레이션을 원활하게 진행할 수 있습니다.

 

  • 사용법
    -v 옵션에 호스트 경로 대신 볼륨 이름을 지정합니다. 해당 이름의 볼륨이 없으면 도커가 자동으로 생성해 줍니다.
# docker container run [options] -v volume-name:/path/in/container repository:tag

    # 예시: 'mysql-data'라는 이름의 볼륨을 생성하여 MySQL 데이터 디렉터리에 마운트
    docker container run -d --name mysql \
      -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" \
      -e "MYSQL_DATABASE=volume_test" \
      -v mysql-data:/var/lib/mysql \
      mysql:8.0.33
  • 장점: 호스트의 파일 시스템 구조로부터 자유롭습니다. docker volume 명령어를 통해 볼륨을 생성, 조회, 삭제하는 등 체계적으로 관리할 수 있어 바인드 마운트보다 권장되는 방식입니다.
  • 특징: mysql 컨테이너를 삭제하고, 동일한 볼륨 이름을 사용하여 mysql2 라는 새로운 컨테이너를 실행해도 이전의 모든 데이터(스키마, 테이블, 레코드 등)가 그대로 보존됩니다.

 

# 기존 mysql 컨테이너 중지 및 삭제
    docker container stop mysql
    docker container rm mysql

    # 새로운 mysql 컨테이너를 'mysql-data' 볼륨과 함께 실행
    docker container run -d --name mysql2 \
      -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" \
      -e "MYSQL_DATABASE=volume_test" \
      -v mysql-data:/var/lib/mysql \
      mysql:8.0.33
`mysql2` 컨테이너에 접속해 보면, `mysql` 컨테이너에서 작업했던 내용이 그대로 남아있는 것을 확인할 수 있습니다.

 

 

3.5.2 Docker Compose를 이용한 볼륨 관리

docker-compose.yml 파일을 사용하면 여러 컨테이너와 볼륨의 구성을 코드로 쉽게 관리할 수 있습니다.

과거에는 volumes_from을 사용하여 다른 컨테이너의 볼륨을 공유했지만, 이 방식은 현재 레거시(legacy)이며 더 이상 권장되지 않습니다. 대신, 최상위 volumes 키를 사용하여 이름 있는 볼륨을 명시적으로 정의하고 각 서비스에서 이를 참조하는 방식을 사용해야 합니다.

## 과거 version
version: "3.9"

services:
  mysql:
    container_name: mysql
    image: mysql:8.0.33
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: yes
      MYSQL_DATABASE: volume_test
    volumes_from:
      - mysql_data

  mysql_data:
    container_name: mysql-data
    build: .      
# docker-compose.yml

version: "3.9"

services:
  # MySQL 애플리케이션 서비스
  mysql:
    container_name: mysql
    image: mysql:8.0.33
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_DATABASE: volume_test
    # 'db-data'라는 이름의 볼륨을 컨테이너의 /var/lib/mysql 경로에 마운트
    volumes:
      - db-data:/var/lib/mysql

# 이 Compose 파일에서 사용할 볼륨을 정의
volumes:
  # 'db-data'라는 이름의 볼륨을 정의합니다.
  # external: true 옵션을 사용하면 외부에서 생성된 볼륨을 참조할 수도 있습니다.
  db-data:

위와 같이 구성하면 docker compose up 명령 실행 시 db-data라는 이름의 볼륨이 없다면 자동으로 생성되고, mysql 서비스 컨테이너에 마운트됩니다.

 

 

 

 


 

 

3.5.3 다른 호스트로 데이터 이전 (백업 및 복원)

이름 있는 볼륨은 매우 편리하지만, 기본적으로는 해당 볼륨을 생성한 단일 호스트에 종속됩니다. 다른 서버(호스트)로 데이터를 이전하려면 어떻게 해야 할까요?

임시 컨테이너를 활용하여 볼륨 데이터를 파일로 백업하고, 다른 호스트에서 해당 파일을 새로운 볼륨으로 복원하는 방법을 사용할 수 있습니다.

 

 

 

1단계: 볼륨 데이터 백업

기존 호스트에서 tar 명령어를 사용하여 볼륨의 전체 데이터를 압축 파일로 만듭니다.

# 'mysql-data' 볼륨의 데이터를 /backup 디렉터리(호스트의 현재 디렉터리)에 'mysql-backup.tar.gz' 파일로 백업
docker run --rm \
  -v mysql-data:/dbdata \
  -v ${PWD}:/backup \
  busybox \
  tar cvzf /backup/mysql-backup.tar.gz -C /dbdata .

명령어 분석:

  • --rm: 명령 실행 후 임시 컨테이너를 자동으로 삭제합니다.
  • -v mysql-data:/dbdata: 백업할 mysql-data 볼륨을 컨테이너의 /dbdata 디렉터리에 마운트합니다.
  • -v ${PWD}:/backup: 호스트의 현재 디렉터리를 컨테이너의 /backup 디렉터리에 마운트하여 백업 파일이 저장될 위치를 지정합니다.
  • busybox: tar와 같은 기본적인 유틸리티가 포함된 경량 이미지입니다.
  • tar cvzf /backup/mysql-backup.tar.gz -C /dbdata .: /dbdata 디렉터리로 이동(-C)한 후, 그 안의 모든 내용(.)을 /backup/mysql-backup.tar.gz 파일로 압축합니다.

이 명령이 실행되면 호스트의 현재 경로에 mysql-backup.tar.gz 파일이 생성됩니다.

 

 

 

2단계: 데이터 복원

백업 파일(mysql-backup.tar.gz)을 새로운 호스트로 복사한 후, 다음 단계를 따라 데이터를 복원합니다.

  1. 새로운 볼륨 생성
    새로운 호스트에서 데이터를 담을 새 볼륨을 생성합니다.
    docker volume create new-mysql-data
  1. 새 볼륨에 데이터 복원
    백업 파일을 새 볼륨에 압축 해제합니다.
    # 'new-mysql-data' 볼륨에 'mysql-backup.tar.gz' 파일의 압축을 해제
    docker run --rm \
      -v new-mysql-data:/dbdata \
      -v ${PWD}:/backup \
      busybox \
      tar xvzf /backup/mysql-backup.tar.gz -C /dbdata
  1. 복원된 볼륨으로 새 컨테이너 실행
    복원이 완료된 볼륨을 사용하여 새로운 MySQL 컨테이너를 실행합니다.
    docker run -d --name new-mysql \
      -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" \
      -e "MYSQL_DATABASE=volume_test" \
      -v new-mysql-data:/var/lib/mysql \
      mysql:8.0.33

이제 new-mysql 컨테이너는 이전 호스트의 모든 데이터를 그대로 가진 채 실행됩니다.

참고로, docker image save 명령은 이미지 자체를 저장하는 것이지, 이미지가 사용하는 볼륨의 데이터를 포함하지 않으므로 데이터 백업 용도로는 적합하지 않습니다.

컨테이너 기술은 애플리케이션의 이식성을 크게 향상시키지만, 이처럼 데이터를 여러 호스트에 걸쳐 이식성 있게 구현하는 것은 도커의 표준 기능만으로는 다소 복잡할 수 있습니다. 이러한 문제는 쿠버네티스(Kubernetes)와 같은 컨테이너 오케스트레이션 기술이 제공하는 PersistentVolume(PV), PersistentVolumeClaim(PVC), StorageClass 등의 개념을 통해 훨씬 더 효과적으로 해결할 수 있으며, 이는 추후에 다루게 될 주제입니다.

728x90