[Docker 기본3] 컨테이너는?

Docker는 애플리케이션의 배포와 운영을 쉽게 해주는 ‘CaaS(Containers as a Service) 플랫폼이며, 클라이언트-서버 모델로 동작하고 있습니다. 여기서 컨테이너 란, 접점의 분리가 아닌, 여러 개의 분리된 것들을 꺼내도록 할 수 있도록 서버하는 방식 입니다 . 이러한 존재들은 자신의 소유이고 있는 Host Machine과 사용자의 관점에서 보면, 실제 서버인 것처럼 보입니다.

뭐(Virtualization)

컨테이너의 방식은 일종의 종류입니다. 하지만 일반적으로 우리가 알고 있는 것은 가상화(Virtualization)라는 VMWare Workstation과 동일한 소프트웨어이며, Linux나 MacOS 위에 있는 Windows를 사용하는 것을 제외할 것입니다. 이러한 방식은 하드웨어와 소프트웨어를 결합하여 가상 머신(VM)을 만들어 사용하는 것, 플랫폼을 의미합니다. Platform에 있는 하드웨어 플랫폼에 포함되는 제어 프로그램, 즉 Host 소프트웨어를 통해 실행됩니다. Host 소프트웨어는 Host 환경을 개선하여 Guest 소프트웨어에 저항하는 가상 머신(VM)을 만들어냅니다. 게스트 소프트웨어는 완전한 작업(즉, 위의 예에서 Windows가 게스트 소프트웨어입니다)이며, 캐시된 하드웨어 플랫폼에 대해 간단히 실행됩니다.

가상기계(VM)의 전가상화

여기에 가상 머신(VM)은 하나의 서버를 여러 서버로 전환하는 순간 하드웨어의 추상화로 Hypervisor 1 기반의 시스템입니다. Hypervisor는 기반이 되는 시스템 내부에 또 다른 시스템을 구동할 수 있게 시스템의 각 요소를 배치하여 제공합니다. 이 때, 기반 시스템을 보통 호스트 시스템이라 하고 Hypervisor를 교체하는 것은 시스템을 가상의 시스템을 의미합니다. 하이퍼바이저는 호스트 시스템의 자원을 기반으로 가상 시스템이 이동으로 이동할 수 있도록 해줍니다. 따라서 Hypervisor를 사용하면 여러 대의 VM을 단일 시스템에서 실행할 수 있지만 호스트 시스템의 하드웨어는 제한됩니다.

출처: Docker Docs — 컨테이너 및 가상 머신

컨테이너의 반가상화

반면, 컨테이너는 공유된 파일에서 검색할 수 있는 형식으로 소프트웨어를 찾는 방법입니다. Hypervisor처럼 시스템의 장치를 돌리는 것이 아니라, 응용 프로그램을 구동할 수 있는 환경, CPU와 메모리 등을 두고 있고 있고 있는 대신에 필요한 호스트 시스템과 공용으로 사용하는 것입니다.

출처: Docker Docs — 컨테이너 및 가상 머신

VM VS 컨테이너

두 가지 방식의 차이점은 무엇을 의미하는가?

VM은 CPU, 메모리, 디스크는 물론이고 그 구동을 포함하여 전체를 포함하여 구분하여 운영됩니다. 각 VM에는 진동의 전체 번들, 하나 이상의 프로그램 응용 프로그램, 필수 바이너리 및 베어링 전체가 포함되어 있기 때문에 GB를 갖추고 있습니다. 반면, 컨테이너는 전체를 번들로 제공하지 않습니다. 단지, 소프트웨어가 부스에는 필요한 라이브러리 및 설정만 포함되기 때문에 VM보다 특별한 공간을 없애줍니다. 일반적으로 컨테이너를 생성하는 이미지의 크기는 MB정도입니다. 따라서 컨테이너는 VM보다 공간을 사용할 수 있고, 구별됩니다.

동작 방식도 다양합니다. 하이퍼바이저 기반의 가상 시스템에서 애플리케이션을 구동하고 해당 시스템이 완전히 실행된 후 애플리케이션이 작동합니다. 따라서, 실제 애플리케이션이 구동되기의 시간이 실험적으로 실행되기만 하면, 컨테이너는 이미 시스템이 동작하는 상태에서 애플리케이션 부품만 작동하기 때문에 속도가 훨씬 많이(거의 즉시 시작됩니다). 또한, 존재하는 시스템이 등을 동작시키기 위해 사용하는 것을 컨테이너에서 사용하고 있기 때문에, 더 많은 소비를 할 수 있는 VM에 맞서고 있습니다.

컨테이너의 경계

하지만, 컨테이너에도 점은 존재합니다. 기존 Hypervisor 기반의 기술보다 컨테이너가 반사 부분은 마치 좀처럼 속도가 빠른 배터리 효율에 적합하기 때문에 호스트 시스템에서 더 많은 애플리케이션을 기반으로 하는 동작을 수행할 수 있습니다. 하지만 Docker의 기반이 되는 컨테이너 기술은 애플리케이션의 안정적인 환경을 제공하기 때문에 호스트 시스템에서 제공하는 것과 동일한 환경에서 제공된다는 점이 있습니다. 즉, 일반 Docker 환경(Linux)에서 Windows 애플리케이션 실행은 현재로선 없는 것입니다. 컨테이너 기술 자체가 활동하고 실행하는 바이너리, 라이브러리를 공유함으로써 애플리케이션 자체의 실행 품질을 향상시켜 기술을 제공하는 상황이기 때문에 가능하지 않습니다.

컨테이너

지금까지, 컨테이너가 어떤 부분에 대해 살펴보았습니다. 컨테이너는 기술의 한 종류이며, 속도가 빠르고 소비력이 적다는 장점이 있다는 것을 알 수 있습니다. 그럼 이제 컨테이너가 어떻게 생성되는지, 동작하는지 확인하겠습니다.

이미지와 컨테이너의 레이어

먼저 컨테이너에 대해 살펴보기 전에, 컨테이너 실행의 주체가 되는 이미지에 대해 살펴보겠습니다.

이미지와 레이어

이미지는 Dockerfile이라는 Build 내부를 바탕으로 생성됩니다. 아래는 최신 버전(16.04 버전) Ubuntu Image의 Dockerfile입니다( Github: docker-brew-ubuntu-core/xenial/Dockerfile ).

Ubuntu의 Dockerfile은 다음의 포럼 구성으로 구성되어 있습니다.

  • 에서
  • 추가하다
  • 4개의 RUN
  • 명령

Dockerfile로 부터 Image가 구성될 때, Dockerfile의 개별의 Dev가 Layer로 구성됩니다. 만약 docker build [OPTIONS] PATH | URL | -위의 Dockerfile에서 Ubuntu를 이미지로 빌드할 때 사용한다면, FROM을 조각 6개 개별의 Layer로 구성합니다.

Image의 Layer가 실제로 Dockerfile의 컨퍼런스로 참여하는지 docker history [OPTIONS] IMAGE확인하겠습니다.

총 6개의 행을 드릴 수 있다면, CREATED BY열에서 해당 Layer가 어떤 협력으로 생성해드릴 수 있습니다. 이렇게 된 레이어를 생성할 수 없으며, 이미지 레이어는 수정할 수 없으므로, 그룹화할 수 있습니다.

컨테이너와 이미지

정글 읽기만 가능하며, 이미지 레이어의 최상단에 읽기/쓰기가 가능한 레이어가 추가되어 수 있고, 이것이 바로 컨테이너입니다. 새롭게 추가된 Layer는 Container Layer라 부탁드립니다. Container Layer에는 컨테이너 로그인 중 발생하는 모든 변경 사항들(파일 생성, 수정, 삭제 등)이 작성되고 저장됩니다. 아래는 현재 로컬 저장소에 실제로 Ubuntu의 Image Layer가 저장되어 있습니다.

그러면 Ubuntu Image에서 컨테이너를 로그인하겠습니다.

마찬가지로, Docker Machine에 직접 접속하여 Container Layer가 추가된 것을 해결할 수 있습니다.

컨테이너를 삭제하겠습니다.

이전에 생성된 컨테이너 레이어는 삭제되고, 이미지 레이어만 남아있는 것을 알 수 있습니다.

정리하면, 다음과 같습니다.

  • 이미지는 Layer의 Set으로 작업을 수행하고, 각각의 Layer는 Dockerfile의 TFT에 해당합니다.
  • 이미지 레이어는 읽기전용 레이어로 추가할 수 없습니다.
  • 컨테이너를 입력하면, 읽기/쓰기가 가능한 컨테이너 레이어가 이미지 레이어 세트의 최상단에 추가됩니다.
  • 컨테이너 입력 중 모든 작업을 수행하는 것은 컨테이너 계층에 있으며, 컨테이너가 삭제되면 해당 컨테이너 계층도 삭제됩니다(단, 이미지 레이어는 삭제되지 않습니다).

아래는 Image와 Container Layer를 도식화한 것입니다.

Docker Docs — 이미지 및 레이어

레이어의 공유

하나의 이미지로 여러 개의 컨테이너가 분리될 수 있고 어떻게 작동하는지 살펴보겠습니다. 먼저 Ubuntu Image로 부터 ubuntu-local-NUM 의 컨테이너를 의미합니다.

로컬 Docker에 실제로 컨테이너와 레이어가 보관되어 있습니다. 각 Container Layer가 추가되었지만 Image Layer는 추가되지 않았습니다.

기후변화 컨테이너의 대락젹인 크기는 docker ps -s으로 해결할 수 있습니다.

  • size : 각 Container의 Container Layer에서 사용하고 있는 데이터 양
  • 가상 크기 : Image Layer에서 사용하고 있는 데이터 양.

로컬 Docker의 파일 시스템에 저장된 실제 컨테이너 크기입니다.

지금까지의 과정에서 다음의 2가지 사실을 해결할 수 있습니다.

  • 같은 이미지를 기반으로 컨테이너가 들어갈 때, 컨테이너 레이어만 추가됩니다.
  • 대략적으로 보이는 컨테이너의 크기와 실제로 저장된 크기는 유사합니다. (docker ps -s로 기분각 컨테이너의 크기는 122MB로, 실제 파일 시스템에 저장된 컨테이너는 32.0K입니다.)

이것이 대체적으로 예외일 때, 동일한 이미지를 바탕으로 가져온 컨테이너는 각각의 컨테이너 레이어만 추가로, 이미지 레이어는 공유하여 사용한다는 사실을 알 수 있습니다(실제로 Docker는 같은 이미지에서 변환된 컨테이너는 이미지 레이어를 100) %공유하여 사용합니다). 또한, 컨테이너는 개별적으로 컨테이너 레이어를 보고 해당 레이어에 모든 변경된 내용이 저장되기 때문에, 여러 컨테이너가 동일한 기본 이미지를 공유하여 사용하면서 컨테이너 자신의 데이터 상태를 가질 수 있기 때문입니다. 이러한 경우로 인해 Docker 컨테이너는 더욱 가벼워지고 기어오는 속도를 낼 수 있는 것입니다.

이런 식으로 표현하면 다음과 같습니다.

Docker Docs — 이미지 및 레이어

Ubuntu Image를 통해, Image와 Container의 Layer 구조를 확인함으로써 Docker가 왜인지 빠르게 알 수 있습니다. 그렇다면, 그러므로 직접적으로 보이는 것은 그렇지 않습니다.

하이퍼바이저(hypervisor)는 호스트 컴퓨터에서 레슬링을 동시에 실행하기 위한 플랫폼을 말합니다. 머신 모니터(Virtual Machine Monitor, 외곽서 VMM)에 위치합니다.