이제 이미지와 컨테이너 내부의 데이터를 관리하는 방법을 알아보자.
- 이미지와 컨테이너가 다양한 방식으로 어떻게 데이터를 관리하는가?
- 다른 폴더 등에 연결하는 방식
- 도커에 내장된 볼륨이라는 개념에 대해 알아보자.
데이터 카테고리 / 다양한 종류의 데이터 이해하기
다양한 데이터 종류가 있고, 어떤 종류의 데이터를 가지고 있는지 이해해야 직면할 수 있는 문제를 이해할 수 있다.
- 애플리케이션(코드 + 환경)
- 임시 애플리케이션 데이터
- 애플리케이션이 실행되는 동안 생성된 데이터
- 웹사이트의 경우 입력된 사용자의 데이터가 바로 그 데이터.
- 코드의 변수에 저장할 수 있으므로 메모리에만 저장되거나, 데이터베이스나 파일에 저장될 수 있다.
- 컨테이너가 종료될 때 그 데이터를 잃어도 상관 없다.
- 읽고 쓰기 전용 → 컨테이너에 데이터 저장
3. 영구 애플리케이션 데이터
- 파일 및 데이터베이스에 저장되는 데이터
- 실행 중인 컨테이너에서 그 데이터를 가져와 생성
- 컨테이너가 중지되고 다시 시작되더라도 그대로 있어야 한다.
- read-write 데이터
- 애플리케이션이 실행되는 동안 작성하지만 영구적으로 저장되어야 한다.
- 컨테이너에 저장하지만 볼륨의 도움을 받게 된다.
실제 앱 분석하기
이제 다양한 종류의 데이터를 확인하고 작동해보자.
- feedback 폴더: 영구 데이터 저장 폴더
- temp: 임시 데이터 저장 폴더
데모 앱 구축 & 이해하기
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
CMD ["node", "server.js"]
- Dockerfile 작성
- docker build -t feedback-node .
- docker run -p 3000:80 -d --name feedback-app --rm feedback-node
feedback 폴더에 전송한 데이터를 확인할 수 있는데, 로컬 시스템 폴더 내에서는 확인할 수 없다. 이는 도커 컨테이너 내부에만 존재하므로 나타나지 않는 것이다. Dockerfile에서 로컬 폴더를 이미지에 복사하고, 컨테이너는 그 이미지를 기반으로 하기 때문이다. 그러므로 이미지와 컨테이너는 로컬 폴더를 기반으로 하는 자체 파일 시스템이 있다는 것을 의미한다.
로컬 폴더와 이미지 내부 파일 시스템은 연결되어 있지 않다.
코드를 이미지에 복사하면 이미지 내부의 특수 파일 시스템에 존재하고 잠긴다. 그리고 호스트 폴더나 호스트 머신과 컨테이너에 대한 연결이 끊긴다. 그러므로 이미지를 생성하는데 사용했던 스냅샷이 복사된 격리된 파일 시스템을 가지게 된다.
문제 이해하기
- docker stop feedback-app
- docker run -p 3000:80 -d --name feedback-app feedback-node (rm 옵션 없이 실행)
서버를 재실행하니 이전 서버에서 저장했던 파일이 사라진 것을 볼 수 있다. 이는 처음에 컨테이너를 중지할 때 컨테이너를 삭제했기 때문이다.
3. docker start feedback-app
컨테이너를 삭제하지 않고 재실행하면 파일이 그대로 남아 있는 것을 볼 수 있다.
컨테이너를 제거하면 컨테이너의 모든 데이터가 지워진다. 컨테이너 전체가 클리어되기 때문이다.
새 컨테이너를 실행해도, 동일한 이미지 상의 공간에 있다 해도, 이전 컨테이너에서 생성되어 저장된 모든 데이터는 손실된다. 이미지는 읽기 전용이기 때문이다.
따라서 컨테이너는 파일을 생성할 때 이 파일을 이미지에 쓰지 않는다. 상단에 추가되는 자체 read-write 레이어에 저장한다. 그래서 컨테이너가 제거되면 변경되지 않는 이미지만 남게 된다.
즉, 새 컨테이너를 시작하면 동일한 이미지 상에서 실행된 이전 컨테이너에 의해 변경된 것이 없는 동일한 기본 파일 시스템으로 시작한다. (동일한 이미지에 기반한 다수의 컨테이너가 서로 완전히 격리)
하지만 컨테이너가 삭제되도 피드백 텍스트 파일을 유지하고 싶으면 어떻게 해야 할까?
볼륨
도커에는 볼륨이라는 내장 시스템이 있다. 볼륨은 데이터를 유지하도록 도우며, 위에서 다룬 문제를 해결하는데 도움이 된다.
볼륨의 특징
- 호스트 머신의 폴더
- 호스트 컴퓨터에 장착된 하드 드라이브에 존재하여 사용 가능하거나 컨테이너로 매핑되는 것
- 도커가 인식하는 컴퓨터에 있는 폴더
- 도커 컨테이너 내부의 폴더에 매핑
- 컨테이너 내부의 폴더를 컴퓨터 상의 컨테이너 외부 폴더에 연결할 수 있다.
- 두 폴더의 변경 사항은 다른 폴더에 반영된다.
- 컴퓨터에 파일을 추가하면 컨테이너 내부에서 액세스할 수 있고, 컨테이너가 매핑된 경로에 파일을 추가하면 컨테이너 외부, 즉 컴퓨터에서도 사용할 수 있다.
- 위 매커니즘을 통해 볼륨을 통해 데이터를 유지할 수 있다
- 볼륨은 컨테이너가 종료된 경우에도 지속되며 계속 존재한다.
- 컨테이너에 볼륨을 추가하는 경우, 해당 볼륨은 제거되지 않으며 컨테이너가 제거되어도 해당 볼륨이 유지되므로 볼륨의 데이터가 유지된다.
- 컨테이너는 볼륨에 데이터를 읽고 쓸 수 있다.
- 컨테이너 외부에서 액세스하려는 폴더와 단순히 컨테이너 종료 및 컨테이너 제거 후에도 살아 있어야 하는 데이터에 사용할 수 있다.
- 데이터가 컨테이너 외부에도 저장되면 컨테이너를 제거해도 살아남기 때문이다.
컨테이너에 볼륨 추가하기
특수한 명령을 Dockerfile에 추가해보자.
...
VOLUME [ "/app/feedback" ]
...
컨테이너의 외부 폴더에 매핑 될 컨테이너 내부의 경로를 지정한다.(데이터가 생존할 위치)
- docker build -t feedback-node:volumes .
- docker run -p 3000:80 -d --name feedback-app --rm feedback-node
- !! 컨테이너 중단(삭제) !!
- docker run -p 3000:80 -d --name feedback-app --rm feedback-node
그러나 기대했던 것과는 다르게 컨테이너를 재실행(재생성)하니 데이터가 삭제되어 있었다.
분명 볼륨을 추가해서 데이터가 유지되는 것을 예상했는데, 어디가 잘못된 걸까?
명명된(named) 볼륨
도커에는 두 가지의 외부 데이터 저장 메커니즘이 있다.
- 볼륨
- 바인드 마운트
여기서는 볼륨에 집중해 보겠다.
현재 우리는 익명의 볼륨을 사용하고 있다. 이 이미지에 익명의 볼륨을 추가하고, 이미지를 기반으로 실행되는 컨테이너에 데이터를 추가한다. 또는 명명된 볼륨을 할당할 수도 있다.
이 두 경우 모두 도커는 일부 폴더와 경로를 컴퓨터에 설정한다. 우리는 컨테이너 내부의 경로만 지정했지, 컴퓨터의 경로는 지정하지 않았다. 그래서 미러링된 폴더가 어디있는지 모른다.
이러한 볼륨에 액세스할 수 있는 유일한 방법은 docker volume 명령을 사용하는 것이다.
-
- docker volume ls
- 도커가 현재 관리 중인 모든 볼륨을 리스팅
- 익명의 볼륨이기 때문에 도커가 자동으로 명명한 이름이 나타난다.
- 컨테이너가 존재하는 동안에만 실제로 존재한다. → 컨테이너를 종료하면 데이터 증발
- 컨테이너가 생성될 때마다 익명 볼륨이 다시 생성되기 때문이다.
- docker volume ls
명명된 볼륨을 사용하면 컨테이너가 종료된 후에도 볼륨이 유지된다. 즉, 하드 드라이브의 폴더가 그대로 유지된다.
따라서 그 이후에 새 컨테이너를 시작하면 볼륨과 폴더가 복구되어 해당 폴더에 저장된 모든 데이터를 계속 사용할 수 있다. 명명된 볼륨은 영구 저장되어야 하는 데이터나, 편집하거나 직접 볼 필요 없는 중요한 데이터에 적합하다.
실질적으로 컴퓨터 폴더에 액세스하지 않을 것이기 때문이다.
컨테이너를 실행할 때 명명된 볼륨 생성
- docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback feedback-node:volumes
- -v feedback:/app/feedback: 저장하려는 컨테이너 파일 시스템 내부의 경로 지정
- -v feedback:/app/feedback: 원하는 이름 지정, 이름을 구분하기 위해 : 로 구분
- 명명된 볼륨은 컨테이너가 삭제될 때 도커에 의해 삭제되지 않는다.
컨테이너 중지 후 볼륨 확인
컨테이너가 중지되었어도 여전히 feedback volume이 있는 걸 확인할 수 있다.
새로운 컨테이너 생성
docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback feedback-node:volumes
새로운 데이터를 생성해서 데이터를 확인해 보면, 여전히 존재하는 것을 확인할 수 있다.
마침내 명명된 볼륨의 도움으로 데이터 유지를 관리할 수 있게 되었다.
익명 볼륨 제거하기
컨테이너를 실행할 때 —rm 옵션 없이 실행하면 컨테이너를 제거하더라도 익명 볼륨은 제거되지 않는다. 사용하지 않는 익명 볼륨을 다음 명령어로 정리하자.
- docker volume rm VOL_NAME
- docker volume prune
'log.info' 카테고리의 다른 글
[Redis] 데이터 추가 및 관리 명령어 (0) | 2024.06.17 |
---|---|
[Redis] Redis에 대해 알아보자 ! (0) | 2024.06.16 |
[Docker] 이미지, 컨테이너 요약 (0) | 2024.06.13 |
[Docker] 이미지 만들기 (0) | 2024.05.29 |
[Docker] 컨테이너 업데이트, Docker Compose (0) | 2024.05.28 |