Docker 03
어떻게 컨테이너의 변경 사항 및 데이터를 저장할 수 있을까?
- 컨테이너는 하나의 프로세스라고 생각할 수 있다.
- 프로세스가 완벽히 종료되어 사라지면 프로세스의 데이터도 같이 사라진다.
- 이렇게 컨테이너 내부에서 생성되거나 변경된 파일에 대한 데이터를 관리해야 하는 니즈가 있다.
- Docker는 Container Layer의 문제점을 개선한 Docker Volumne이라는 기술로 이것을 해결했다.
R/W Container Layer
- 컨테이너 내에서 생성/변경된 모든 파일을 Read-Write 가능한 Container Layer에 저장한다.
- Docker는 Copy-on-Write 방식으로 변경 사항을 관리한다.
- 컨테이너는 이미지의 연속된 층인데 컨테이너 자체에서 관리하는 층(R/W layer)을 하나 둔다.
- 그래서 파일, 디렉터리를 읽기만 할 때는 기존 파일을 참조하고, 수정하는 경우에만 파일을 해당 레이어로 복사해서 수정한다.
문제점
- 컨테이너의 R/W Layer는 각 컨테이너마다 가지고 있다.
- 그 말은 각자 다른 호스트에 각각 다른 Layer를 가지고 있다는 것이고, 그렇기 때문에 데이터를 다른 호스트(컨테이너)로 이전하기 어렵다.
- 그리고 Container Layer도 리눅스 커널이 지원하는 가상화 기법 중 하나인 Storage Driver를 사용하기 때문에 계속 추가되면 성능 저하의 원인이 된다.
- 무엇보다 컨테이너가 어떤 문제로 인해 종료될 경우 R/W Container Layer는 컨테이너 내부에 존재하는 계층이고, 여전히 데이터는 휘발되기 때문에 영구적으로 유지시킬 수 없다.
Docker Volume
- 컨테이너 데이터의 영속성을 유지하기 위해 탄생한 기술
- 크게 3가지가 있다.
- Bind Mount
- Volume
- tmpfs
Bind Mount
- 호스트의 특정 디렉터리 및 파일을 컨테이너 시작과 동시에 마운트
- 단순하지만 확실한 효과, 여전히 많이 사용하고 있다고 한다.
- 호스트 machine의 파일 시스템 및 디렉터리 구조에 의존적이라는 점이라는 단점이 있다.
Volume
- Volume이라는 객체(?)를 만들고 해당 Volume을 컨테이너가 생성될 때 mount 해서 파일을 관리한다.
- Bind Mount와 다르게 호스트 머신에 의존적이지 않은 영속적인 컨테이너 파일 관리를 할 수 있다.
- Volume은 컨테이너 내부에 존재하지 않기 때문에 위에 언급한 Container Layer처럼 컨테이너가 종료 혹은 삭제되어도 데이터가 휘발되지 않는다.
- 요컨대 Container안에 포인터를 두고, 그 포인터가 호스트 머신의 Volume이라는 객체를 가리키고 있어서 컨테이너 내부에서 영속시켜야 하는 파일들이 Volume 안에 저장된다고 생각하면 될 것 같다.
- 컨테이너가 다른 컨테이너에 바인딩된 볼륨을 바인드 해서 사용할 수 있다. 즉 컨테이너 간 데이터를 공유하는 것이 가능하다.
- 중요한 점이 Volume은 컨테이너 내부에 없다. 그래서 어떤 컨테이너 a에 바인드 된 볼륨을 다른 컨테이너 b에 바인딩했을 때 a가 정지하거나 삭제되어도 b와 Volume 기능은 정상적으로 작동한다.
Volume Mount vs Bind Mount
- 바인드 마운트는 반드시 호스트 디렉터리의 내용으로만 보게 된다.
- 즉 바인드 마운트를 하면 컨테이너 안에선 컨테이너 디렉터리와 무관하게 호스트 디렉터리 기준의 파일만 보인다.
- 볼륨 마운트의 경우 컨테이너 디렉터리에만 있는 파일 이어도 그 파일이 컨테이너 안에서 보인다.
tmpfs
- 컨테이너 실행 시 호스트 메모리에 마운트 된다.
- 컨테이너 종료와 함께 데이터가 삭제된다.
- 컨테이너 간의 데이터 공유는 불가능하다. -> 메모리에 있기 때문