도커 이미지란?

도커는 대부분의 소프트웨어를 "이미지" 라는 개념으로 만들 수 있다. "이미지"란, 어플리케이션 실행에 필요한 프로그램 본체+라이브러리+관련 미들웨어(필요한경우)+OS/네트워크 설정값 등을 모아서 하나의 객체로 만든 것이다.  파일시스템적으로 "이미지"는, 애플리케이션의 실행에 필요한 파일들이 저장된 디렉토리를 모은 것이다.

 

도커에서 이러한 이미지를 기반으로, 실행환경에서 움직이는 컨테이너를 만들게 된다. 하나의 이미지에 여러 어플리케이션을 합칠 수도 있지만, 도커의 기본 이념은 "한 컨테이너에 한 어플리케이션" 이다.

 

단순히 운영체제(CentOS, Ubuntu) 의 이미지가 있을수도 있고, mysql이나 apache 이미지가 있을수도 있고, wordpress 같은 이미지가 있을수도 있다.  이미지는 미들웨어, 운영체제, 3rd 소프트웨어, 상용 소프트웨어, 오픈소스 소프트웨어 모두 다 존재한다.


이미지 실행 : "컨테이너화"

이미지를 도커에서 실행하면, 그 이미지를 기반으로 컨테이너가 생성되고 가동된다.  이미지는 컨테이너의 베이스일 뿐이라 한 이미지로 여러 개의 컨테이너를 만들 수 있다. 실행된 컨테이너를 가지고 서비스를 띄우고 운영하는 것이다. 예를 들어, mysql 이미지와 httpd 이미지를 다운받은 후, mysql 이미지와 httpd 이미지를 각각 컨테이너로 만들어서 서로 연동하여 웹서비스를 만들 수 있다.

 

다른 가상화 기술로 서버 기능을 실행시키려면, os의 실행부터 시작하므로 느릴 수 밖에 없지만, 도커는 이미 움직이고 있는 os 상에서 프로세스를 실행시키는것과 거의 똑같은 속도로 빠르게 실행 가능하다.


생성된 컨테이너의 개념

컨테이너는 OS 파일시스템이 있지만 커널이 없다. 호스트OS(도커가 설치된 장비)의 커널을 공유한다. 따라서 가상머신보다 훨씬 가볍다. 이 컨테이너에는 프로세스가 있으며, 해당 프로세스는 컨테이너 내에 "격리되어 있다" 라고 표현된다. 즉 호스트OS와는 분리되어 있다는 것.


컨테이너 안에서 작동하는 프로세스를 하나의 그룹으로 관리하고, 그룹마다 각각 파일시스템이나 호스트명, 네트워크 등을 할당하고 있다. 그룹이 다르면 프로세스나 파일에 대한 액세스를 할 수 없다. 이러한 구조를 사용하여 컨테이너를 독립된 공간으로서 관리하고 있다. 이를 위해 linux 커널 기능인 namespace, cgroups 등의 기술이 사용된다.


호스트OS 입장에서는 컨테이너는 프로세스로 보이며, ps 명령으로 확인할 수 있다. 컨테이너는 호스트OS와 통신을 하며, 그 통신은 네트워크로 이루어진다.  단순하게 그룹으로 관리되는 것이므로, 컨테이너와 호스트OS는 별개가 아니다. 컨테이너 내부와 호스트OS에서 둘다 uname -r을 치면, 호스트와 동일한 커널이 나온다. 호스트와 컨테이너의 OS 종류,버전은 상관없다.

# 참고 : 호스트OS=Redhat / 컨테이너=Ubuntu 버전 비교
root@457b2eb299ee:/# cat /etc/lsb-release (컨테이너457b2eb299ee의 운영체제 정보 확인)
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
root@457b2eb299ee:/# uname -r (컨테이너457b2eb299ee의 커널버전 확인)
3.10.0-957.el7.x86_64
[root@CENTOS7-docker ~]# cat /etc/redhat-release (호스트OS의 운영체제 정보 확인)
CentOS Linux release 7.6.1810 (Core)
[root@CENTOS7-docker~]# uname -r (호스트OS의 커널버전 확인)
3.10.0-957.el7.x86_64 (동일하다)


도커의 이미지 데이터 저장/관리 방식 : CoW (Copy on Write)

데이터를 복사할 때 새로운 빈 영역을 확보하고 거기에 복사하는 것이 일반적인 방식이지만, 복사될 데이터에 변경이 없다면 굳이 복사를 해서 용량을 낭비할 필요가 없다. 그래서 복사를 요구받아도 바로 복사하지 않고, 원래 데이터를 그대로 참조시키고, 원본 또는 사본에 수정이 가해진 시점에 비로소 새로운 빈 영역을 확보하고 데이터를 복사하는 방식이 있다.

 

이것을 Copy on Write 방식이라고 하며, 도커에서는 이 방식을 사용하여 이미지를 저장하고 관리한다. 이미지의 여러 부분을 분할된 "레이어"를 합쳐 하나의 이미지로 만드는 개념이다. 예를 들어 apache 이미지는 아래 그림과 같이 여러개의 레이어로 이루어져 있다.

예시처럼, 이미지는 apache를 실행할 운영체제 이미지 레이어, 운영체제 업데이트 레이어, 아파치 프로그램 레이어, custom file 부분엔 아파치 값 설정이 레이어가 될 수도 있고, 또 추가적으로 레이어를 올릴 수도 있다. 그리고 마지막 부분은 read/write가 가능한 레이어로 마운트하여 사용자가 추가/수정을 할 수 있도록 하는 것이다. 각각의 이미지 레이어는 51136EA3C5A 같은 코드로 관리된다.

 

즉, 도커 이미지는 여러개의 레이어가 겹쳐저 있고, 구성 변경이 있으면 변경이 있는 부분도 레이어로 만들어서 관리하게 된다. 이 방법은 매우 혁신적이며 2가지 큰 장점을 가지고 있다. 

 

공간 활용.하나의 이미지 레이어를 여러 이미지에 사용할 수 있다. 즉, 우분투 베이스 이미지 레이어 부분을 위 예시의 apache가 아닌 elastic search 라는 프로그램 이미지에서도 우분투 베이스 이미지를 쓸 수 있으므로  한 이미지 레이어가 여러 이미지에 적용되는 것이다. 따라서 이미지의 사본을 만들지 않아 공간을 아주 많이 절약할 수 있다.

 

속도 향상 및 효과적인 자원 사용. 도커 이미지를 만들(build) 때,  raw 데이터를 가지고 빌드하는 게 아니라, 빌드할 내용 중 원래 만들어 놓은 이미지 레이어가 있다면 빌드하지 않고 그 레이어를 가져다 쓰므로 속도도 빠르고 자원도 사용하지 않는다.

 

이러한 방식을 쓰는 파일시스템을 Union Filesystem 이라고 하며, 여러가지 파일시스템 종류가 있다. AUFS, OverlayFS, loop-lvm, direct-lvm, zfs 등이 있다.

+ Recent posts