가상화
여러 OS를 하나의 HW에서 동시에 실행할 수 있는 것
상황 가정
원래 HW 1개엔 OS 한 개.
이 상황에서 여러 애플리케이션 실행 원함.
문제 : 각 애플리케이션에서 필요로하는 java version 다름. 또한 DB 따로 써야하는데 같은 port 번호 공유.
해결책 :
1. 여러 컴퓨터 구매 -> 비용적 부담, 하나의 컴퓨터 리소스 모두 활용 못하는 비효율.
2. 하나의 HW 위에 여러 OS를 만들어보자.
-> 가상머신 (VMware, Virtual Box)
Q. 어떻게 가능하지?
운영체제 위에 Hypervisor 설치
Hypervisor : HW(cpu, ram, --) 가져와서 논리적으로 쪼갬. 그 쪼갠 것들을 각 OS로 할당.
가상머신에서 컨테이너로
가상머신 핵심기술인 Hypervisor 필요 없음.
운영체제 위에서 Docker Daemon 프로세스 동작.
-> 긱 컨테이너를 프로세스 단위로 실행시킴
과정 : Docker client 명령어 -> dockerd가 운영체제에 프로세스 격리 요청 -> 컨테이너 실행
가상머신 - 컨테이너 차이
공통 : HW, OS 깔림
가상머신 : 하이퍼바이저 & 물리적 HW 쪼개서 각각 guest OS 실행.
컨테이너 : docker daemon이 OS에 요청 & 각 앱 격리.
언제 뭘 사용하지?
가상머신 :
- 운영체제에 종속된 프로그램 실행 시
- 최신 운영체제에서 실행되지 않는 레거시 애플리케이션 실행 시
컨테이너 :
- 애플리케이션 빠르게 실행
(host OS -> guest OS 거치는 VM과 달리, host os만을 거침)
- 협업시 개발 환경 통일
(VM은 같은 guest OS 설치 + 프로그램 설치 번거로움. but 컨테이너는 같은 프로세스 환경만 격리시켜 실행하면 됨)
docker Layer
image
- 한 번 만들어지면 이미지 내 정보 절대 안변함 (불변성)
- 도커 이미지 용량 mb ~ gb
문제 : 이미지에 작은 변경사항 생겨 수정하려면, 큰 용량 다시 다운로드 받아야함 = 비효율
-> Solution : image Layer
Layer
각 Layer 특징
- 이전 레이어의 변경사항 가짐
- read only
도커 컨테이너 생성 때의 레이어
- 컨테이너 생성하면 쌓인 레이어 위에 R/W Layer 추가.
- 애플리케이션 실행 중 추가된 파일 + 변경사항이 R/W Layer에 저장됨 -> 변경사항 받아주기에, 이미지 레이어는 불변 유지 가능
Layer 과정
- dockerFile 이미지 정의
- 명령어들 순서대로 실행 -> 실행 때마다 새로운 레이어 생성. 변경 사항은 레이어에 저장.
- 이미지 실행시, 해당 이미지의 모든 레이어 연결되어 전체 파일 시스템 구성.
- 애플리케이션 실행 중 변경사항은 R/W Layer에 저장.
문제 : Layer 많아지면 이미지 용량, 빌드 시간, 관리복잡도 UP
-> Solution : 명령어 합치기 OR 멀티스테이지 빌드
멀티스테이지 빌드
이미지 만들면서, 빌드엔 필요하지만 실행시 필요 없는것을 떼어내는 것.
-> 방법 : 빌드 여러번 거쳐 이미지 용량 최소화
- Multi Stage : Docker build의 옵션 기능.
- Docker build란? -> dockerFile 내용 해석하고 도커 이미지 만드는 "과정"
어떻게 가능하지?
- 멀티스테이지 -> 여러 base image 사용하여 docker build 수행.
- FROM 키워드를 기준으로 작업공간(stage) 분리.
- 가장 마지막에 실행된 stage 작업만 이미지로 생성됨. 여러개로 분리됐다고 여러개 생성 X.
-> 이 특성 이용하여 Image 크기 줄임.
용량 줄이기
- stage -> build stage + run stage로 나눔.
build - run 차이?
- build : 필요한 것 정의 & 이미지 생성. RUN, COPY, ADD, WORKDIR 등 명령어들 실행됨.
(건물 짓는 과정. 여러 공구들이 쌓임)
- run : "이미 만들어진" 이미지 기반 컨테이너 실행.
(지어진 건물에서 사는 것. 건물 지을 때 쓰인 공구들 더이상 필요 없음)
Q. build - run 나눴다고 왜 용량 줄어듦?
Docker 이미지는 레이어 단위.
멀티 스테이지 시에, 불필요한 레이어 포함 안시킴. 필요한 것만 추출해오는 것.
Single stage
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "app.js"]
- npm install 위해 필요한 build 도구들, 의존성들 이미지 안에 그대로 남음.
-> 실제로 실행 땐 필요 없는데도 포함되어버림
=> 용량 증가
Multi stage
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install
FROM node:18-slim
WORKDIR /app
COPY --from=builder /app /app
CMD ["node", "app.js"]
- 첫 스테이지 -> 무거운 작업
- 둘 스테이지 -> 필요한 것만 가져와서 실행