인프런 커뮤니티 질문&답변

answntjd1006님의 프로필 이미지

작성한 질문수

개발자를 위한 쉬운 도커

이미지와 레이어(Layer)

이미지 레이어 관련 궁금증 질문드립니다!

해결된 질문

작성

·

185

·

수정됨

2

안녕하세요 궁금증이 생겨 질문드립니다!

강의 중 엔진엑스로 만든 이미지가 있는데 index.html이 다른 A가 있고 B가 있다라는 예시가 있었습니다.

 

이때 아래와 같이 설명해주셨는데요 이미지를 공유해서 사용하는거랑 컨테이너 생성속도랑 어떻게 연관이 있는건지 잘 이해가 가지 않아 질문드립니다.

동일한 이미지로 컨테이너를 아주 많이 만들어도 이 이미지로 실행된 모든 컨테이너가 하나의 이미지를 공유해서 읽어옵니다.

실제로 큰 부분을 차지하는 이미지를 하나로 유지할 수 있기 때문에 컨테이너를 생성할 때 속도가 빨라지는 것이죠.

 

또한 아래와 같이 설명해주셨는데요

컨테이너를 만들 때 사용된 이미지에 따라서 이미지의 읽기 전용 레이어 전체를 공유할수도 있고 일부만 공유할 수도 있습니다

이렇게 이미지의 읽기 전용 레이어를 활용하면 컨테이너를 실행할 때 전체 공간을 복사하지 않아도 되기 때문에 컨테이너를 빠르게 실행할 수 있습니다.

그리고 컨테이너가 늘어나면서 사용하는 공간을 최대한 작게 관리할 수 있습니다.

엔진엑스 이미지 A가 다운받아져있다 가졍하고 index.html이 다른 이미지 B를 다운 받는다 가정해보겠습니다.
이미지 B를 다운받을때 이미지 A와 레이어가 같은것은 다운받지 않고 레이어가 다른 index.html레이어만 다운받는걸까요?
컨테이너가 늘어나면서 사용하는 공간을 최대한 작게 관리할 수 있다라는게 어떤것인지 잘 이해가 되지 않아 질문드려봅니다 (레이어별로 파일이 나뉘어 있는걸까요)

혹시 위와 같은 부분을 실습으로 확인할 수 있는 것이나 공식문서 부분에서 확인할 수 있는게 있다면 같이 부탁드립니다!

답변 1

0

데브위키님의 프로필 이미지
데브위키
지식공유자

answntjd1006님 안녕하세요. 데브위키입니다.

 

이미지 B를 다운받을때 이미지 A와 레이어가 같은것은 다운받지 않고 레이어가 다른 index.html레이어만 다운받는걸까요? <- 네 맞습니다. 이 질문에 답이 있다고 보시면 될 것 같습니다!

 

먼저 이미지는 여러 개의 레이어로 구성되어 있습니다.

그리고 하나의 레이어는 이전 레이어의 변경 사항이 저장되어 있습니다.

예를 들어 여러 개의 이미지가 있을 경우에 강의 자료와 같이 아래 처럼 구성될 수 있는데요.

여기서 4개 모두 첫 6개 레이어의 값이 동일한 것을 알 수 있습니다.
image

nginx의 이미지 레이어는 6개, hello-nginx는 7개, config-nginx와 pre-config-nginx가 8개이고 이 4개의 이미지를 PC에 저장한다고 생각해 보면, 실제로 PC에 저장되는 레이어는 29개로 저장하지 않습니다.

같은 레이어는 재사용할 수 있기 때문에, 일단 모든 이미지에 저장되어 있는 6개의 레이어는 별개로 저장할 필요 없이 6개만 가지고 있으면 됩니다. 모든 레이어가 독립적으로 레이어를 가진다면 파일 용량을 많이 차지하겠죠. 그래서 레이어를 공유하는 구조가 스토리지를 효율적으로 사용한다고 하는 것입니다. (29개로 저장할 것을 10개로 저장해서 사용할 수 있기 때문입니다)

여기서 nginx:1.24.0 이미지만 PC에 가지고 있는 상태에서 hello-nginx 이미지를 다운받을 때는, PC에 이미 nginx:1.24.0의 레이어 6개를 PC에 가지고 있기 때문에 d22f82790361 레이어 1개만 다운받으면 hello-nginx 이미지를 사용할 수 있는 것입니다. 😀

 

nginx:1.24.0 이미지의 6개 레이어 안에는 nginx 소프트웨어가 포함되어 있습니다. 그리고 이 컨테이너를 실행할 경우, 컨테이너 레이어가 하나 추가됩니다.

image

nginx:1.24.0 이미지로 컨테이너를 10개 실행할 경우에도, 컨테이너 레이어가 1개씩 10개 추가되는 것이죠. 실제로 nginx 소프트웨어는 6개 레이어 안에 포함되어 있기 때문에, 6개 레이어는 컨테이너를 100개 추가하더라도 PC에 한 개만 저장됩니다. 레이어를 공유하는 구조가 아니라면 컨테이너를 한 개 실행할 때마다 nginx를 독립적으로 구성해야 해서 파일 사이즈를 많이 사용하게 될 것입니다.

 

강의 들으시면서 더 궁금하신 부분이 있으면 편하게 질문주세요!

 

 

answntjd1006님의 프로필 이미지
answntjd1006
질문자

안녕하세요 데브위키님 답변 달아주셔서 정말 감사드립니다
설명을 너무 잘해주신 덕분에 다른부분들은 모두 잘 이해가 되었습니다.
다만 한가지 걸리는 부분이 있는데 이미지를 공유하면 컨테이너 생성 속도가 빨라진다는 것이 어떤 것 때문에 생성속도가 빨라진다는 것인지 잘 모르겠어 질문드립니다

잘 모르겠지만 추측을 해보자면 A이미지를 통해 컨테이너가 실행되어있다 가정하면 A이미지를 만들때 쓰는 레이어들이 컨테이너 실행되는 동안 어딘가에 저장되어있고 이후 B이미지를 통해 컨테이너를 만들때 A이미지에 공통된 레이어가 있다면 이부분은 이미 올라와 있는 것을 사용하면 되니 생성속도가 빨라진다 추측이 되는데 맞을까요..?

A이미지를 컨테이너 만들때 사용하면 굳이 어딘가에 저장해놓지 않을거 같긴한데 잘모르겠으나 이렇지 않을까 생각이들어 추측해봅니다.

 

 

그리고 추가적 질문이 있습니다

section5에서 클라우드 네이티브를 설명해주시면서 상태 비저장인게 클라우드 네이티브하다라고 하셨는데 그럼 애플리케이션에서 필요한 상태는 어떻게 처리가 되는걸까요?

백엔드 단인 Spring에서 데이터베이스, Redis,AWS 등등과 같은 환경변수들이 많이 생길텐데 DockerFile에 ENV로 넣어 놓거나 Run시 직접 주입을 해주는걸까요?

그런데 환경변수가 많아지면 Run을 할때는 무리가 될거 같고 또한 스케일 업시 각 서버는 다른 환경변수를 가진다라는 생각이 드는데 어떻게 구성해야하는지 잘 모르겠어 질문드려봅니다!

 

 

데브위키님의 프로필 이미지
데브위키
지식공유자

안녕하세요!

 

네 먼저 컨테이너 생성 속도에 관련해서는 이미지를 공유하지 않는 환경과 비교해보시면 됩니다!

대표적으로 VM과 비교할 수 있는데요.

VM은 레이어 구조가 아니기 때문에 새로운 VM을 만들기 위해서는 OS와 소프트웨어를 모두 설치해야 합니다.

VM에서도 파일의 상태를 압축해서 저장해두는 스냅샷이라는 개념이 있지만, 스냅샷도 마찬가지로 레이어 구조가 아니기 때문에 스냅샷으로 VM을 만든다는 것은 완전히 새로운 환경으로 복사해서 만드는 것과 동일합니다. 그래서 시간이 오래 걸리게 되는 것이죠.

 

반면에 이미지-컨테이너 구조는 읽기전용 레이어를 공유하기 때문에 컨테이너를 실행할 때마다 이미지를 복사하지 않아도 됩니다. 그래서 속도가 VM을 실행하는 속도보다 훨씬 빠르게 됩니다.😀물론 PART1에서 말씀드린 것처럼 커널도 공유하기 때문에 속도가 아주 크게 차이가 나는 것입니다!

 

잘 모르겠지만 추측을 해보자면 A이미지를 통해 컨테이너가 실행되어있다 가정하면 A이미지를 만들때 쓰는 레이어들이 컨테이너 실행되는 동안 어딘가에 저장되어있고 이후 B이미지를 통해 컨테이너를 만들때 A이미지에 공통된 레이어가 있다면 이부분은 이미 올라와 있는 것을 사용하면 되니 생성속도가 빨라진다 추측이 되는데 맞을까요..?

이해하신 부분이 대체적으로 맞습니다. 정확히 정의하자면,

A이미지를 통해 컨테이너를 실행한다 가정하면 A이미지를 '구성하는' 레이어들이 컨테이너가 '실행되기 전 부터' 다운로드 되어 어딘가에 저장되어 있고, 이후 B이미지를 '다운로드'받을 때 A이미지와 공통된 레이어가 있다면, 새로운 레이어만 다운받기 때문에 빠르게 다운받을 수 있습니다.

그리고 A컨테이너, B컨테이너를 실행할 때 이미 읽기전용 레이어인 이미지를 다운받은 상태이기 때문에, 컨테이너 레이어만 추가하면 되서 생성속도가 VM과 비교했을때 아주 빠르다.

라고 정리할 수 있겠습니다!

 

추가 질문에서, 애플리케이션이 필요한 상태는 크게 두 가지로 나눌 수 있습니다.

첫 번째로 사용자의 로그인 세션 정보처럼 일시적인 정보를 저장하거나, 데이터베이스에 저장하는 데이터라고 볼 수 있겠죠.

로그인 세션 정보는 일반적으로 Redis와 같은 캐시 서버에 저장하고, 애플리케이션이 사용하는 데이터는 데이터베이스에 저장합니다.

 

두 번째로 말씀해주신 환경 변수입니다. 보통 컨테이너에 환경 변수를 주입할 경우 ENV로 지정합니다. 환경변수는 OS에 저장되는 데이터이기 때문에, 애플리케이션에 크게 영향을 주지 않습니다 😀

그리고 아마 스케일 아웃을 말씀해주신 것 같습니다. 스케일 아웃의 경우 '동일한' 서버의 대수를 늘리는 행위를 말합니다. 동일하다는 것은 환경변수를 완전히 일치시켜야 합니다. 각 서버가 다른 환경변수를 가지게 되면 다른 기능을 수행하기 때문에 스케일아웃이라고 정의하기 어렵습니다!