[도커] 6장 도커 볼륨을 이용한 퍼시스턴트 스토리지

공효은·2023년 5월 31일
0

도커

목록 보기
4/12
post-thumbnail

퍼시스턴드(스)란?- 데이터의 영속성

컨테이너는 무상태 애플리케이션에게는 최적의 실행 환경이다.
사용량이 증가하더라도 클러스터에 실행 중인 컨테이너의 수를 늘리기만 하면, 모든 요청이 똑같이 처리된다.
또 롤링 업데이트를 통해 서비스 중단 없이 점진적으로 업데이트를 배포할 수도 있다.

그러나 어플리케이션에 상태가 전혀 없을 수는 없다. 퍼시스턴시나 성능 향상을 위해 디스크를 사용하는 컴포넌트가 있어야하고, 이 컴포넌트 역시 컨테이너에서 실행된다.

스토리지 관리되면 복잡한 상황이 많다.

컨테이너 속 데이터가 사라지는 이유

도커 컨테이너에도 단일 드라이브로 된 파일 시스템이 있다. 이 파일 시스템의 내용은 이미지속 파일로 부터 만들어 진다.
Dockerfile 스크립트에서 COPY 인스트럭션을 사용해 파일을 이미지로 복사하면, 이 이미지로 실행한 컨테이너에도 같은 경로에 복사된 파일이 있다.
컨테이너의 디스크 는 이미지 레이어를 순서대로 합쳐 만든 가상의 파일 시스템이다.

모든 컨테이너는 독립된 파일 시스템을 갖는다.
같은 이미지에서 실행한 여러 개의 컨테이너는 처음에는 디스크의 내용이 모두 같지만, 그중 한 컨테이너에서 애플리케이션이 파일을 수정해도 다른 컨테이너나 이미지는 영향을 받지 않는다.

//컨테이너 두개를 실행하는데 이 이미지에 담긴 애플리케이션은 컨테이너 속 파일에 무작위 숫자를 쓰는 기능을 한다.

docker container run --name rn1 diamol/ch06-random-number

docker container run --name rn2 diamol/ch06-random-number

컨테이너를 실행하면 텍스트 파일에 무작위 숫자를 쓰는 스키립트가 실행된다. 그리고 컨테이너를 종료하면 Exited 상태가 된다. 이 두 컨테이너는 같은 이미지로 실행됐으나 파일시스템의 내용이 서로 다르다.
컨테이너를 종료해도 파일 시스템은 삭제되지 않는다. 그러므로 컨테이너의 파일과 디텍터리는 그대로 남아있다.

// docker container cp 명령을 사용해 두 컨테이너에서 무작위 숫자가 쓰인 텍스트 파일을 로컬 컴퓨터로 복사해 온 다음, 파일의 내용을 확인한다.

// 두 컨테이너로 부터 /random/number.txt 파일을 로컬 컴퓨터로 복사한다. 이 파일은 컨테이너에서 생성한 것으로 서로 내용이 다르다.
docker container cp rn1:/random/number.txt number1.txt
docker container cp rn2:/random/number.txt number2.txt

// 두 컨테이너에서 복사해 온 파일의 내용을 확인한다 실제로 파일의 내용이 서로 다르다.
cat number1.txt
cat number2.txt
  • 컨테이너의 파일시스템은 단일 디스크(리눅스 컨테이너는 /dev/sda1, 윈도는 C:)다.
  • 디스크는 도커가 여러 출처로부터 합쳐 만들고 컨테이너에 전달한 가상 파일 시스템이다.
  • 이 출처는 기본적으로 이미지 레이어컨테이너의 기록 가능 레이어로 구성되는데, 이미지 레이어는 모든 컨테이너가 공유하지만 기록 가능 레어어는 컨테이너마다 다르다.
  • 모든 컨테이너가 공유하는 이미지 레이어는 읽기 전용이고, 각 컨테이너가 따로 갖는 기록 가능 레이어는 컨테이너와 같은 생애주기를 갖는다.
  • 이미지 레이어는 이미지를 내려받은 순간부터 삭제할 때까지 로컬 컴퓨터의 이미지레이어에 존재한다.
  • 컨테이너의 쓰기 가능 레이어는 컨테이너를 실행할 때 생성되며 컨테이너를 삭제하 때 함께 삭제된다.(컨테이너를 종료하는 것만으로는 컨테이너가 삭제되지 않는다. 그래서 종료된 컨테이너의 데이터도 그대로 남아있는 것이다.)

기록 가능 레이어를 새 파일을 만드는 데만 사용하는 것은 아니다. 기존 이미지 레이어에 있는 파일을 수정할 수도 있다.
도커는 기록 중 복사 라는 방법을 사용해 읽기 전용 레이어의 파일을 수정할 수 있다.
컨테이너에서 이미지 레이어에 포함된 파일을 수정하려면!
먼저 도커가 이 파일을 쓰기 가능 레이어로 복사해 온 다음 쓰기 가능 레이어에서 파일을 수정한다.

컨테이너를 실행해 파일의 내용을 출력한다. 그다음 파일의 내용을 수정하고 컨테이너를 재시작해 변경된 파일 내용을 확인한다.

// 컨테이너가 실행되면 input.txt 파일의 내용을 출력한다. 지금 출력된 내용은 이미지에 포함된 input.txt 파일의 내용이다.

docker container run --name f1 diamol/ch06-file-display

// 이 명령을 실행하면 로컬 컴퓨터에 다른 내용이 들어 있는 새로운 파일이 생성된다. 그리고 컨테이너에서 이 파일이 원래 있던 input.txt 파일을 덮어씌운것 처럼 사용된다.
echo "https://eltonstoneman.com" > url.txt

docker container cp url.txt f1:/input.txt
// 컨테이너가 첫 번째 실행을 마치고 종료됐다. 이 컨테이너를 다시 시작하면 똑같은 명령이 실행되지만 파일의 내용이 변경된 상태다.
docker container start --attach f1

컨테이너 속 파일을 수정하면 컨테이너의 동작에 영향을 미친다.

그러나 이미지를 공유하는 다른 컨테이너나 이미지는 영향을 받지 않는다. 수정된 파일은 해당 컨테이너의 기록 가능 레이어에만 존재하기 때문이다. 새로운 컨테이너는 이미지로부터 받은 최초의 내용을 담은 파일시스템을 가지며 f1 컨테이너가 삭제되면 수정된 파일도 삭제된다.

새 컨테이너를 실행해 해당 파일의 내용이 그대로인지 확인해 보자. 그리고 처음 실행했던 컨테이너를 삭제하고 수정된 데이터가 사라진 것을 확인하라.

// 같은 이미지로 새 컨테이너를 실행하면 원래 파일 내용이 출력된다. f1 컨테이너의 파일을 수정해도 이미지에는 영향을 미치지 않았다.
docker container run --name f2 diamol/ch06-file-display

//처음 만든 컨테이너를 삭제하면 이 컨테이너의 기록 가능 레이어도 수정된 데이터와 함께 삭제된다. 컨테이너의 파일 시스템은 일시적인 것이다.
docker container rm -f f1
docker container cp f1:/input.txt .

컨테이너 파일 시스템은 컨테이너와 같은 생애주기를 갖는다. 컨테이너가 삭제되면 이 컨테이너의 기록 가능 레이어와 여기서 수정된 데이터도 함께 삭제된다.

실무에서는 새 이미지를 빌드하고 오래된 컨테이너를 삭제한 다음 새 이미지에서 실행한 컨테이너로 대체하는 방법으로 애플리케이션을 업데이트한다. 이 과정에서 기존 컨테이너에 있는 수정된 데이터는 모두 손실된다. 새 컨테이너는 이미지에서 받은 파일만 갖고 있기 때문이다. => 도커 볼륨과 마운트! 이들 요소는 컨테이너와는 별개의 생애주기를 갖는다. 그러므로 컨테이너가 대체돼도 지속돼야 할 데이터를 저장할 수 있다.

6.2 도커 볼륨을 사용하는 컨테이너 실행하기

  • 도커 볼륨은 도커에서 스토리지를 다루는 단위다. 컨테이너를 위한 USB 메모리라 생각하면 이해하기 쉽다.
  • 볼륨은 컨테이너와 독립적으로 존재하며 별도의 생애주기를 갖지만, 컨테이너에 연결할 수 있다.
  • 퍼시스턴시가 필요한 유상태 애플리케이션을 컨테이너로 실행하려면 볼륨을 사용해야한다. 볼륨을 생성해 애플리케이션 컨테이너에 연결하면 컨테이너 파일 시스템의 한 디렉터리가 된다.
  • 나중에 애플리케이션을 업데이트 하더라도 새로운 컨테이너에 다시 볼륨을 연결하면 데이터가 그대로 유지된다.

컨테이너에서 볼륨을 사용하는 방법은 두가지다.
1. 수동으로 직접 볼륨을 생성해 컨테이너에 연결한다.
2. Dockerfile 스크립트에서 VOLUME 인스트럭션을 사용하는 방법이다. 이 인스트럭션을 사용해 만든 이미지로 컨테이너를 실행하면 자동으로 불륨을 생성한다.

VOLUM 인스트럭션의 문법은 VOLUME target-directory 형식이다.
아래 예제는 diamol/ch06-todo-list 이미지를 빌드하기 위한 멀티 스테이지 빌드 Dockerfile 스크립트의 일부다. 이 애플리케이션은 볼륨을 사용하는 유상태 어플리케이션이다.

// 볼륨이 사용된 멀티 스테이지 빌드 Dockerfile 스크립트의 일부
FROM diamol/dotnet-aspnet
WORKDIR /app
ENTRYPOIN ["dotnet", "ToDoList.dll"]

VOLUME /data
COPY --from=builder /out/ .

이 이미지로 부터 컨테이너를 실행하면 자동으로 볼륨을 생성해 컨테이너에 연결해준다.
실행된 컨테이너에는 /data 디렉터리가 있는데(윈도 컨테이너라면 C:\data). 이 디렉터리는 다른 디렉터리와 똑같이 사용할 수 있는데 이 데렉터리의 내용은 볼륨에 영구적으로 저장된다.

// todo-list 애플리케이션 이미지로 컨테이너를 실행해 컨테이너와 연결된 볼륨을 살펴보자.
// container run 명령에는 볼륨이 언급되지 않았지만, Dockerfile 스크립트의 정의에 따라 볼륨을 생성해 컨테이너에 연결한다.

docker container run --name todo1 -d -p 8010:80 diamol/ch06-todo-list

// 컨테이너 정보를 확인하면 'mounts' 항목에서 볼륨 정보를 볼 수 있다. 불륨 ID와 해당 볼륨의 호스트 컴퓨터상 결로, 볼륨이 연결된 컨테이너 파일 시스템의 경로 등을 확인할 수 있다.

docker container inspect --format '{{.Mounts}}' todo1

// 볼륨은 도커에서 이미지나 컨테이너와 동급인 요소다. docker volume 명령을 사용해 볼륨을 만들고 목록을 확인하고 삭제할 수 있다. 이 볼륨은 새로 만든 컨테이너에 연결하기 위해 만들어진 것이다.

docker volume ls

웹브라우저에서 https://localhost:8018에 접근하면 to-do 애플리케이션을 볼 수 있다. 이 애플리케이션은 데이터를 /data 디렉터리에 저장하는데, 웹 페이지에서 할일을 하나 추가하면 이 데이터는 도커 볼륨에 저장된다.

  • 도커 이미지에서 볼륨을 정의하면 컨테이너를 생성할 때마다 새로운 볼륨을 만든다. 하지만 컨테이너가 같은 볼륨을 공유하게 할 수도 있다.
  • to-do 애플리케이션의 새로운 컨테이너를 그냥 실행하면 자신만의 볼륨을 생성하니 할 일 목록이 비어있을 것이다. 하지만 volumes-from 플래그를 적용하면 다른 컨테이너의 볼륨을 연결 할 수 있다.
// to-do 애플리케이션의 두 번째 컨테이너를 실행하고 data 디렉터리의 내용을 확인해보자. 그 다음에는 이 컨테이너와 데이터를 공유하는 첫 번째 컨테이너의 해당 디렉터리와 내용을 비교하자.

// 이 컨테이너는 새로운 볼륨과 함께 실행된다.
docker container run --name todo2 -d diamol/ch06-todo-list

// 볼륨에는 아무것도 없으므로 /data 디렉터리가 비어있다.
docker container exec todo2 ls /data

//이 컨테이너는 todo1 컨테이너의 볼륨을 공유한다. /data 디렉터리의 내용도 같다.
docker container run -d --name t3 --volumes-from todo1 diamol/ch06-todo-list

// todo1 컨테이너와 볼륨을 공유하므로 /data 디렉터리에 애플리케이션에서 추가된 데이터가 보인다.
docker container exec t3 ls /data

컨테이너간 볼륨 공유는 모든일을 해결해주지는 못한다. 애플리케이션 컨테이너는 종종 자신만이 접근 할 수 있는 파일을 필요로 한다.
이러한 파일을 다른 컨테이너가 동시에 접근하게 허용하면 어플리케이션이 비 정상적으로 동작할 수도 있다.
볼륨은 컨테이너 간 파일 공유보다는 업데이트 간 상태를 보존하기 위한 용도로 사용해야한다.
이미지에 정의하는 것보다는 명시적으로 관리하는 편이 더 낫다.
볼륨에 이름을 붙여 생성하고 업데이트 시 다른 컨테이너로 옮겨 연결하면 된다.

볼륨을 생성하고 버전 1의 to-do 애플리케이션에서 볼륨을 사용하라. 그다음 애플리케이션에서 UI를 통해 데이터를 추가하고, 애플리케이션을 버전 2로 업데이트 해 보자. 운영체제에 따라 팡리 경로가 달라지므로 환경 변수로 먼저 정의해 본문의 코드를 쉽게 붙여 넣을 수 있다.

# 복사 대상 결로를 환경 변수로 정의한다.
target='/data' 

# 데이터를 저장할 볼륨도 생성한다
// 새로운 볼륨을 이름을 붙여 만든다. 지금은 그냥 빈 스토리지다.
docker volume create todo-list


# 볼륨을 연결해 v1 애플리케이션을 실행한다.
// -v 플래그를 사용해 새 컨테이너를 실행한다. 이 플래그는 컨테이너의 파일 시스템 경로 /data에 지정한 볼륨을 마운트 하라는 의미다.

docker container run -d -p 8011:80 -v todo-list:/data --name todo-v1 diamol/ch06-todo-list

# http://localhost:8011 페이지에서 애플리케이션에 데이터를 몇 건 추가한다.

# v1 애플리케이션이 실행 중인 컨테이너를 삭제한다
// -f 플래그를 붙이면 컨테이너가 실행되고 있더라도 컨테이너를 삭제할 수 있다. 이 과정에서 컨테이너의 기록가능 레이어가 함께 삭제 되지만 볼륨은 삭제되지 않는다.
docker container rm -f todo-v1

# 그 다음에는 같은 볼륨을 사용하도록 v2 애플리케이션 컨테이너를 실행한다.
// 업데이트된 이미지로 새로운 컨테이너를 실행하고, 이 컨테이너에 기존 볼륨을 같은 경로로 연결한다.
그러면 v2 애플리케이션은 v1에서 생성했던 데이터를 그대로 유지한다.
docker container run -d -p 8011:80 -v todo-list:/data --name todo-v2 diamol/ch06-todo-list:v2

볼륨은 컨테이너보다 먼저 생성돼 자신과 연결됐던 컨테이너가 삭제된 뒤에도 그대로 남아있다. 이로써 볼륨이 컨테이너와 별개의 생애주기를 가졌다는 것을 알 수 있다. 볼륨을 사용하면 컨테이너를 교체해 애플리케이션을 업데이트 하더라도 데이터를 보존할 수 있다.

Dockerfile 스크립트의 VOLUME 인스트럭션과 docker container 명령의 --volume 플래그는 별개기능이다.

VOLUME 인스트럭션을 사용해 빌드된 이미지로 docker container run 명령에서 볼륨을 지정하지 않으면 항상 새로운 볼륨을 함께 생성한다.
이 볼륨은 무작위로 만들어진 식별자를 가지므로, 컨테이너를 삭제한 후 볼륨을 재사용하려면 이 식별자를 미리 기억해야한다.

--volume 플래그는 이미지에 볼륨이 정의돼 있든 말든 지정된 볼륨을 컨테이너에 마운트 한다. 이미지에 볼륨이 정의돼 있더라도 이 정의가 무시되므로 새로운 볼륨이 생성되지 않는다.
지금 우리가 to-do 애플리케이션을 업데이트한 과정이 바로 이 경우다.

이미지에 볼륨이 정의돼 있지 않아도 똑같은 결과를 얻는다. 이미지를 만드는 입장에서 안전장치 삼아 VOLUME 인스트럭션 이미지 정의 에 포함해 두는게 좋다. 그러면 사용자가 볼륨을 지정하지 않더라도 데이터를 유실할 일이없다.
이미지의 기본 볼륨 설정에 의존하지 않고 별도로 이름을 붙여 만든 볼륨을 사용하는 것이 좋다.

6.3 파일 시스템 마운트를 사용하는 컨테이너 실행하기

  • 볼륨의 장점은 컨테이너와 스토리지의 생애주기를 분리하면서도 도커를 사용하는 방식 그대로 스토리지를 다를 수 있다는 점이다.
  • 볼륨 역시 호스트 컴퓨터상에 존재하지만 컨테이너와는 분리돼 있기 때문이다.
  • 하지만 호스트의 스토리지를 컨테이너에 좀 더 직접적으로 연결할 수 있다.
  • 바인트 마운트는 호스트 컴퓨터 파일 시스템의 디렉터리를 컨테이너 파일 시스템의 디렉터리로 만든다.
  • 도커를 사용하는 입장에서는 컨테이너가 호스트 컴퓨터의 파일에 직접 접근 할 수 있고 그 반대도 가능해지므로 좀 더 흥미로운일을 할 수 있다.
  • 바인드 마운트를 사용하면 호스트 컴퓨터의 파일 시스템읠 명시적으로 지정해 컨테이너 데이터로 쓸 수 있다.
  • 속도 면에서 뛰어난 SSD 디스크, 고사용성 디스크 어레이, 네트워크상에서 사용하는 분산 스토리지 까지 호스트 컴퓨터에 접근 가능한 파일 시스템이라면 무엇이든 컨테이너에서도 사용가능하다.
  • 만약 RAID가 적용된 디스크 어레이를 가진 서버가 있다면 이 스토리지를 to-do앱의 데이터 베이스를 저장할 고 신뢰성 스토리지로 활용할 수도 있다.
// 호스트 컴퓨터의 로컬 디렉터리를 컨테이너에 바인드 마운트로 연결해 보라. 파일 시스템 경로는 호스트 운영체제의 방식을 따라야한다.
// 본문의 명령을 그대로 복사해 사용할 수 있도록 경로를 환경 변수로 설정한다.
source="$(pwd)/databases" && target='/data'

// 바인드 마운트를 적용해 컨테이너를 실행. 호스트 컴퓨터의 data 디렉터리를 컨테이너 안에서 사용한다.
mkdir ./databases 
docker container run --mount type=bind,source=$source,target=$target -d -p 8012:80 diamol/ch06-todo-list

// to-do 애플리케이션에 HTTP 요청을 보낸다. 이 요청을 받아 애플리케이션이 시작되며 데이터베이스 파일이 생성된다.
// 컨테이너 포트 80번을 호스트의 8012번 포트로 공개한다. curl 명령으로 컨테이너에 HTTP 요청을 보내면 애플리케이션이 시작되면서 data 에 데이터 베이스 파일이 생성된다.
curl http://localhost:8012

// 호스트 컴퓨터에 연결된 데렉터리에 데이터 베이스 파일이 생성된것을 확인하는 명령어 이다.
ls ./databases

이 파일이 컨테이너에서 생성한 파일이다.
호스트 컴퓨터에서 이 파일을 직접 사용하거나 다른 파일을 추가할 수 있다. 새로 만든 파일도 컨테이너에서 사용할 수 있다.

  • 바인드 마운트는 양방향으로 동작한다. 컨테이너에서 만든 파일을 호스트 컴퓨터에서 수정할 수 도 있고, 반대로 호스트에서 만든 파일도 컨테이너에서 수정할 수 있다.
  • 호스트 컴퓨터에 대한 공격을 방지하기 위해 컨테이너는 최소 권한을 가진 계정으로 실행되는데, 바인드 마운트를 사용하면 호스트 컴퓨터 파일에 접근하기 위해 권한 상승이 필요하다. 그래서 Dockerfile 스크립트에서 USER 인스럭션을 사용해 컨테이너에 관리자 권한을 부여한다. (리눅스는 root, 윈도는 ContainerAdministrator 계정으로 실행된다.)
  • 파일에 쓰기 작업을 할 필요가 없다면 호스트 컴퓨터의 디렉터리를 읽기 전용으로 컨테이너에 연결할 수도 있다. 이 방법은 호스트 컴퓨터에 작성한 설정을 컨테이너에 적용하기 위해 자주 쓰인다.(to-do 어플리케이션은 이미지 내에 로그 출력을 최소한으로 줄이도록 설정된 설정 파일을 내장하고 있는데, 이 방법으로 이미지를 수정하지 않고도 애플리케이션의 설정을 변경할 수 있다.)
// to-do 애플리케이션은 /app/config 경로가 존재할 경우 이 디렉터리에서 추가 설정파일을 로드한다. 호스트 컴퓨터의 디렉터리를 이 경로에 연결하도록 바인드 마운트를 적용한 컨테이너를 실행해 애플리케이션이 호스트 컴퓨터에 있는 설정 파일을 사용하도록 하라. 이 책 소스 코드의 압축을 푼 디렉터리까지 이동한 다음, 아래 명령을 입력한다.


source="$(pwd)/config" && target='/app/config'

//바인드 마운트된 호스트 컴퓨터의 디렉터리에 로그 레벨을 저정한 설정 파일이 들어 있기 때문에 컨테이너 속 애플리케이션이 이 설정 파일을 읽어 들여 적용한다.
docker container run --name todo-configured -d -p 8013:80 --mount type=bind,source=$source,target=$target,readonly diamol/ch06-todo-list

curl http://localhost:8013

호스트 컴퓨터에 위치한 설정 파일에는 좀 더 상세한 내용까지 로그를 출력하도록 설정돼 있다.
컨테이너를 실행하면 호스트 컨테이너의 디렉터리가 연결되고 애플리케이션이 설정파일 디렉터리를 발견해 안에 있는 로그 설정을 읽어들인다. 많은 양의 debug 레벨 로그가 출력된 것으로 보아 설정이 변경됐음을 알 수 있다.

호스트 컴퓨터가 접근할 수 있는 스터리지라면 무엇이든 바인드 마은트를 통해 컨테이너에 연결할 수 있다.

6.4 파일 시스템 마운트의 한계점

바인드 마운트와 볼륨을 효율적으로 활용하려면 각 요소의 핵심 사용 시나리오와 한계점을 이해 해야한다.

컨테이너의 마운트 대상 디렉터리가 이미 존재하고 이미지 레이어에 이 데렉터리의 파일이 포함돼 있다면 어떻게 될까?
이미 존재하는 대상 디렉터리에 마운트하면 마운트의 원본 디렉터리가 기존 디렉터리를 완전히 대체한다. 그래서 이미지에 포함돼 있던 원래 파일을 사용할 수 없다.

디렉터리의 목록을 출력하는 간단한 컨테이너를 실행해 직접 확인해보자.

// 마운트가 없는 컨테이너를 실행해 이미지에서 받은 파일 목록을 확인하라. 그 다음 마운트를 지정해 컨테이너를 다시 실행하고 마운트 원본 디렉터리의 파일 목록이 출력되는지 확인하라.

cd ./ch06/exercises/bind-mount
source="$(pwd)/new" && target='/init'

//컨테이너를 실행하면 /init 디렉터리의 파일 목록을 출력한다. 이 컨테이너는 바인드 마운트가 마운트되지 않았으므로 이미지에 포함된 기존 파일의 목록이 출력된다.
docker container run diamol/ch06-bind-mount

처음 실행한 컨테이너는 두 개의 파일명 abc.txt와 def.txt를 출력했다.
이들 파일은 이미지 레이어에서 컨테이너로 전달된 파일이다.

// /init를 대상으로 바인드 마운트를 마운트해 컨테이너를 실행하면 원래 디렉터리의 내용은 숨겨지고 바인드 마운트의 원본 디렉터리가 이를 대체한다.

docker container run --mount type=bind,source=$source,target=$target diamol/ch06-bind-mount

두번째 컨테이너는 이미지 레이어에서 받은 파일이 마운트된 파일로 대체 됐으므로 파일 목록이 123.txt, 456.txt로 바뀌었다.

두 번째 시나리오는 이와는 조금 다르다.
호스트 컴퓨터의 파일 하나를 컨테이너에 이미 존재하는 디렉터리로 마운트 하면 어떻게 될까?
이번에는 디렉터리의 파일이 합쳐져 이미지에서 온 파일과 호스트에서 마운트된 파일이 모두 나타난다.(단, 윈도 컨테이너는 이 기능을 제공하지 않아 동작이 달라짐)

컨테이너 파일 시스템은 윈도 컨테이너와 리눅스 컨테이너의 동작이 일치하지 않는다. (동일하게 동작하는 경우가 없는것은 아님)

단일 파일 마운트의 한계점은 이보다 더 명확하다. 윈도와 리눅스 컴퓨터를 모두 갖고 있거나 리눅스 컨테이너와 윈도 컨테이너를 모두 지원하는 윈도 버전 도커 데스크톱에서 확인할 수 있다.

리눅스 컨테이너에는 단일 파일 마운트 기능을 사용할 수 있다. 대상 디렉터리가 컨테이너에 이미 존재한다면 마운트되는 디렉터리와 내용이 합쳐진다.

세 번째 시나리오는 다른 시나리오에 비해 드물다.
분산파일 시스템을 사용하면 네트워크상의 모든 컴퓨터에서 데이터에 접근할 수 있지만, 대개 분산 파일 시스템의 메커니즘은 윈도 파일 공유에 쓰이는 SMB, 파일스 , AWS, s3 등 로컬 컴퓨터의 운영체제의 파일시스템과 다른 경우가 많다. 이런한 분산 파일 스토리지를 컨테이너에 마운트하면 일반적인 파일 시스템의 일부처럼 보이지만 지원하지 않는 동작이 있을 수 있다.

컨테이너에 분산 스토리지를 마운트할 계획이라면, 이런 위험과 함께 분산 스토리지의 성능이 로컬 스토리지와 큰 차이가 있다는 것도 고려해야한다.

6.5 컨테이너의 파일시스템은 어떻게 만들어지는가?

모든 컨테이너는 도커가 다양한 출처로부터 모아 만든 단일 가상 디스크로 구성된 파일시스템을 갖는다. 이 파일 시스템을 유니언 파일 시스템이라고한다. 도커를 설치하면 우리가 사용하는 운영체제에 맞춰 최선의 구현을 선택해 주기 때문에 상세한 구현은 신경쓸 필요가 없다.

컨테이너는 유니언 파일 시스템을 통해 물리적 위치가 서로 다른 파일과 디렉터리에 마치 단일 디스크를 사용하듯 접근할 수 있다.

컨테이너이세 실행되는 애플리케이션의 입장에서는 단일 디스크만을 볼 수 있지만 컨테이너나 이미지를 생성해 사용하는 사용자는 여러 출처를 합쳐 이 디스크를 구성 할 수 있다.
여러 개의 이미지 레이어, 역시 하나 이상의 볼륨 마운트와 바인드 마운트를 컨테이너에 연결 할 수 있다.
그러나 기록 가능 레이어는 하나밖에 가질 수 없다.

컨테이너 스토리지를 구성할 때 고려해야할 일반론

  • 기록 가능 레이어: 비용이 비싼 계산이나 네트워크를 통해 저장해야 하는 데이터의 캐싱 등 단기 저장에 적합하다. 각 컨테이너마다 독립적인 기록 가능 레이어를 갖지만, 컨테이너가 삭제되면 여기 저장된 데이터는 유실된다.

  • 로컬 바인드 마운트: 호스트 컴퓨터와 컨테이너 간 데이터를 공유하기 위해 사용한다. 개발자의 로컬 컴퓨터에서 컨테이너로 소스 코드를 전달하기 위해 사용하면 로컬 컴퓨터에서 수정한 내용이 이미지 빌드 없이도 즉시 컨테이너로 전달 될 수 있다.

  • 분산 바인드 마운트: 네트워크 스토리지와 컨테이너 간에 데이터를 공유하기 위해 사용한다.
    가용성이 높지만 로컬 디스크와 비교해 지원하지 않는 파일 시스템 기능이 있거나 성능 면에서 차이가 있을 수 있다.
    읽기 전용으로 설정 파일을 전달하거나 공유 캐시로 활용할 수 있으며 읽기 쓰기 가능으로 데이터를 저장해 동일 네트워크 상의 모든 컨테이너나 컴퓨터와 데이터를 공유하는 데 적합하다.

  • 볼륨 마운트: 컨테이너와 도커 객체인 볼륨 간에 데이터를 공유하기 위해 사용된다. 볼륨 마운트를 사용하면 애플리케이션이 볼륨에 데이터를 영구적으로 저장한다. 컨테이너를 교체하는 방식으로 애플리케이션을 업데이트해도, 이전 버전 컨테이너의 데이터를 그대로 유지할 수 있다.

  • 이미지 레이어: 이미지 레이어는 컨테이너의 초기 파일 시스템을 구성한다. 레이어는 적층 구조를 갖는데, 후속 레이어와 이전 레이어의 내용이 서로 충돌하는 경우 후속 레이어의 내용이 적용된다. 레이어는 읽기 전용이며 여러 컨테이너가 공유한다.

profile
잼나게 코딩하면서 살고 싶어요 ^O^/

0개의 댓글