IT 관련된 업무에 관련된 사람이라면 컨테이너에 대한 애기를 한번쯤은 들어봤을 것이다. 

하지만, VM이란 용어는 흔하게 많이 접해봤을 것이다. 
좀 더 깊숙하게 들여다보면 VM과 컨테이너를 비교한 자료들이 많이 있을 것이다.

이제 IT 흐름은 컨테이너 기반의 환경이 구성되어 있다. 

컨테이너 개념을 알고가 하기 전에 컨테이너가 진정으로 의미하는 바는 무엇이며 어떻게 작동하고 왜 중요한 것일까에 대한 생각부터 해야 할 필요가 있다. 

그럼 먼저, 컨테이너를 알기 위해서는 VM 개념을 알아야 한다.

그리고 VM 개념을 알기 위해서는 OS와 Kernel 개념을 알아야 한다.


따라서, OS와 커널에 대한 개념부터 짚고 넘어가도록 하겠다.

1. OS and Kernel

대부분의 컴퓨터 및 전자 장치들은 CPU, 보조(장기) 기억 장치(디스크 드라이브, SSD), 메모리, 네트워크 카드 등과 같은 하드웨어를 기반으로 만들어져 있다.

컴퓨터 내에서 어떤 정보를 공유하기 위해서는 이러한 하드웨어간 상호작용을 해야 한다. 이러한 상호 작용을 하기 위해서는 운영체제(OS) 안에 있는 커널(kernel)이라는 것이 하드웨어간 상호 작용을 할 수 있는 다리 역할을 수행한다. 뿐만 아니라, 커널은 실행될 프로세스(프로그램)의 스케쥴링을 담당하며, 장치들을 관리(디스크나 메모리의 특정 주소를 읽거나 쓰고)하는 등 많은 일들을 수행한다. 


컴퓨터 내부의 모습>


2. 가상 머신이란.

IT 개발자 및 운영자들은 현재의 사용하고 있는 컴퓨터에서 더 많은 일들을 하고 싶어한다. 
이유는 크게 2가지로 생각해 볼 수 있다. 
지금 사용하고 있는 컴퓨터에게 명령을 내렸는데, CPU 및 여러 하드웨어들은 명령을 모두 마친 후 쉬고 있는데, 업무를 수행하고 있는 프로세스가 계속해서 일하고 있기 때문이다. 즉, 소프트웨어가 하드웨어를 따라가지 못하고 있는 상황이다. 따라서, CPU를 비롯한 다양한 하드웨어들이 쉬지 말고 계속해서 일하도록 하기 위해 하나의 컴퓨터에 여러 개의 컴퓨터를 구성해서 CPU 및 하드웨어를 여러개로 나누어서 쉬지 못하고 계속해서 일하도록 하기 위해서이다. 

또 하나는, IT 환경이 변화하고 있는 상황에서 IT 개발자 및 운영자들은 다양한 환경에서 업무를 수행해야 하는 상황이 되고 있다. 그런데, 여러개의 컴퓨터를 마련하기에는 많은 비용이 소비될 뿐만 아니라, 여러대의 컴퓨터를 가지고 이동하는 것도 어려운 현실이다. 따라서, 한대의 컴퓨터에 여러 개의 컴퓨터를 만들수 있기를 희망하고 있다. 이러한 요구사항을 만족하기 위해서 여러 개의 가상화 환경을 만들고 각각의 가상화 환경에 CPU 등 하드웨어를 여러 개로 나누어서 사용할 수 있도록 한다. 이것이 가상 머신의 개념이다. 


2.2 가상 머신 구성
그럼 한 대의 컴퓨터에 여러 대의 컴퓨터를 만들기 위해서는 가상 머신 환경을 구성해야 한다. 

가상머신도 하나의 컴퓨터를 구성하기 위한 환경이다. 
따라서, 가상머신에도 컴퓨터를 운영할 수 있는 기본 운영체제가 있어야 한다. 일반적으로 이것을 게스트 운영체제라고 한다. 실질적으로 운영되는 메인 OS는 호스트 운영체제라고 한다.

그렇다면 게스트 운영체제를 만들어야 하고, CPU 및 하드웨어들도 몇 개로 분할해야 하는데, 이러한 작업을 수행하도록 돕는 것이 하이퍼바이저(hypervisor)라고 하는 것이 수행한다. 





하이퍼바이저는 호스트 OS 위에서 동작하거나, bare metal 방식처럼 머신 하드웨어 위에서 직접적으로 동작하는 (기존 OS를 대체하는) 것입니다 . 어떤 방식이든, 하이퍼바이저를 사용한 접근법은 다수의 파트에 대한 가상화를 필요로 하기 때문에 무겁다고 여겨진다.

같은 머신에 다수의 독립적인 그룹을 구성할 필요성이 있을 때, 각각의 그룹에 대해 가상머신을 작동시키는 것은 좋은 접근법이라기엔 너무 무겁고 리소스를 낭비하게 된다.


추후에 말하겠지만, 컨테이너 방식과 비교해 볼때 
가상머신은 머신 수준의 분리를 위해 하드웨어 가상화가 필요한 반면 컨테이너는 동일한 운영체제 내의 독립된 공간에서 실행된다. 독립된 공간의 수가 증가할 수록 오버헤드의 차이가 더 명확해진다. 
예를 들면, 노트북으로 수십개의 컨테이너를 실행시킬 수 있는 반면에 
가상머신의 경우는 단 하나의 가상머신도 버거울 수 있다.


3. 발전 동향

2006년, 구글의 엔지니어들은 Linux “control groups”라는 것을 발명하였고 이를 줄여 cgroups이라 하는데, cgroups는 유저 프로세스의 리소스 사용을 분리하여 관리하는 Linux 커널의 기능을 애기한다. 

리소스 관리를 위해 프로세스의 집합인 네임스페이스(namespace)에 집어 넣을 수 있는데, 하나의 컴퓨터는 다수의 네임스페이스를 가질 수 있고, 각각은 커널에 의해 제한을 갖게 된다. 

즉, 네임스페이스 별로 CPU, RAM 등의 리소스 양을 할당받는 되는데, 이러한 이유는 프로세스가 서버를 점유하지 못하도록 제한을 두기 위한 것이다. 

Linux의 cgroups 이라는 커널 기능에서의 네임스페이스 분리 자체는 프로세스 분리(process isolation) 개념을 가지고 공유 메모리와 같은 일들을 방지한다. 

또한, 프로세스들이 독립적일수 있도록 보장해주는 기능을 가진다.

이러한 개념에서 보여지듯이 네임스페이스 내부의 프로세스는 각각의 고유한 머신으로 보여질 수 있으며, 컨테이너의 시발점이 된다고 볼 수 있다. 

Linux cgroups는 LXC (linux container)라는 기술의 기반이 되었다고 한다. 

LXC는 오늘날 컨테이너라고 불리는 것의 가장 첫 번째 구현이라고 할 수 있다.  

따라서, 여러가지로 혼합해 보면, 리눅스 기반의 cgroups와 네임스페이스 분리 기능을 사용하여 별개의 프로세스와 네트워킹 스페이스를 가진 가상 환경을 만들어내게 되었고,

이러한 기술 기반의 LXC는 독립적이고 격리된 유저 스페이스를 어느 정도 가능하게 했다.

LXC 기본 개념이 컨테이너가 되엇으며, 초기의 Docker는 LXC을 기반으로 하여 만들어졌다.

따라서, Docker는 가장 널리 사용되는 컨테이너 기술이고, 

사람들이 컨테이너라고 하면 대부분 Docker를 가르키는 이유이기도 하다.


Docker

Docker는 가장 널리 사용되는 컨테이너 기술이고, 사람들이 컨테이너라고 하면 대부분 Docker를 가르킨다. 그 이유는 Docker는 여전히 cgroups와 Linux 커널, 최근 Windows에서 제공되는 네임스페이스 기술을 기반으로 하고 있으며, Docker는 컨테이너화(containerization)의 산업 표준이 되었기 때문이기도 하다. 물론 다른 오픈소스 컨테이너 기술들(CoreOS의 rkt 등)과 직접 컨테이너 엔진을 만드는 거대 기업들(Google의 lmctfy 등)도 존재한다. 

Docker 컨테이너는 여러 image(이미지, 하나의 패키지로 묶인 바이너리)들의 레이어로 이루어져 있다. base image는 컨테이너의 운영체제를 포함하고 있고, 이 OS는 호스트의 OS와 다를 수 있다.


이 base image 위에 각각의 컨테이너 부분이 되는 다수의 이미지들이 올라가는데, 예를 들어, apt-get 의존성을 포함하는 이미지가 base image 위에 올라갈 수 있게 된다. 그 위에는 어플리케이션 바이너리 등을 포함하는 이미지가 올라갈 수 있다.

예를 들면, 두 컨테이너가 각각 레이어 a, b, c와 레이어 a, b, d로 되어 있다면 각 레이어 a, b, c, d의 하나의 복사본만을 local과 repository에 보관하면 된다. 이것이 바로 Docker의 유니온 파일 시스템(union file system)이다. 

해시로 식별되는 각 이미지는 컨테이너를 구성하는 많은 가용 레이어 이미지들 중 하나입니다. 하지만 컨테이어너는 최상위 이미지로 식별되며, 부모 이미지에 대한 참조를 가집니다. 위 그림에서 두 최상위 이미지(image 1과 image 2)는 첫 3개의 레이어를 공유하고 있습니다. image 2는 구성과 관련된 2개의 레이어를 부가 적으로 가지지만, image 1과 같은 부모 이미지를 공유하고 있습니다.

컨테이너가 부팅되면, 해당 이미지와 부모 이미지들이 저장소로부터 다운로드되고, cgorup과 네임스페이스가 만들어지며, 이미지를 사용하여 가상 환경을 생성한다. 컨테이너 내에서는, 이미지에 명시된 파일과 바이너리들은 전체 머신에서의 유일한 파일들로 나타내어 진다. 이후 컨테이너의 메인 프로세스가 실행되고 컨테이너는 alive 상태가 된다.


Docker는 copy on write, volume(컨테이너 사이에서 공유되는 파일 시스템), docker daemon(머신의 컨테이너들을 관리), 버전 관리 저장소(컨테이너를 위한 Github) 등의 기능들을 가지고 있다. 

Docker를 사용하는 실용적인 예제 관련 내용이다.

①②클라이언트는 도커 데몬이라고 불리는 프로세스에 무엇을 해야할지 알려주고, 

③이 데몬은 registry 또는 repository로부터 이미지를 가져오고

④ 이러한 이미지들은 로컬 머신에 캐시되고

⑤ 데몬에 의해서 부팅되어 컨테이너를 실행합니다


Why Containers

프로세스 분리 이외에, 컨테이너는 다른 많은 이점이 있다.

컨테이너는 스스로 독립된 유닛으로서 해당 컨테이너를 지원하는 어느 곳에서든 실행될 수 있다. 즉, 호스트 OS가 CentOS이던 Ubuntu이던 MacOS이건 심지어 Windows와 같은 UNIX 기반 OS인지 상관없으며, 컨테이너가 지정한 OS가 된다. 

또한 컨테이너는 표준화된 작업 또는 연산의 유닛 역할을 하는데, 

각 컨테이너가 하나의 웹서버, 하나의 데이터베이스 등으로 구성하게 할 수 있는데, 이렇게 하는 경우, 어플리케이션의 규모를 키우기(scale) 위해서는, 단순히 컨테이너의 수를 늘리기만 하면 된다. 

즉, 각 컨테이너에게는 일정한 리소스 설정(CPU, RAM, 스레드의 수 등)이 주어지고, 어플리케이션의 규모를 증가시키기 위해서는 개별적인 컨테이너의 리소스 설정을 변경하는 대신 단지 컨테이너의 수를 증가시키면 된다. 이는 엔지니어가 어플리케이션의 규모를 증가시키거나 축소시켜야 할 때, 훨씬 쉽게 기능을 제공하는 것과 같다.

이러한 조합법에 기반하여 컨테이너들을 마이크로 서비스 아키텍처를 구현하기 위한 훌륭한 도구로 사용할 수 있게 되는데, 예를 들어 Redis 마이크로 서비스는 하나의 마스터 컨테이너와 다수의 슬레이브 컨테이너를 사용하여 구현할 수 있다.

이러한 (마이크로) 서비스 지향적 아키텍처는 엔지니어링 팀이 어플리케이션을 개발하고 배포하는 것을 쉽게 해주는 많은 중요한 성질들을 가지고 있다.


Orchestration

Linux 컨테이너의 사용자들은 각 컨테이너에서 프로세스가 실행되는 여러 개의 가상 머신에 걸쳐 규모가 큰 어플리케이션을 배포하고자 하는 경우, 

이를 위해서 수만개의 컨테이너를 수백개의 가상 머신에 걸쳐 효과적으로 배포할 수 있어야 했고, 이 사이의 네트워킹, 파일 시스템, 리소스 등을 효과적으로 관리할 수 있어야 했다. 

오늘날의 Docker는 컨테이너 네트워킹, volume을 위한 파일 시스템, 리소스 설정 등을 정의하는 추상화를 통해서 이를 더욱 쉽게 할 수 있도록 하였다.

하지만 다음과 같은 것들을 위해 Docker 이외의 툴이 여전히 필요하다.

  • 실제로 명세(specification)을 받아들이고 컨테이너를 머신에 할당 (스케쥴링)
  • 실제로 docker를 통해 지정된 컨테이너를 해당 머신에서 실행
  • 업그레이드, 롤백, 끊임없이 변경되는 시스템의 성질에 대한 처리
  • 컨테이너 크래시와 같은 고장에 대한 대응
  • 서비스 디스커버리, VM 간 네트워킹, 클러스터에 대한 추가(ingress), 제거(egress) 등의 클러스터 리소스 생성

이들은 (일시적일 수도 있고 또는 끊임없이 변화할 수도 있는) 컨테이너들의 집합 위에 만들어진 분산 시스템의 오케스트레이션(orchestration)과 관련이 있는 문제들이고, 사람들은 이 문제들을 해결하기 위해서 정말 대단한 시스템을 구축

출처 : https://goofcode.github.io/container-101


'정보관리기술사 도전 > 용어 정의' 카테고리의 다른 글

REST(Representational State Transfer - 작업 중  (0) 2019.02.22
VM vs container  (0) 2019.02.22
이클립스(Eclipse)  (0) 2019.02.19
Maven-> working  (0) 2019.02.19
스위프트(Swift)  (0) 2019.02.15

+ Recent posts