Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

소개

베어메탈(bare metal), 가상 머신 기반의 가상화(Virtualization) 과 비교해서 컨테이너 기술을 설명한다. 이들 기술과 비교해서 컨테이너 기술이 가진 특징이 무엇인지, 어떤 장점때문에 컨테이너 기술을 사용하는지 그리고 어떤 단점을 가지고 있는지 살펴 본다.

베어메탈과 가상화

하드웨어를 다루는 엔지니어가 아닌 소프트웨어 개발자에게 베어메탈이란 다소 생소한 용어일 것이다. 베어메탈은 "운영체제가 설치 돼 있지 않는 컴퓨터 하드웨어"를 의미한다. "깡통 컴퓨터"라고 하면 이해하기가 쉬울 것이다.

이 베어메탈에 운영체제를 설치하면, 우리가 일반적으로 알고 있는 서버 컴퓨터, 컴퓨터 노드가 된다. 베어메탈이라는 용어는 보통 데이터센터(IDC)에서 많이 사용한다. 데이터센터에서 서버 컴퓨터는 랙단위로 구매해서 들어오는데, 랙 골격과 컴퓨터들이 모두 분리된채로 배달이 된다. 당연히 컴퓨터에는 운영체제가 설치돼 있지 않다. 공장에서 막 나온 상태라고 보면 되겠다. 이 상태를 구분하기 위해서 굳이 베어메탈이라는 용어를 사용한다. 이와 관련해서 베어메탈 프로비저닝(provisining)이라는 용어도 사용하는데, 깡통 하드웨어에 운영체제를 설치하고 네트워크를 설정해서 엄연한 컴퓨터로 작동하도록 하는 일련의 과정을 일컫는다. 상당한 노가다가 될 수 있기 때문에 chef등의 도구를 이용해서 자동화를 한다.

가상화란 가상의 베어메탈을 만드는 일련의 기술들을 의미한다. 베어메탈을 그냥 하드웨어라고 하면, 가상의 컴퓨터 하드웨어를 만드는 기술이라고 할 수 있겠다. 에뮬레이션(Emulation)과 매우 비슷한 개념이다. 오락실 게임을 PC에서 돌리기 위해서 노력했던 사람들이라면 익술할 MAME(Multiple Arcade Machine Emulator)가 대표적인 에뮬레이터다. MAME는 오락실 게임기계의 CPU, 비디오, 사운드등을 소프트웨어를 이용해서 가상으로 구현하고 롬파일을 실행하는 방식으로 일반 PC에서도 다른 기종의 게임을 실행 할 수 있도록 한다.

 MAME

가상화역시 가상의 하드웨어를 만들기는 하지만 순수하게 소프트웨어로 구성하는 에뮬레이션과는 달리 하드웨어에 직접 접근한다는 점이 다르다. 애뮬레이션은 보통 이기종의 하드웨어에서 작동하는 소프트웨어를 실행하는게 목적이지만, 가상화는 현재 사용 중인 하드웨어에서 구동 할 수 있는 소프트웨어를 실행하기 위해서 사용한다. 기본 하드웨어를 그대로 사용 하기 때문에 에뮬레이션 보다 더 빠르게 작동한다. 특히 최근의 하드웨어들은 아예 가상화지원을 내장하고 있기 때문에 더욱 효율적으로 작동한다.

가상화로 가상의 하드웨어를 만들 수 있으므로, 여기에 가상의 운영체제를 실행하는 것으로 하나의 컴퓨터 하드웨어에서 여러 개의 운영체제를 실행 할수 있을 것이다. 아래 그림은 가상화의 개념을 보여주고 있다.

 가상화의 개념

우리가 일반적으로 알고 있는 컴퓨터의 상태는 베어메탈에 하나의 운영체제(OS)가 올라가고 여기에 애플리케이션을 실행하는 방식이다. 가상화는 베어메탈에 하나 이상의 가상 머신(VM, Virtual Machine)을 만든다. 이 가상머신에 운영체제를 올리고 애플리케이션을 실행한다. x86 컴퓨터에서 가상머신을 만들었다면 이 가상머신은 x86을 에뮬레이션 한다. 따라서 x86에서 작동하는 어떠한 운영체제라도 설치 할 수 있다. 예컨데, 윈도우와 오픈솔라리스, 리눅스를 함께 운용하는게 가능하다.

리눅스에서의 가상화

물론 리눅스는 가상화를 지원한다. 지원하는 정도를 넘어서 가상화와 클라우드 시스템 구축을 위한 핵심 운용체제로 사용하고 있다. 가상화를 위해서는 하이퍼바이저(Hypervisor)이라고 하는 가상머신을 관리하는 별도의 소프트웨어가 필요하다. 리눅스에서 사용하는 하이퍼바이저로는 XEN, KVM이 유명하다.

Xen의 구성은 아래와 같다.

 Xen 구조

Xen 호스트가 시작되면 운영체제는 먼저 Xen 하이퍼바이저를 실행하고, Dom0라고 부르는 첫번째 게스트 운영체제를 실행한다. Dom0는 게스트 운영체제이기는 하지만 직접 하드웨어에 엑세스하며, 다른 게스트 운영체제를 관리하는 특수권한을 가지고 실행 된다. Dom0는 이런 특수한 권한을 이용해서 다른 게스트 운영체제에 가상 네트워크 디바이스와 가상 블럭 디바이스를 서비스 한다. Dom0의 관리하에 실행되는 게스트 운영체제들을 DomU라고 부른다. 우리가 흔히 말하는 가상머신이 DomU에 해당한다.

KVM은 Xen과는 다른 관점으로 접근 한다. 아래 그림을 보자.

 KVM 구성

KVM의 경우 하이퍼바이저가 커널 모듈 형태로 올라간다. 예컨데, 메모리 관리자나 파일 시스템과 같은 수준에서 운영체제의 일부분으로 다룬다. 이 방식은 많은 장점을 가진다. 일단 일반적인 리눅스 운영체제를 그대로 사용하기 때문에, 다양한 애플리케이션을 이용해서 손쉽게 VM 들을 제어 할 수 있다. 다만 KVM을 이용하기 위해서는 CPU가 하드웨어 차원의 가상화(HVM - Hardware Virtual Machine)를 제공해야 한다. Intel은 VT-x, AMD는 SVM 기술을 이용해서 하드웨어 가상화를 지원하고 있다. 최근의 X86 CPU들은 가상화 기능을 기본으로 지원하기 때문에, 그다지 단점이 되지는 않는다.

KVM을 보면 QEMU 디바이스가 올라가는데, QEMU는 하드웨어 애뮬레이션이다. 이처럼 하드웨어 자체를 가상화하기 때문에 전가상화라고 부른다. 이미 하드웨어를 가상화하기 때문에, (동일한 아키텍처의)모든 운영체제를 실행 할 수 있다.

가상화 타입

Type-1
네이티브 혹은 베어메탈 하이퍼바이저를 이용하는 가상화다. 하이퍼바이저가 하드웨어를 직접 제어하고 그 위에 게스트 운영체제(Guest OS)를 올리는 방식이다. 이런 이유로 베어 메탈 하이퍼바이저라고 부른다. Oracle VM Server for X86, Citrix Xenserver, Hyper-V, VMware ESX/ESXi 등이 Type-1 형태의 하이퍼바이저다.

 하이퍼바이저 타입

출처 : wikipedia Hypervisor
Type-2
전통적인 운영체제위에 하이퍼바이저를 실행하고, 이 하이퍼바이저 위에서 게스트 운영체제를 실행하는 방식이다. 하이퍼바이저를 실행하는 운영체제를 호스트 운영체제라고 부른다. 기존에 사용하던 운영체제 위에, 애플리케이션을 실행 하듯이 새로운 운영체제를 올릴 수 있다. 기존 운영체제에 익숙한 일반 사용자들이 주로 접하는 하이퍼바이저다. VMware Workstation, VMware Player, VirtualBox, QEMU등이 Type-2 하이퍼바이저다.

반면 Type-1과 Type-2의 구분이 명확하지 않은 하이퍼바이저도 있다. 예컨데, 리눅스 KVM이나 FreeBSD의 bhyve는 커널모듈로 구현된다. 커널 모듈은 하드웨어를 직접 관리하기 때문에 Type-1 하이퍼바이저로 분류 할 수 있다. 하지만 리눅스와 FreeBSD는 하이퍼바이저가 아닌 범용 운영체제며 가상머신과 다른 애플리케이션이 함께 운영된다. 이런 이유로 Type-2 하이퍼바이저로 분류 할 수도 있다.

가상화의 장점

가상화는 하나의 베어메탈을 여러 개의 컴퓨터로 보이게 해서 결과적으로 여러 개의 운영체제를 작동하게 하는게 목적이다. 이러한 목적을 구현한 이유는
  1. 여러 서버를 모아서 자원의 사용율을 개선하고
  2. 풀(pool) 개념을 사용 함으로서 자원에 대한 빠른 전개와 회수가 가능하다.
  3. 애플리케이션들을 완전히 격리 함으로써 멀티터넌트 환경을 구성
하기 위함이다.

가상화를 하게 되면, 보통 여러 개의 베이메탈을 풀(pool)로 묶어서 관리를 한다. 8core CPU, 128G 메모리를 가진 베어메탈 8개가 있다면, 이들을 하나로 묶어서 64 core CPU, 1Tera의 용량을 가진는 컴퓨팅 자원 풀을 만든다. 그리고 이 자원을 유저가 요청 할 때 할당을 한다. 따라서 컴퓨팅 자원을 꽉꽉채워서 효율적으로 사용 할 수 있다. 자원 풀을 구성하기 때문에, 자원의 할당과 회수도 용이해지는 장점이 있다. 또한 애플리케이션이 완전히 격리 되기 때문에 멀티너넌트 환경을 구성하기 쉬워진다.

결국
  1. 높은 집적도를 통해서 데이터센터의 공간을 줄이고
  2. 하드웨어의 가동률을 높일 수 있으며
  3. 전력을 아끼고
  4. 유저를 대상으로 빠르고 안전하게 컴퓨팅 자원을 제공
하는 시스템을 만들 수 있다.

가상화의 단점

완전한 운영체제가 올라가기 때문에, 대량의 메모리가 필요하다. 프로세스의 경우 전환이 매우 빠르고, 애플리케이션들이 대부분의 시간을 sleep상태로 있기 때문에, 여러 개의 VM들이 CPU를 경쟁해도 크게 문제가 되지 않는다. 하지만 메모리는 CPU 만큼 빠르게 전환 할 수가 없다. 따라서 CPU를 아끼는 만큼 메모리를 아낄 수는 없고, 상대적으로 대량의 메모리를 가지고 있어야 한다. 가상화를 할 때, 적정 메모리를 산정하는 것은 상당히 까다로운 문제가 될 수 있다.

그리고 운영체제 자체가 메모리를 많이 잡아 먹는다. 우분투 리눅스 서버를 올릴려고 하면, 운영체제를 유지하는 것만으로 500M 정도의 메모리가 소모도니다.

CPU 성능 확보도 문제다. CPU는 빠른 전환이 가능 하기 때문에 애플리케이션간 CPU 경쟁이 분산이 된다. 하지만 애플리케이션의 요청이 중첩되는 걸 피할 수는 없다. 애플리케이션의 CPU 요청이 중칩되면 애플리케이션의 응답시간이 늦어지는 문제가 생길 수 있다. 이런 이유로 가상화나 클라우드 서비스는 CPU 경쟁에 따른 성능저하가 있을 수 있다는 것을 명시 한다. 가상화/클라우드 서비스 업체에 따라서 일정한 응답시간의 보장이 중요한 서비스를 위한 유저를 위한 데디케이스(dedicate)서비스의 사용을 권고하기도 한다.

가상화라는 개념 자체가 이미 만들어진 시스템위에 또 다른 시스템을 구축하는 것이기 때문에, 운영체제와 네트워크, 스토리지, 보안, 운영, 모니터링에 대한 통합된 지식이 필요하다. 기존에는 시스템 운영과 소프트웨어 개발이 따로 떨어져 있었지만, 가상 환경에서는 이들이 통합돼야 한다. 따라서 효율적인 가상화(혹은 클라우드) 환경을 운용하기 위해서는 DevOps와 같은 새로운 조직 구성이 필요하다. 상당히 부담이 될 수 있다.

가상화에 사용되는 기술들

가상화는 물리적인 자원을 모아서, 하나의 논리적인 자원으로 만들고 이것을 나눠서 제공함으로써 자원 사용의 효율성을 높이기 위해서 사용한다. 이렇게 통합되는 자원으로 크게 컴퓨팅 자원(CPU, Memory), 네트워크, 스토리지가 있다. 이들 자원을 어떻게 가상화하고 통합하는지에 대해서 간단히 살펴보려고 한다.

다양한 가상화 솔류션이 있고, 같은 솔류션에서도 다양한 방법이 존재하기 때문에 이들을 모두 고려하면서 설명 할 수는 없다. 리눅스의 가상화 솔류션인 KVM으로 한정해서 설명한다. 서버측 가상화 솔류션의 주요 흐름은 KVM이므로 무난한 선택이 될 것이다.

 KVM 가상화

컴퓨터 시스템가상화

컴퓨팅 자원(CPU와 메모리)에 대한 가상화다. 컴퓨팅 자원은 결국 운영체제를 통해서 사용 할 수 있기 때문에, 운영체제 가상화라고 부르기도 한다. KVM에서의 운영체제 가상화는 그림으로 묘사했다.

 KVM에서의 가상화

리눅스 커널은 가성머신을 제어하기 위한 KVM 커널 모듈을 가지고 있다. QEMU는 하드웨어 애뮬레이터다. PC 하드웨어를 시뮬레이션 하는 거라고 보면 된다. 이 위에 게스트 운영체제가 올라간다. 아예 하드웨어를 애뮬레이션 하기 때문에, CPU 아키텍처만 일치한다면 다양한 리눅스, 윈도우즈, BSD, OpenSolaris, QNX, Minix 등 다양한 운영체제를 실행 할 수 있다. KVM Guest Support Status에서 KVM이 지원하는 운영체제를 확인 할 수 있다. 오픈소스 가상화 솔류션인 VirtualBox도 QEMU를 기반으로 하고 있다.

하드웨어가 준비 됐으니, 운영체제를 올려야 한다. 게스트 운영체제를 실행하기 위해서는 운영체제가 설치된 이미지 파일이 필요하다. 이 이미지 파일을 KVM Image라고 한다.

 kvm 이미지 파일

네트워크 가상화

가상화는 결국 여러 개의 컴퓨터를 띄우는 것이나 마찬가지다. 가상머신은 독립적인 하나의 컴퓨터로 역시 독립적인 네트워크 인터페이스(NIC)를 가지며, 이 인터페이스로 다른 가상 머신 혹은 인터넷과 통신 해야 한다. 아래 그림을 보자.

 네트워크 가상화

호스트 운영체제에 여러 개의 게스트 운영체제들이 실행 됐다. 이들 게스트 운영체제들이 서로 통신을 하려면 네트워크로 묶여야 한다. 물리적인 환경에서는 물리적인 네트워크 스위치로 서로 연결이 된다. 하지만 호스트 운영체제 내부에 물리적인 네트워크를 둘 수 없으니, 결국 이들을 연결하기 위한 가상의 네트워크를 구성해야 한다. 이때 사용하는 기술이 네트워크 가상화다.

리눅스 브릿지(Bridge), OpenVSwitch 같은 소프트웨어 스위치와 네트워크 네임스페이스(Network Namespace), Iptables, 가상 네트워크 인터페이스(veth - Virtual Ethernet device), OpenFlow, Proxy 들이 핵심 기술이다. 이 기술들을 이용해서 L2 네트워크, L2 Overlay Network, L3 Network 등 서비스 목적에 따른 다양한 네트워크를 구성하게 된다.

스토리지 가상화

가상화 환경에서 가상머신(컴퓨터)는 실체가 없는 소프트웨어로 물리적인 제약을 받지 않는다. 컴퓨터를 자유로이 이동 할 수 있다는 이야기다. 이렇게 하기 위해서는 데이터를 담고 있는 스토리지가 가상 머신과 분리돼야 한다. 아래 그림을 보자.

 스토리지 가상화

단순화 한 그림이지만 개념은 잡을 수 있을 것이다. 하드디스크를 호스트 운영체제가 아닌 전용 스토리지 노드에 둔다. 이렇게 하면 가상머신은 서버 노드 사이를 자유롭게 이동 할 수 있다. 그럼 이런 질문이 떠오를 것이다. 왜 가상머신이 자유롭게 이동할 수 있어야 하는가 ?

가상화의 가장 큰 목적은 자원을 효율적으로 사용하려는데 있다. 유저가 가상 머신을 요청하면, 자원이 남는 서버를 찾아서 가상 머신을 할당해야 한다. 가상 머신을 운영하다가 CPU나 메모리가 부족하게 됐다면, 다른 자원이 남는 서버 노드에서 가상머신을 실행해야 한다. 이렇게 하기 위해서는 가상머신이 자유롭게 떠다닐 수 있어야 한다. 이때 하드디스크까지 함께 옮겨야 한다고 생각해 보자. 애로사항이 꽃필 것이다.

디스크에 저장된 정보를 복구하기 힘들다는 것도 분리하려는 이유가 된다. CPU나 메모리는 문제가 생기면 교체하면 된다. 가상화 환경에서라면 다른 서버노드에 가상서버를 실행하는 것만으로 복구 할 수 있다. 하지만 디스크에 담겨있는 정보는 그렇지 않다. 백업과 복구 그리고 가용성이 매우 중요한 문제가 된다. 그래서 디스크 정보 관리에 특화된 서버 장비로 스토리지 환경을 구성한다.

스토리지를 물리적으로 분리를 하게 되면, 네트워크를 통해서 디스크를 읽고 쓸 수 있어야 한다. iSCSI, NFS, CIFS(SMB) 등의 기술을 사용한다. iSCSI는 블럭 디바이스를 NFS, CIFS는 파일 시스템을 제공하는 서비스다.

컨테이너

컨테이너에 대해서

앞서 가상화 기술은 자원을 효율적으로 사용하기 위함이라고 했다. 하지만 최종목적은 결국 애플리케이션을 실행해서 서비스를 제공하는 것이다. 가상화라는 것은 애플리케이션 서비스를 저렵한 비용으로 빠르고, 안정적으로 제공하기 위한 기반 환경(인프라 스트럭쳐)인 것이다.

애플리케이션을 실행하겠다는 건데, 애플리케이션 몇개를 실행하기 위해서 컴퓨터(비록 가상이긴 하지만)를 띄우는 건 엄청난 낭비다. 그냥 운영체제에서 애플리케이션을 실행하면 되지 않을까 ? 이를 위해서는 애플리케이션 격리와 관련한 문제를 해결 해야 한다.

가상 머신을은만드는 것 만으로 자연스럽게 격리된다. 독립적인 운영체제가 올라오고, 네트워크와 디스크 프로세스가 운영체제 안에서 완전히 격리되기 때문이다. 하지만 애플리케이션의 경우는 다르다. 운영체제에서 제공하는 네트워크와 디스크, CPU, 메모리를 모두 공유한다. 이는 보안 문제와 자원 활용의 문제를 야기 한다. 유저가 만든 애플리케이션과 애플리케이션이 사용하는 디스크, 네트워크를 완전히 격리 할 수 있어야 한다. 또한 CPU와 메모리에 대한 제한(Quota)을 설정 할 수도 있어야 한다.

컨테이너의 개념은 간단하다. 격리된 네트워크, CPU, 메모리, 디스크를 가진 공간을 만들고 이 공간에서 프로세스 실행해서 유저에게 서비스하겠다는 거다. 이 공간(컨테이너)는 여러개 만들 어서 유저에게 제공하는 것으로 멀티 터넌스 환경을 만들 수 있다. 아래 그림을 보자.

 컨테이너를 이용한 멀티터넌트

컨테이너를 만든다. 각 컨테이너는 CPU, 볼륨, Core, 네트워크 카드를 할당 할 수 있다. 이 컨테이너는 다른 컨테이너와 분리된다.

cgroup

대량의 프로세스를 운영해야 하는 구글입장에서 컨테이너는 매력적인 기술이다. 그래서 구글은 2006년 부터 process containers라는 이름으로 자원을 격리하기 위한 기능 개발을 시작한다. 그리고 2007년 cgroup(control group)으로 이름을 변경한다. 그리고 2008년 리눅스 커널 2.6.24의 메인 코드에 추가했다. Cgroup은 아래의 기능들을 제공한다.
  • Resource limiting - 프로세스 그룹이 사용할 메모리와 파일 시스템 캐시등에 대한 제한을 설정 할 수 있다.
  • Prioritization : 프로세스 그룹간 디스크 입출력과 CPU 이용에 대한 우선순위를 설정 할 수 있다.
  • Accounting : 프로세스 그룹의 자원 사용량을 측정 할 수 있다.
  • Control : 프로세스에 대한 checkpoint를 설정하고 리스타트 할 수 있다.

namespace

cgroup이 계속 발전되는 한편, 리눅스 커널은 네임스페이스 격리(namespace isolation)라는 기능을 추가한다. 리소스들을 서로 다른 네임스페이스 그룹으로 나눠서, 다른 네임스페이스에서 볼 수 없도록하는 기술이다. 예를 들어 PID 네임스페이스는 서로 다른 네임스페이스에서 독립된 PID를 관리 할 수 있도록 한다. 하나의 운영체제에서 여러개의 프로세스 tree를 운용할 수 있다는 의미다. 그밖에 아래 6개의 자원에 대한 네임스페이스 관리 기능을 제공한다.
  1. UTS 네임스페이스 : hostname 관리 공간
  2. IPC 네임스페이스 : IPC(Inter process communication)관리 공간
  3. PID 네임스페이스 : PID 즉 프로세스를 관리하는 공간
  4. MNT 네임스페이스 : 파일 시스템 마운트를 관리하는 공간
  5. NET 네임스페이스 : 네트워크를 자원을 관리하는 공간
  6. User 네임스페이스 : 리눅스 어카운트(User, Group)를 관리하는 공간
리눅스 프로세스들은 각 타입별로 네임스페이스에 포함될 수 있다. 네임스페이스에 대한 자세한 내용은 XX에서 다루도록 하겠다.

cgroup & namespace

cgroup과 네임스페이스를 서로 결합하면, 기존의 가상 머신과 비슷한 수준의 가상환경을 만들 수 있다. 즉
  • cgroup를 이용해서 자원의 사용량을 제한하고
  • 네임스페이스를 이용해서 특정 유저만 자원을 볼 수 있도록 제한
할 수 있다.

Storage

가상머신은 새로운 운영체제가 올라가므로, (흔히 하드디스크라고도 부르는) 블럭 디바이스를 제공해주면 된다. 하지만 컨테이너는 좀 다르다. 컨테이너는 근본적으로 프로세스의 실행이기 때문이다. 프로세스가 실행되는 과정을 보자.

 프로세스의 실행 과정

프로세스는 하나의 프로그램 이미지에서 시작한다. 프로세스의 데이터가 변경되더라도 원본 프로그램 이미지를 변경할 수 없다. 대신 설정파일등을 이용해서 원본 프로그램 이미지늬 변경 없이, 격리된 프로세스를 실행 할 수 있다. vim을 예로 들자면, 유저별로 .vimrc를 설정하는 것으로 전혀 다른 환경의 vim 프로세스를 실행 할 수 있다.

컨테이너의 실행 방식을 보자.

 컨테이너 실행 과정

프로그램과 각종 설정파일들을 가지고 있는 컨테이너 이미지로 부터, 컨테이너가 만들어진다. 컨테이너 이미지프로그램 이미지, 컨테이너는 프로세스에 대응이 된다. 프로그램과 마찬가지로 컨테이너 이미지는 변경 할 수가 없다. 누가 실행 하든지 간에 동일한 프로그램 환경을 보장해야 하기 때문이다. 컨테이너가 실행 되면, 원본인 컨테이너 이미지로 부터 변경되는 정보를 저장할 수 있어야 한다. 원본으로 부터 복사(Copy)를 하고 변경되는 정보를 쓰는 (Write)하는 저장 방식이 필요하다. 원본을 수정하지 않고 변경된 정보만 저장하는 것을 COW(Copy on Write)기법이라고 하는데, 컨테이너를 구현하기 위해서는 COW 파일 시스템이 반드시 필요하다.

XX장에서 AUFS, OverlayFS, ZFS와 같은 다양한 COW 파일 시스템에 대해서 살펴보도록 하겠다.

컨테이너의 장점과 단점

컨테이너의 장점이다.
  • 가상 머신의 경우 부팅 준비하는 것만 해도 상당한 시간이 걸리지만 컨테이너는 밀리세컨드 단위로 실행된다. 일반 프로세스를 실행하는 것과 차이가 없다. 가상머신 방식과 비교해서 가장 큰 장점이다.
  • 가상머신은 운영체제가 실행된다. 따라서 실행 자체만으로도 수백메가의 메모리를 소비한다. 가상환경에서 CPU와는 달리 메모리는 자원회수가 느리다. 상당히 많은 메모리를 소모할 수 밖에 없다. 컨테이너는 실행하기 전에는 자원을 소비하지 않는다.
  • 가상머신은 완전한 운영체제를 포함한다. 우분투 서버리눅스의 경우 설치만으로도 1G가 넘는 디스크 공간을 사용한다. 컨테이너는 이미지로 부터 Copy on write 방식으로 만들어진다. 그 자체로 디스크 공간을 점유하지 않는다. 1000개의 가상머신을 만든다고 가정해 보자. 가상머신을 띄우는데만 1테라의 공간이 필요하다. 반면 컨테이너는 디스크 공간을 거의 쓰지 않는다.
장점만 있는 건 아니다. 그런 기술은 없다.
  • 자원의 격리와 제한이 어렵다. cgroup와 네임스페이스와 같은 기술들이 발전 하고 있기는 하지만, 가상머신에 비해서는 부족한 점이 있다.
  • 스토리지 성능이 좋지 않다. 가상머신은 블럭 디바이스 위에 ext3, ext4를 이용해서 스토리지를 사용한다. 컨테이너는 AUFS, Device mapper, Overlay Filesystem등과 같은 유니온 파일 시스템(Union filesystem)을 사용하는데, ext4와 같은 파일 시스템 위에 올라가는 데다가 변경된 내용을 기록하고, 기록된 내용으로 부터 원본 데이터를 복원해야 하기 때문에 느릴 수 밖에 없다. 데이터의 읽기와 쓰기를 일반 파일 시스템으로 분리하거나 Btrfs나 ZFS 같은 COW파일 시스템을 이용하는 등으로 문제를 해결 할 수 있기는 하지만, 가상머신에 비해서 신경써야 할게 많다.
  • 네트워크 구성이 어렵다. 가상머신은 물리적인 컴퓨터 시스템과 차이가 없어서 네트워크 구성이 특별히 어렵지 않다. 그냥 가상머신 마다 IP 주소 붙여서 연결하면 된다. 하지만 컨테이너는 그렇게 하기 힘들다. 프로세스에 IP를 준다고 생각해 보라 이상하지 않은가 ? 게다가 컨테이너는 대량으로 만들 수 있기 때문에 IP 주소를 붙이는 것 자체가 낭비다. 호스트 운영체제 레벨에서 네트워크를 한번 더 추상화 해야 해서 가상머신 보다 네트워크 구성에 신경을 써야 할게 많다.
몇 가지 단점이 있기는 하지만, 장점이 워낙에 막강하기 때문에 가상화와 클라우드에서 널리 사용 될 것이다.

컨테이너의 활용

컨테이너는 하나의 컨테이너 이미지로 부터 만들어진다. 하나의 프로그램으로 부터 실행된 프로세스가 모두 동일한 실행 환경을 가지듯이, 이들도 모두 동일한 실행 환경을 가진다. 게다가 컨테이너는 프로그램의 실행에 필요한 라이브러리, 다른 프로그램들 까지를 포함하므로 완전히 동일한 개발 & 배포 환경을 구성 할 수 있다. 애플리케이션을 개발하고 배포 할 때, 외부 라이브러리 버전과 소프트웨어 버전을 관리하는게 얼마나 까다로운 일인지를 생각해 보자. 컨테이너는 이런 것 들에 신경 쓸 필요가 없다.

워드프레스 컨테이너를 배포 한다고 가정해 보자. 워드프레스 컨테이너는 대략 아래와 같이 구성될 것이다.

 워드프레스 컨테이너

워드프레스를 위한 APM 과 여러가지 라이브러리들(libz, libpng.. 기타등등)이 패키징 형태로 구성된다. 따라서 통일된 개발 및 배포 환경을 만들 수 있다. 물론 개발 & 배포 환경을 통일하려면 개발에서 테스트 배포까지의 과정이 체계적으로 작동되야 한다. 이와 관련된 내용은 DevOps장에서 자세히 다루겠다.

참고