Container 는 뜻 그대로 화물 수송용 박스를 생각하면 됩니다. container에 다양한 화물을 넣고 다양한 운송수단에 적재되어 쉽게 옮길 수 있는데 서버에서도 마찬가지입니다. 서버 실행에 필요한 모든 것(코드, 런타임, 시스템도구)들을 container에 넣어 쉽게 추상화하고 어디서에든(GCP, AWS, Local-machine) 실행할 수 있습니다.

 

Docker image는 container의 모든 정보를 포함한 하나의 단위로 볼 수 있습니다.

 

Docker 를 사용하는 이유는 container를 활용하여 쉽게 개발환경과 운영환경을 동일하게 구성할 수 있기 때문입니다.

 

Docker container를 동시에 여러개를 생성하여 구동하려면 어떻게 해야 할까요?

하나씩 docker run 명령어를 치는 것은 귀찮음과 더불어 생산성도 떨어지게 됩니다. 이러한 문제를 해결하기 위하여 docker-compose 를 사용합니다. (docker-compose는 한번에 여러개의 container를 정의하고 실행시킬 수 있는 yml 형식의 설정 파일입니다.)


Docker image가 저장되는 방식

 

도커 이미지를 pull 받게 되면 마치 여러개로 분리된 조각을 내려받는 것처럼 보인다.

$ docker pull nginx:latest

Using default tag: latest
latest: Pulling from library/nginx
c499e6d256d6: Already exists
74cda408e262: Pull complete
ffadbd415ab7: Pull complete
Digest: sha256:282530fcb7cd19f3848c7b611043f82ae4be3781cb00105a1d593d7e6286b596
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

이렇게 분리된 데이터를 레이어(Layer) 라고 한다.
레이어는 도커 이미지가 빌드될 때 Dockerfile에 정의된 명령문(Instructions)을 순서대로 실행하면서 만들어진다. 이 레이어들은 각각 독립적으로 저장되며 읽기 전용이기 때문에 임의로 수정할 수 없다.

 

실제로 레이어가 어디에 어떻게 저장되는지 정확하게 확인하려면 docker image inspect 명령어를 실행한 뒤 출력된 결과에서 아래와 같은 해시값들을 볼 수 있다.

"sha256:c3a984abe8a88059915bb6c7a1d249fd1ccc16d931334ac8816540b0eb686b45"
"sha256:99134ec7f247e5a211c7205fec587bf72a6d4aac339b21858b892e9c04f78920"
"sha256:d37eecb5b7691ec21bd19989e37f8bb4d20b340a775591d0f3db5897d606b0e4"

이 해시값으로 호스트 머신 내 어딘가 실제 레이어 내용이 저장된 것을 찾을 수 있다.
좀 더 자세한 설명은 “만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS | 44BITS”를 참고하는 것을 추천한다.


그렇다면 도커 컨테이너가 실행될 때 생성되는 결과물들은 어디에 저장될까?


도커 컨테이너가 실행되면 모든 읽기 전용 레이어들을 순서대로 쌓은 다음 마지막에 쓰기 가능한 신규 레이어를 추가하게 된다. 그 다음 컨테이너 안에서 발생하는 결과물들이 쓰기 가능 레이어를 기록되게 되는 것이다.

 

즉, 아무리 많은 도커 컨테이너를 실행하더라도 기존 읽기 전용 레이어는 변하지 않고, 컨테이너마다 생성된 쓰기 가능 레이어에 데이터가 쌓이기 때문에 서로 겹치지 않으며 컨테이너가 종료되면 모두 사라지게 된다.

 


Docker image layer에 대해

도커 이미지 레이어가 중요한 이유는 이미지를 빌드할 때마다 이미 생성된 레이어가 캐시 되어 재사용 되기 때문에 빌드 시간을 단축할 수 있다.


하지만 Dockerfile에 정의된 모든 명령문(Instructions)이 레이어가 되는 것은 아니다.

RUN,  ADD, COPY 이 3가지 단계만이 레이어로 저장되고, CMD, LABEL, ENV, EXPOSE 등과 같이 메타 정보를 다루는 부분은 임시 레이어로 생성되지만 저장되지 않아 도커 이미지 사이즈에 영향을 주지 않는다.

 

이 글의 가장 첫 부분에서 pull 받은  nginx:latest 도커 이미지의 Dockerfile을 보면 처음에 베이스 이미지를 가져오는 부분을 포함해서 2개 RUN 명령까지 총 3개의 레이어를 받아왔다.
만약  Dockerfile에 RUN, ADD, COPY 명령문이 수정되면 기존 캐시가 무효가 되어 새로운 레이어를 생성하게 될 것이다.

 

도커 이미지를 각각 나누어서 저장한다. 쪼개서 나누는데 일치하는 데이터는 그대로 유지하고 일치하지 않는 레이어들은 새롭게 백업해서 저장한다.

 

레이어 단위로 저장을한다.

 

왼쪽: 이미지 A가 있는데 이미지 B를 다운받으면 레이어 D만 다운받게 된다.

이미지 A를 지운다 하더라도 이미지 B에서 레이어 A, B, C를 사용하고 있기 때문에 지워지지 않는다.

 

오른쪽: 이미 존재하는 레이어 A, B는 새로 다운로드 받을 필요가 없다. 

 

이미지 안에는 이미지 데이터베이스, 레이어 데이터베이스가 있다 

image/imagedb/layerdb

 

Id : 해시값 

Tag가 붙지 않으면 nginx 뒤에 latest로 표시가 된다.

ExposedPorts: 포트

 

Env : 환경변수 

Cmd : 컨테이너로 바꿔서 실행했을 때 컨테이너 안에서 프로세스가 돌아야한다. 그때 어떻게 돌아야 할지 설정한다.

nginx에 -g 옵션과 daemon off 로 실행한다.

 

실질적으로 파일 시스템을 구성해주는 부분이다.

레이어가 5개 보인다.

레이어 5개를 pulling 하면 다운로드 받을 수 있다.

 

image에 저장되고 image의 실질적인 정보들은 overlay2에 저장된다.

 

run 이나 create를 통해 container에 대한 데이터를 만들 수 있다.

 

레이어를 과하게 많이 받으면 image와 overlay에 데이터가 쌓인다.

 

'🚦 Server > Docker' 카테고리의 다른 글

Docker - container 제거하기  (0) 2021.01.13
Docker 로 python 실행하기  (0) 2021.01.08
Docker - 라이프 사이클, 명령어  (0) 2021.01.07
Docker - image, docker file, docker hub  (0) 2021.01.07
Docker 설치 - Mac  (0) 2021.01.07
복사했습니다!