본문 바로가기

개발공부/Docker & Kubernetes 실전 가이드 강의

Udemy : Docker & Kubernetes 실전 가이드 (3)

728x90

이미지와 컨테이너의 데이터 관리하기

1. 데이터 카테고리/ 다양한 종류의 데이터 이해하기

- 실행 중인 어플리케이션은 코드 변경을 해선 안되기 때문에 이미지는 읽기 전용으로 기능한다

- 임시 사용자 데이터는 메모리에만 저장하는 등 일시 저장한다 ~ 읽기 전용으로 다룰 필요가 없다.

-> 컨테이너 레이어(부가 레이어)에 저장한다. 읽기 - 쓰기 권한을 가지고 임시 데이터를 다루는 레이어.

- 영구 사용자 데이터(ex 사용자 계정) : 컨테이너가 중지/ 제거되더라도 보존되어야 하는 데이터

-> 컨테이너와 볼륨에 저장한다.

 

2. 데이터 관리를 위한 도커화

- 임시 데이터의 경우 컨테이너에 저장되므로 로컬 머신에서 볼 수 없다

- 로컬 머신에서 코드를 변경한 경우 이미지를 새로 빌드하고 이를 기반으로 한 컨테이너도 새로 실행해야 한다.

- 컨테이너에서 생성되서 저장되는 모든 데이터는 컨테이너 삭제 시 같이 삭제된다 : 이미지에 데이터가 저장되는 것이 아니기 때문에(이미지는 읽기 전용 레이어, 컨테이너의 추가 레이어가 읽기,쓰기 레이어기 떄문에 여기에 저장된다)

 

3. 볼륨

- 볼륨은 호스트 머신의 폴더 ~ 호스트 컴퓨터에 장착된 하드 드라이브에서 사용가능하거나, 컨테이너로 매핑되는 것

- 컨테이너 내부의 폴더로 매핑되는 것은 도커파일의 COPY와 유사 ~ 차이점 : COPY는 한 번의 스냅샷을 만들고 끝이지만, 볼륨의 경우에는 매핑 후 수정사항도 바로 반영된다 ~ 데이터의 유지가 가능하다.

적용방법

도커파일에서 VOLUME 명령어 사용 : VOLUME ["컨테이너 내부 데이터 저장 폴더 경로"]

 

4. 볼륨의 종류

~ 기본적으로 도커는 볼륨에 저장할 폴더를 호스트 머신에서 개발자가 모르는 곳에 미러링해서 관리한다.

1) 익명 볼륨 : 이름이 부여되지 않은 볼륨, 도커가 자동으로 이름 생성

~ 도커가 관리하기 때문에, 컨테이너가 존재하는 동안에만 볼륨도 존재한다.

= 하나의 특정 컨테이너와 밀접한 연관을 가진다.

- 컨테이너에 --rm 조건(중지 시 자동 제거조건)을 붙이지 않고 연관되어 만들어진 익명 볼륨은 컨테이너를 제거해도 제거되지 않는다. 

 

2) 명명된 볼륨 : 이름을 부여해서 컨테이너가 삭제되더라도 계속 유지되는 볼륨을 만들 수 있다.

-> docker run -v 명명하고 싶은 볼륨 이름:볼륨 대상 파일 경로 ~ 컨테이너 이름 뒤 위치

ex) docker run -v feedback:/app/feedback

= 하나의 컨테이너에만 연결되는 것이 아니다.

컨테이너를 삭제해도 명명된 볼륨은 계속 남아있다.

 

5. 바인드 마운트 : 바인드 마운트한 폴더를 하나의 볼륨으로 사용하는 개념

- 스냅샷 이후 이미지 리빌드와 컨테이너 재실행을 하지 않고도 수정 사항을 반영할 수 있도록 하는 기능

- 바인드 마운트는 개발자가 호스트 머신에 매핑되는 컨테이너의 경로를 설정할 수 있다. ~ 볼륨과 차이점

- 바인드 마운트에 소스 코드를 저장하면, 도커는 소스 코드를 복사할 때 스냅샷이 아니라 바인드 마운트에 저장된 호스트 머신의 소스 코드에서 복사해온다. 그렇기 때문에 코드의 변경 사항을 바로 반영할 수 있다.

컨테이너 내부 경로의 경우 더 긴 내부 경로가 우선하고 더 짧은 내부 경로를 덮어 쓴다.

적용 방법

docker -v 소스코드의 프로젝트 절대 경로(파일명X): 컨테이너 내부 복사할 폴더 위치

~ 파일에 바인딩하고 싶은 경우는 파일명을 입력해도 된다

+ 특수 문자 등이 있을 경우 큰 따옴표로 감싸는 방법이 있다.

- 바인드 마운트하는 폴더에 도커가 접근할 수 있어야 한다.

cf) 원도우가 아닌, WSL이 아닌 경우에는 도커 데스크탑 설정에서 리소스 - 파일 공유 항목에서 도커가 해당 프로젝트 경로에 접근할 수 있도록 설정해야 한다.

 

- 바인드 마운트 - 바로가기

macOS / Linux: -v $(pwd):/app

Windows: -v "%cd%":/app

 

6. 다른 볼륨 결합 & 병합하기

- 지금까지의 방식으로 이미지를 빌드하고 컨테이너를 실행하면 바인드 마운트에서 호스트 머신의 프로젝트를 컨테이너에 덮어쓰기 때문에 이미지로 받아온 언어 등의 종속성이 없어지게 된다.

- 도커는 컨테이너 내부 폴더 파일보다 호스트 머신의 소스 코드을 더 우선한다.

- 그러므로 컨테이너 내부에 덮어쓰면 안되는 부분이 있다는 것을 알려야 한다.

- 익명 볼륨을 추가하고 바인딩한다. ~ 도커파일에서 만들지 않고 -v 명령어를 사용할 수도 있다.(기존 방식도 가능 - 이미지를 리빌드해야됨)

~ -v 이후 콜론 앞에 1) 호스트 머신 경로 : 바인드 마운트 2) 그 외 : 볼륨의 이름으로 간주해 명명된 볼륨을 생성

 

익명 볼륨을 추가하고 거기에 덮어쓰면 안되는 종속성을 연결하면 해결할 수 있다. : 익명 볼륨을 설정하면 바인드 마운트의 예외로 둘 수 있다.

cf) 노드JS에서 Nodemon 확장패키지를 사용할 때 Wsl2인 경우 별도 설정이 필요하다.

 

바인드 마운트의 내용을 삭제하려면 로컬 머신의 모든 로컬 컨텐츠를 삭제해야 한다.

 

7. 읽기 전용 볼륨

바인드 마운트를 읽기 전용으로 설정하기 : 바인드 마운트 매핑 도커 경로 뒤에 :ro를 추가한다. 그러면 도커는 로컬 파일에 대한 쓰기 권한이 없게 된다.

 

8. COPY vs 바인드 마운트

- 바인드 마운트는 개발 중인 docker run 명령일 때 적용 가능

- COPY는 프로덕션 환경에서 필요한 스냅샷을 복사하기 때문에 필요하다.

 

9. dockerignore 명령 사용하기

.dockignore 파일 생성 후 복사해서는 안되는 파일과 폴더를 지정할 수 있다.(깃 이그노어와 동일) ~ 이미지에 복사되지 않는다. ~일반적으로 애플리케이션이 올바르게 실행되는데 필요없는 것을 추가함

 

10. 환경 변수 & ".env" 파일 작업

인수와 환경변수 : 보다 유연한 이미지와 컨테이너를 만들 수 있다.

- 도커는 빌드타임 인수와 런타입 환경변수를 지원한다.

1) 인수 : 도커파일에서, 또는 전체 애플리케이션 코드에서 특정 명령어로 다른 값을 추출하는 데 사용할 수 있다.

2) 환경변수 : 도커파일 내부, 그리고 애플리케이션 코드 안에서 사용 가능하다.

 

환경변수 적용 : 도커파일에서 ENV PORT 80(포트넘버) ~ PORT 변수에 80을 할당한다는 뜻이다.

장점 : --env(-e) 명령어(여러 개 붙일수 있다)를 활용한 설정이 가능 ~ 이미지를 리빌드하지 않고 포트 넘버 변경 가능

 

옵션 : .env 파일을 만들고 관련 설정을 모아둘 수 있다. 그리고 실행문에서 --env-file .env 명령을 하면 편하게 값을 읽을 수 있다.

+ 보안 데이터의 경우 이미지에 포함해서는 안된다. 누구나 조회할 수 있기 때문에 ~ .env 파일은 런타임 시에만 사용되므로 보안 데이터를 보호할 수 있다.

 

빌드타임 인수 : 환경변수의 디폴트 값도 유연하게 만들고 싶을 때 사용할 수 있다.

ARG NAME ~ 다만, CMD에서는 인수를 사용할 수 없다 : ARG는 컨테이너 실행 시 시작되는 런타임 명령이기 때문에

인수를 설정하고 난 후엔 run 명령문에서 해당 인수에 값을 새로 할당할수 있다 ~ ex) --build-arg ARG=8000 -> 빌드하고나면 해당 인수는 불변 인수로 활용된다.

 

인수 또는 환경변수 앞에는 $를 붙여 도커에게 인수 또는 환경변수라는 것을 알려줘야 한다.

이미지 빌드 시 인수를 할당하면 인수 레이어보다 아래에 위치한 레이어 작업이 다시 수행된다 ex) npm install

~ 전체 COPY 레이어 밑에 추가하는 것이 좋다.

 

 

 

 

 

 

728x90