본문 바로가기
프로그래밍 놀이터/Settings

[Docker] 컨테이너 기술과 Docker 의 개요

by 돼지왕왕돼지 2020. 3. 20.

[Docker] 컨테이너 기술과 Docker 의 개요


-

Docker 는 컨테이너 기술을 사용하여 앱의 실행 환경을 구축 및 운용하기 위한 플랫폼이다.

앱 실행에 필요한 것을 하나로 모아,  docker  이미지를 관리함으로써 앱의 이식성을 높일 수 있다.





2.1. 컨테이너 기술의 개요


* 컨테이너


-

컨테이너란 호스트 OS 상에 논리적인 구획(컨테이너)를 만들고, 앱을 작동시키기 위해 필요한 라이브러리나 앱 등을 하나로 모아, 마치 별도의 서버인 것처럼 사용할 수 있게 만든 것이다.

호스트 OS 의 리소스를 논리적으로 분산시키고, 여러 개의 컨테이너가 공유하여 사용한다.

컨테이너는 오버헤드가 적기 때문에 가볍고 고속으로 작동한다는 것이 특징이다.



-

보통 물리 서버 상에 설치한 호스트 OS 의 경우 하나의 OS 상에서 움직이는 여러 앱이 똑같은 시스템 리소스를 사용한다.

여러 앱은 데이터를 저장하는 디렉터리를 공유하고, 서버에 설정된 동일한 IP 주소로 통신한다

그래서 미들웨어나 라이브러리의 버전이 다른 경우 각 앱이 서로 영향을 받지 않도록 주의해야 한다.


이에 반해 컨테이너 기술을 사용하면 OS 나 디렉터리, IP 주소 등과 같은 시스템 자원을 마치 각 앱이 점유하고 있는 것처럼 보이게 할 수 있다.



-

컨테이너는 앱의 실행에 필요한 모듈을 컨테이너로 모을 수 있기 때문에 여러 개의 컨테이너를 조합하여 하나의 앱을 구축하는 마이크로 서비스형 앱과 친화성이 높은 것이 특징이다.



-

호스트형 서버 가상화

    하드웨어 상에 베이스가 되는 호스트 OS 를 설치하고, 호스트 OS 에 가상화 소프트웨어를 설치한 후, 이 가상화 소프트웨어 상에서 게스트 OS 를 작동시키는 기술을 말한다.

    Oracle VM VirtualBox, VMWare VMWare Workstation Player 등이 있다.

    이 방식은 컨테이너와는 다르게 호스트 OS 상에서 다른 게스트 OS 를 움직이고 있기 때문에 오버헤드가 커진다.



-

하이퍼바이저형 서버 가상화

    하드웨어 상에 가상화를 전문으로 수행하는 소프트웨어인 하이퍼바이저를 배치하고, 하드웨어와 가상환경을 제어한다.

    Hyper-V 나 XenServer 등이 있다.

    호스트 OS 없이 하드웨어를 직접 제어하기 때문에 자원을 효율적으로 사용할 수 있다.

    단, 가상 환경마다 별도의 OS 가 동작하므로 가상 환경의 시작에 걸리는 오버헤드가 커진다.

    하이퍼바이저형은 펌웨어로서 구축하는 경우가 많다.




* 컨테이너 역사


-

FreeBSD Jail

    프로세스의 구획화 : Jail 에서 작동하는 프로세스만 액세스할 수 있도록 프로세스를 분리한다. Jail 안에서 실행중인 프로세스는 Jail 밖의 프로세스에 대해 영향을 줄 수 없다.    

    네트워크의 구획화 : Jail 은 하나 하나에 IP 주소가 할당되어 있다. 여러 개의 주소를 할당할 수도 있다. Jail 의 외부에는 네트워크를 경유해야 액세스 할 수 있다.

    파일 시스템의 구획화



-

Solaris Containers

    Solaris 존 기능 : 하나의 OS 공간을 가상으로 분할하여 여러 OS 가 작동하고 있는 것처럼 보여주는 소프트웨어 파티셔닝 기능이다. 한 대의 물리 서버 안에 최대 8192개의 가상 Solaris 환경을 구축할 수 있다. 베이스가 되는 OS 영역을 글로벌 존(global zone), 구획화된 가상 존을 비 글로벌 존(non-global zone)이라고 한다.

    Solaris 리소스 매니저 기능 : 비 글로벌 존에서 CPU 나 메모리와 같은 하드웨어 리소스를 배분하는 리소스 관리 기능. Docker 와 구조가 매우 비슷하다.



-

Linux Containers (LXC)

    Linux 상에서 사용하는 컨테이너 환경을 말한다. 툴이나 API 등을 제공한다.

    namespace 와 cgroups 라는 리소스 관리 장치를 사용하여 분리된 환경을 만든다.

    또한 데이터 영역에 대해서는 특정 디렉토리를 루트 디렉토리로 변경하는 chroot 를 사용하여 분리 환경을 만든다.

    Docker 는 이전 버전에서는 내부에서 LXC 를 사용했지만 현재는 사용하지 않는다.





2.2. Docker 의 개요


-

Docker 는 앱 실행에 필요한 환경을 하나의 이미지로 모아두고, 그 이미지를 사용하여 다양한 환경에서 앱 실행 환경을 구축 및 운용하기 위한 오픈 소스 플랫폼이다.




* 프로그래머에게 Docker 란?


-

개발 환경이나 테스트 환경에서는 올바르게 작동해도 스테이징 환경에서나 제품 환경으로 전개하면 정상적으로 작동하지 않는 경우도 있다.

스테이징 환경이란 지속적 딜리버리가 일어나는 시스템 개발에서 개발한 앱을 제품 환경에 전개하기 직전에 확인하는 테스트 환경이다.

Docker 에서는 이런 인프라 환경을 컨테이너로 관리한다.

앱의 실행에 필요한 모든 파일 및 디렉토리들을 컨테이너로서 모아버리는 것이다.

이런 컨테이너의 바탕이 되는 Docker 이미지를 Docker Hub 와 같은 리포지토리(repository)에서 공유한다.



-

프로그래머는 Docker 를 사용하여 개발 앱의 실행에 필요한 모든 것이 포함되어 있는 Docker 이미지를 작성한다.

이 이미지는 컨테이너의 바탕이 된다.

그리고 이렇게 작성한 이미지를 바탕으로 컨테이너를 가동시킨다.

이 이미지는 Docker 가 설치되어 있는 환경이라면 기본적으로 어디서든지 작동되므로 개발/테스트 환경에서는 정상 동작하지만 제품 환경에서는 정상 동작하지 않는다는 리스크를 줄일 수 있다.



-

앱의 이식성(portability)

    한 번 만들면 어디서든 움직이는 소프트웨어의 특싱을 이식성이라고 한다.

    Docker 는 이식성이 좋기 때문에 클라우드 시스템과의 친화력도 높다.








2.3. Docker 의 기능


-

다음 기능들이 있다.

    Docker 이미지를 만드는 기능(Build)

    Docker 이미지를 공유하는 기능(Ship)

    Docker 컨테이너를 동작시키는 기능(Run)




* Docker 이미지를 만드는 기능(Build)


-

Docker 는 앱의 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어, OS나 네트워크 설정 등을 하나로 모아서 Docker 이미지를 만든다.

Docker 이미지는 실행 환경에서 움직이는 컨테이너의 바탕이 된다.



-

Docker 에서는 하나의 이미지에는 하나의 앱만 넣어 두고, 여러 개의 컨테이너를 조합하여 서비스를 구축한다는 방법을 권장하고 있다.



-

Docker 이미지의 정체는 앱의 실행에 필요한 파일들이 저장된 디렉토리이다.

Docker 명령을 사용하면 이미지를 tar 파일로 출력할 수 있다.

Docker 이미지는 Docker 명령을 사용하여 수동으로 만들 수도 있고, Dockerfile 이라는 설정 파일을 만들어 그것을 바탕으로 자동으로 이미지를 만들 수도 있다.



-

Docker 이미지는 겹쳐서 사용할 수 있다.

예를 들어 OS 용 이미지에 웹 앱용 이미지를 겹쳐서(얹어서) 새로운 이미지를 만들 수 있다.

Docker 에서는 구성에 변경이 있었던 부분을 차분(이미지 레이어)로 관리한다.

또한 앱 실행에 필요한 파일은 크기가 큰 경우도 있으므로 가능한 한 효율이 좋은 이미지를 만들 필요가 있다.




* Docker 이미지를 공유하는 기능(Ship)


-

 Docker 레지스트리에서 공유할 수 있다.

예를 들어 Docker 공식 레지스트리인 Docker Hub 에서는 Ubuntu 나 CentOS 같은 Linux 배포판의 기본 기능을 제공하는 베이스 이미지를 배포하고 있다.

이러한 베이스 이미지에 미들웨어나 라이브러리, 전개할 앱 등을 넣은 이미지를 겹쳐서 독자적인 Docker 이미지를 만들어 가는 것이다.



-

Docker 명령을 사용하여 Docker Hub 에 로그인하여 레지스트리에 있는 이미지를 검색이나 업로드, 다운로드 할 수 있다.



-

Docker Hub 는 GitHub 나 Bitbucket 과 연계할 수도 있다.

예를 들어 GitHub 상에서 Dockerfile 을 관리하고, 거기서 Docker 이미지를 자동으로 생성하여 Docker Hub 에 공유하는 것도 가능하다.

이러한 자동 생성 기능을 Automated Build 라고 한다.



-

Docker 이미지의 변조 방지 및 취약성 검사 기능

    Docker Container Trust 는 Docker 이미지의 제공자를 검증하는 기능이다.

    이미지의 제공자는 Docker 레지스트리에 이미지를 송신하기 전에 로컬 환경에서 비밀키를 사용하여 이미지에 서명을 한다.

    그 후 그 이미지를 이용할 때는 이미지 제공자의 공개키를 사용하여 실행하려고 하는 이미지가 정말 제공자가 작성한 것인지를 확인한다.

    만일 이미지가 변조된 경우 이미지를 무효로 만든다.

    또한 Docker Security Scanning 은 Docker 이미지를 검사하여 이미 알려진 보안상의 취약성이 없다는 것을 확인해준다.




* Docker 컨테이너를 작동시키는 기능(Run)


-

Docker 는 Linux 상에서 컨테이너 단위로 서버 기능을 작동시킨다.

이 컨테이너의 바탕이 되는 것이 Docker 의 이미지이다.

Docker 이미지가 있고, Docker 가 설치된 환경이라면 어디서든 컨테이너를 작동시킬 수 있다.

또한 Docker 이미지를 가지고 여러 개의 컨테이너를 가동시킬 수도 있다.

컨테이너의 기동, 정지, 파기는 Docker 명령을 사용한다.

다른 가상화 기술로 서버 기능을 실행시키려면 OS 의 실행부터 시작하기 때문에 시간이 걸리지만, Docker 의 경우는 이미 움직이고 있는 OS 상에서 프로세스를 실행시키는 것과 거의 똑같은 속도로 빨리 실행시킬 수 있다.



-

Docker 는 하나의 Linux 커널을 여러 개의 컨테이너에서 공유하고 있다.

컨테이너 안에서 작동하는 프로세스를 하나의 그룹으로 관리하고, 그룹마다 각각 파일 시스템이나 호스트명, 네트워크 등을 할당하고 있다.

그룹이 다르면 프로세스나 파일에 대한 액세스를 할 수 없다.

이러한 구조를 사용하여 컨테이너를 독립된 공간으로 관리하고 있다.

이를 실행하기 위해 Linux 커널 기능인 namespace, cgroups 등의 기술을 사용한다.



-

제품 환경에서는 모든 Docker 컨테이너를 한 대의 호스트 머신에서 작동시키는 일은 드물며, 시스템의 트래픽 증감이나 가용성 요건, 신뢰도 요건 등을 고려한 후에 여러 대의 호스트 머신으로 된 분산 환경을 구축한다.

그리고 보통 컨테이너 관리에 대해서는 오케스트레이션 툴을 이용하는 것이 일반적이다.

컨테이너 오케스트레이션 툴은 분산 환경에서 컨테이너를 가동시키기 위해 필요한 기능을 제공하고 있다.




* Docker 에디션


-

Docker Community Edition (CE)

    무료 Docker 에디션이다.

    로컬 환경에서 사용하는 경우 및 상용 지원이 불필요한 환경에서 앱 실행 환경을 이용할 때 적합하다.



-

Docker Enterprise Edition (EE)

    Docker 사가 지원하고 상용 이용에 적합한 에디션이다.

    Basic, Standard, Advanced 3 종류가 있다.

    Basic 은 Docker 사의 지원 및 Docker Store 에서 인증이 끝난 컨테이너, 인증이 완료된 플러그인을 제공한다.

    Standard 는  Basic 의 내용에 더해, LDAP 나 Active Directory 와 통합 가능한 Docker Datacenter 를 이용할 수 있다.

    Advanced 에서는 보안 기능을 제공한다.



-

지원 플랫폼(Docker CE 기준)

    서버 OS 용 : Ubuntu, Debian, CentOS, Fedora

    퍼블릭 클라우드용 : MS Azure, Amazon Web Services

    클라이언트 OS용 : MS Windows 10, macOS



-

IoT 디바이스와 같은 ARM 아키텍처에서 작동하는 디바이스의 경우는 Docker Community Edition(ARM)을 이용할 수 있다.

Ubuntu 와  Debian 을 지원한다.



-

Docker 의 버전 번호는 연도 2자리, 월 2자리로 표시된다.

17.03 은 2017년 3월에 릴리스된 버전이다.



-

Moby Project

    컨테이너 기술을 베이스로 한 컴포넌트를 조합하여 시스템을 구축할 수 있다는 것을 지향하는 오픈소스 프로젝트이다.

    다양한 컴포넌트가 제공되며, Docker 는 Moby Project 에서 개발이 진행되고 있는 툴 중 하나이다.




* Docker 컴포넌트


-

Docker Engine(Docker 의 핵심 기능)

    이미지를 생성하고 컨테이너를 가동시키기 위한 Docker 의 핵심 기능

    Docker 명령의 실행이나, Dockerfile 에 의한 이미지도 생성한다.



-

Docker Registry(이미지 공개 및 공유)



-

Docker Compose(컨테이너 일원 관리)

    여러 개의 컨테이너 구성 정보를 코드로 정의하고, 명령을 실행함으로써 앱의 실행환경을 구성하는 컨테이너들을 일원 관리하기 위한 툴



-

Docker Machine(Docker 실행 환경 구축)

    VirtualBox 를 비롯하여 Amazone Web Service EC2 나 MS Azure 와 같은 클라우드 환경에 Docker 의 실행 환경을 명령으로 자동 생성하기 위한 툴



-

Docker Swarm(클러스터 관리)

    Docker 호스트를 클러스터화하기 위한 툴.



-

Docker 를 클라이언트 OS 에서 사용하려면 Docker for Mac, Docker for Windows 를 설치한다.

그 외 환경에서는 Docker Toolbox 를 이용할 수 있다.








2.4. Docker 의 작동 구조


-

Linux 커널의 기술이 베이스로 되어 있다.




* 컨테이너를 구획화하는 장치(namespace)


-

컨테이너를 구획하는 기술은 Linux 커널의 namespace 라는 기능을 사용한다.

namespace 란 한 덩어리의 데이터에 이름을 붙여 분할함으로써 충돌 가능성을 줄이고, 쉽게 참조할 수 있게 하는 개념이다.

namespace 가 다르면 동일한 이름이라도 다른 실체로 처리된다.



-

PID namespace

    namespace 가 다른 프로세스끼리는 서로 액세스 할 수 없다.



-

Network namespace

    네트워크 디바이스, IP 주소, 포트 번호, 라우팅 테이블, 필터링 테이블 등과 같은 네트워크 리소스를 격리된 namespace 마다 독립적으로 가질 수 있다.



-

UID namespace

    UID 와 GID 를 namespace 별로 독립적으로 가질 수 있다.

    namespace 안에서는 UID/GID 가 0인 root 사용자를, 호스트 상에서는 일반 사용자로서 취급할 수 있다.

    이것은 namespace 안의 관리자 계정은 호스트 OS 에 대해서는 관리 권한을 일절 갖지 않는다는 것을 의미하므로 보안이 뛰어난 환경으로 격리시킬 수 있다.



-

MOUNT namespace

    namespace 안에 격리된 파일 시스템 트리를 만든다.



-

UTS namespace

    namespace 별로 호스트명이나 도메인명을 독자적으로 가질 수 있다.



-

IPC namespace

    프로세스 간의 통신 오브젝트를 namespace 별로 독립적으로 가질 수 있다.




* 릴리스 관리 장치(cgroups) 


-

물리 머신 상의 자원을 여러 컨테이너가 공유하여 작동한다.

이 때 Linux 커널 기능인 control groups(cgroups) 기능을 사용하여 자원의 할당 등을 관리한다.



-

Linux에서는 프로그램을 프로세스로서 실행한다.

프로세스는 하나 이상의 스레드 모음으로 움직이다

cgroups 는 프로세스와 스레드를 그룹화하여, 그 그룹 안에 존재하는 프로세스와 스레드에 대한 관리를 수행하기 위한 기능이다.

예를 들어 호스트 OS 의  CPU 나 메모리와 같은 자원에 대해 그룹별로 제한을 둘 수 있다.



-

cgroups 의 주요 서브 시스템

    cpu : CPU 사용량 제한

    cpuacct : CPU 사용량 통계 정보 제공

    cpuset : CPU 나 메모리 배치를 제어

    memory : 메모리나 스왑 사용량을 제한

    devices : 디바이스에 대한 액세스 허가/거부

    freezer : 그룹에 속한 프로세스 정지/재개

    net_cls : 네트워크 제어 태그를 부가

    blkio : 블록 디바이스 입출력량 제어



-

cgroups 는 계층 구조를 사용하여 프로세스를 그룹화하여 관리할 수 있다.

예를 들어 사용자 앱과 서버와 같은 데몬 프로세스를 나눠, 각각의 그룹에 CPU 사용량을 할당할 수 있다.

cgroups 의 부모자식 관계에서는 자식이 부모의 제한을 물려받는다.




* 네트워크 구성(가상 브리지/가상 NIC)


-

Docker 를 설치하면 서버의 물리 NIC 가 docker0 이라는 가상 브리지 네트워크로 연결된다.

이 docker0 은 Docker 를 실행시킨 후에 디폴트로 만들어진다.

Docker 컨테이너가 실행되면 컨테이너에 172.17.00/16 이라는 서브넷 마스크를 가진 프라이빗 IP 주소가 eth0 으로 자동 할당된다.

이 가상 NIC 는 OSI 참조 모델의 레이어 2인 가상 네트워크 인터페이스로, 페어인 NIC 와 터널링 통신을 한다.



-

Docker 컨테이너와 외부 네트워크가 통신을 할 때는 가상 브리지 docker0 과 호스트 OS 의 물리 NIC 에서 패킷을 전송하는 장치가 필요하다.

Docker 에서는 NAPT 기능을 사용하여 연결한다.


NAPT(Network Address Port Translation)란 하나의 IP 주소를 여러 컴퓨터가 공유하는 기술로, IP 주소와 포트 변호를 변환하는 기능이다.

Docker 에서는 NAPT 에 Linux 의 iptables 를 사용하고 있다.


Docker 에서는 이 기능을 사용할 때 컨테이너 시작 시에 컨테이너 안에서 사용하고 있는 포트를 가상 브리지인 docker0 에 대해 개방한다.

예를 들어 컨테이너 시작 시에 컨테이너 안의 웹 서버가 사용하는 80번 포트를 호스트 OS 의 8080번 포트로 전송하도록 설정한다.

그러면 외부 네트워크에서 호스트 OS 의 8080번 포트에 액세스하면 컨테이너 안의 80번 포트로 연결된다.



-

NAPT 는 IP 주소와 함께 포트 번호도 같이 변환하는 기술이다.

Linux 에서 NAPT 를 구축하는 것을 IP 마스커레이드라고 부른다.

마스커레이드(mascarade)란 영어로 가면무도회를 의미한다.




* Docker 이미지의 데이터 관리 장치


-

데이터를 복사할 필요가 생겼을 때 새로운 빈 영역을 확보하고 거기에 복사를 한다.

그러나 복사한 데이터에 변경이 없다면 그 복사는 쓸데없는 것이 된다.

복사할 데이터의 용량이 클수록 쓸데없는 낭비가 된다.

그래서 복사를 요구받아도 바로 복사하지 않고 원래의 데이터를 그대로 참조시켜, 원본 또는 복사 어느 쪽에 수정이 가해진 시점에 비로소 새로운 빈 영역을 확보하고 데이터를 복사한다.

이러한 장치를 Copy on Write 라고 부른다.

Docker 에서는 Copy on Write 방식으로 컨테이너의 이미지를 관리한다.



-

AUFS

    다른 파일 시스템의 파일이나 디렉토리를 투과적으로 겹쳐서 하나의 파일 트리를 구성할 수 있는 파일 시스템.



-

Btrfs

    Linux 용 Copy on Write 파일 시스템으로, 과거의 상태로 돌아갈 수 있는 롤백 기능이나 어떤 시점에서의 상태를 저장할 수 있는 스냅샷 기능을 갖고 있다.



-

Device Mapper

    Linux 2.6 에 들어간 블록 디바이스 드라이버와 그것을 지원하는 라이브러리들이다.

    파일 시스템의 I/O 와 디바이스의 매핑 관계를 관리한다.

    thin-provisioning 기능과 snapshot 기능을 가지고 있다.

    CentOS 나 Fedora 같은 Red Hat OS 나 Ubuntu 등에서 docker 를 이용할 때 사용된다.



-

OverlayFS

    UnionFS 중 하나로 파일 시스템에 다른 파일 시스템을 투과적으로 머징하는 장치이다.



-

ZFS

    Sun(현재 Oracle)이 개발한 새로운 파일 시스템이다.




댓글0