욱'S 노트

Docker Engine - Architecture 본문

Programming/Docker

Docker Engine - Architecture

devsun 2016. 2. 17. 16:55

Understand the architecture


도커란 무엇인가?


도커는 개발하고 적재하고 어플리케이션을 실행하기 위한 오픈 플랫폼이다. 도커는 어플리케이션을 더빨리 딜리버리하기 위해서 설계되었다. 도커와 함께라면 인프라스트럭처와 어플리케이션을 분리 할 수 있으며, 인프라스트럭처를 어플리케이션처럼 관리할 수 있다. 도커는 코드를 더 빨리 적재하고, 더 빨리 테스트하고, 더 빨리 디플로이하고 코드를 작성하고 코드를 실행하는 사이클을 더 짧게 만들어준다.


도커는 이러한 일들을 결합된 커널 컨테이너 기술로 제공한다. 이러한 워크플로우와 툴들은 당신의 어플리케이션을 디플로이하고 관리하는 것을 도와준다.


핵심적으로 도커는 컨테이너에 안전하고 독립적으로 거의 모든 어플리케이션을 실행하는 방법을 제공한다. 독립과 안정성은 당신의 호스트에 많은 컨테이너를 실행하는 것을 허용한다. 컨테이너의 경량화에 의해 하이퍼바이저의 추가적인 부하없이 실행할 수 있으며, 이것은 하드웨어에 더많은 부분을 활용할 수 있다는 것이다.


컨테이너 환경은 다음과 같은 경우에 툴과 플랫폼으로써 도움을 준다.


어플리케이션은 도커 컨테이너로 넣는다.

컨테이너를 배포하고 적재함으로써 개발과 테스트를 용이하게 한다.

어플리케이션을 프로덕션 환경에 배포한다. 로컬 데이터 센터든 클라우드든 상관없다.


What can I use Docker for?


더빨리 어플리케이션을 배포한다.


도커는 개발 라이프사이클을 완벽하게 지원한다. 도커는 어플리케이션과 서비스를 로컬컨테이너상에서 개발할 수 있도록 해준다. 이것은 CI나 배포 워크플로우와 통합될 수 있다.


예를 들어 개발자는 로컬에 코드를 작성하고 그것을 도커를 통해 동료의 개발 스택에 공유할 수 있다. 준비가 되면 그들의 코드를 푸쉬하고 그것을 테스트 환경에 보내고 필요한 테스트를 수행할 수 있다. 테스트 환경으로 부터 도커 이미지를 푸쉬하여 프로덕션에 당신의 코드를 배포할 수 있다.


더 쉽게 디플로이하고 스케일링할 수 있다. 


도커의 컨테이너 베이스 플랫폼은 대량의 워크로드에 더욱 적합하다. 도커 컨테이너는 개발자의 로컬 호스트에서 실행될 수 있다. 또한 물리장비 또는 vm이든 데이터센터든 클라우드든 상관없이 실행할 수 있다.


도커의 이식성과 경량성은 쉽고 다이나믹하게 워크로드를 관리할 수 있게 해준다. 도커를 사용하면 어플리케이션과 서비스를 쉽게 스케일업 또는 티어다운할 수 있다. 도커의 속도는 거의 실시간에 가깝게 스케일링을 할 수 있다.


더 밀도있고 더 많은 워크로드 수행


도커는 가볍과 빠르다. 하이퍼바이저 기반 vm에 viable 그리고 cost-effective 한 대안으로 제공한다. 도커는 특히 고집적 환경에 더 유용하다. 예를 들어 당신만의 클라우드 혹은 PAAS를 구성할 수 있다. 그러나 또한 작거나 중간 사이브의 디플로이환경에도 유용하며 자원을 더욱 효율적으로 사용할 수 있도록 만들어 줄것이다.


What are the major Docker components?


도커는 두개의 주요 컴포넌트를 가지고 있다.


Docker: 오픈소스 컨테이너 플랫폼

Docker Hub:  도커 컨테이너를 관리하고 공유하기 위한 SAAS

Note: 도커의 라이센스는 Apache 2.0이다.


What is Docker’s architecture?


도커는 클라이언트-서버 아키텍처를 이용한다. 도커 클라이언트는 도커 데몬과 대화한다. 도커 데몬은 도커 컨테이너를 빌드, 실행, 분산을 담당한다. 도커 클라이언트와 데몬은 같은 시스템에서 실행되거나 도커 클라이언트가 리모트에 있는 도커 데몬에 접속할 수 있다. 도커 클라이언트와 데몬은 소켓이나 RESTful API를 통해서 통신한다.


The Docker daemon


위의 다이어그램에서 보다시피 도커 데몬은 호스트 모신에서 실행된다. 유저는 도커 데몬과 직접 통신하는 대신 도커 클라이언트를 통해서 통신한다.


The Docker client


도커 클라이언트는 도커와 통신하는 프라이머리 유저이다. 유저로부터 명령을 받아서 도커 데몬으로 전송하고 결과를 받는다.


Inside Docker


도커의 내부구조를 이해하기 위해서는 3가지 컴포넌트에 대해서 알 필요가 있다.


Docker images.

Docker registries.

Docker containers.


Docker images


도커 이미지는 읽기전용 템플릿이다. 예를들어 이미지는 우분투 OS와 아파치 그리고 설치된 웹어플리케이션을 포함할 수 있다. 이미지는 도커 컨테이너를 생성하기 위해서 사용된다. 도커는 새로운 이미지를 생성하고 기존 이미지를 업데이트하는 단순한 방법을 제공한다. 또한 다른 사람이 이미 생성한 도커 이미지를 다운로드 받을 수도 있다. 도커 이미지는 도커의 빌드 컴포넌트이다.


Docker registries


도커 레지스트리는 이미지를 저장한다. 이것은 퍼블릭 또는 프라이빗 스토어로부터 이미지를 업로드 또는 다운로드 할 수 있다. 퍼블릭 도커 레지스트리는 도커 허브에 의해 제공된다. 도커 허브는 당신이 사용할 수 있는 대량의 이미지 컬렉션을 제공한다. 도커 레지스트리는 도커의 분산 컴포넌트이다.


Docker containers


도커 컨테이너는 디렉토리와 비슷하다. 도커 컨테이너는 어플리케이션을 실행하는 모든것을 포함하고 있다. 도커 이미지로부터 각 컨테이너는 생성된다. 도커 컨테이너는 실행하고, 시작되고, 중지되고, 이동되고, 삭제될 수 있다. 각 컨테이너는 어플리케이션 플랫폼에 완전하게 독립적이다. 도커 컨테이너는 도커의 실행 컴포넌트이다.


So how does Docker work?


어플리케이션을 저장하기 위해 도커 이미지를 생성할 수 있다.

도커 이미지로부터 어플리케이션을 실행하기 위해 도커 컨테이너를 생성할 수 있다.

도커허브나 자신만의 레지스트리를 통해 도커 이미지를 공유할 수 있다.


이제 이러한 엘리먼트들이 어떻게 함께 결합되는지 살펴보자.


How does a Docker image work?


우리는 이미 도커 이미지는 읽기 전용 템플릿이라는 것을 알고 있다. 이것은 도커 컨테이너를 실행하기 위해 사용된다. 각 이미지는 일련의 레이어로 구성된다. 도커는 이러한 레이어를 하나의 이미지로 결합하기 위해 union 파일시스템을 이용한다. 유니온 파일 시스템은 분리된 파일 시스템을 파일과 디렉토리를 하나의 파일 시스템으로 구성한다. 


도커가 경량화된 하나의 이유는 이러한 레이어에 때문이다. 도커 이미지를 변경하면 - 예를들어 어플리케이션을 새로운 버젼으로 업데이트하면 - 새로운 레이어가 생성된다. 그러므로 전체 이미지를 대체하거나 전체를 리빌딩하기 않고 단지 레이어를 추가하거나 변경한다. 이제 새로운 이미지 전체를 분산할 필요없이 단지 업데이트하므로 도커 이미지 분산은 더 빠르고 단순해진다.


모든 이미지는 기본 이미지로부터 시작한다. 예를 들어 우분투는 기본 우분트 이미지로부터 페도라는 기본 페도라이미지로 부터 시작한다. 또한 새로운 이미지를 위해 당신의 이미지를 베이스로 시작할 수도 있다. 예를들어 기본 아파치 이미지를 가지고 있다면 그것을 기반으로 웹어플리케이션 이미지를 생성할 수 잇을 것이다.


Note: 도커는 일반적으로 도커허브로부터 기본 이미지를 제공받는다.


도커 이미지는 이러한 기본 이미지를 기반으로 빌드된다. 빌드시에 단순하고 직관적인 일련의 스텝을 지시할 수 있다. 이러한 지시에 따라 이미지에 새로운 레이어를 생성할 수 있다. 지시는 다음과 같은 액션을 포함할 수 있다.


커맨드를 실행한다. 

파일이나 디렉토리를 추가한다.

환경변수를 생성한다.

이미지로부터 컨테이너가 구동될때 실행할 프로세스를 지정한다.


이러한 지시는 Dockerfile이라고 불리는 파일에 저장된다. 도커는 이미지 빌드 요청시 Dockerfile을 읽고 지시를 수행한 다음, 최종적으로 이미지를 리턴한다.


How does a Docker registry work?


도커 레지스트리는 도커 이미지를 저장하기 위한 스토어이다. 도커허브와 같은 퍼블릭 레지스트리에 도커 이미지를 푸쉬할 수 있고 또한 방화벽 내의 프라이빗 레지스트리를 운영할 수도 있다.


도커 클라이언트를 사용하여 이미 배포된 이미지를 찾을수 있고 그러한 이미지들을 호스트로 풀해서 컨테이너를 생성하는데 사용할 수도 있다.


도커 허브는 이미지를 위한 퍼블릭 그리고 프라이빗 레지스트리를 제공한다. 퍼블릭 스토리지는 누구나에게나 조회하고 다운로드받을 수 있다. 프라이빗 스토리지는 허용된 사용자에게만 검색과 다운로드가 가능하다. 


How does a container work?


컨테이너는 OS, 유저추가파일 및 메타데이터로 구성된다. 각 컨테이너는 이미지로부터 빌드된다. 이미지는 어떠한 컨테이너가 포함되어 있는지 컨테이너가 실행될 때  어떠한 프로세스가 실행되는지 그리고 다양한 설정 데이터들을 포함한다. 도커 이미지는 읽기전용이다. 이미지로부터 도커가 컨테이너를 실행할때 이미지와 최상단에 읽기-쓰기가 가능한 레이어가 추가된다.


What happens when you run a container?


도커 바이너리나 API를 통해 도커 클라이언트는 도커 데몬에게 컨테이너를 실행하라고 요청할 수 있다.


$ docker run -i -t ubuntu /bin/bash


이 커맨드를 분석해보자. 도커 바이너리를 사용한 도커 클라이언트가 구동된다. run 옵션은 새로운 컨테이너를 구동하라는 명령이다. 


도커를 실행할려면 최소한 다음과 같은 내용이 기술되어야 한다.


어떠한 도커 이미지로부터 컨테이너를 빌드할 것인가? 여기에서는 우분투 즉 기본 우분투이다.

명령은 컨테이너가 실행되었을 때 실행할 커맨드를 포함할 수 있다. 여기서는 /bin/bash 이다. 이 명령은 새로운 컨테이너내의 배쉬쉘을 실행시킨다.


이 명령이 실행되면 내부적으로 어떠한 일들이 발생할까?


도커는 다음과 같은 일들을 수행한다.


도커 이미지를 풀한다 : 도커는 우분투 이미지가 존재하는지 확인한다. 만약 호스트에 없다면 도커는 도커 허브로부터 다운로드 한다. 만약 존재한다면 도커는 해당 이미지를 재사용한다.

새로운 컨테이너 생성: 도커가 이미지를 가지고 있다면 해당 이미지를 이용하여 새로운 컨테이너를 생성한다.

파일 시스템을 할당하고 읽기-쓰기 레이어를 마운트 : 파일 시스템에 새로운 컨테이너를 생성하고 이미지에 읽기-쓰기 레이어를 추가한다.

네트워크/브리지 인터페이스 할당 : 로컬 호스트와 통신할 수 있는 네트워크 인터페이스를 도커 컨테이너에 할당

셋업 IP 어드레스 : 주소풀로부터 이용가능한 IP주소를 찾아서 할당함

명시한 프로세스 실행 : 어플리케이션 실행

어플리케이션 출력 결과 캡쳐 및 제공 : 표준입출력 및 에러출력에 연결하여 어플리케이션이 어떻게 실행되고 있는지 제공


이제 수행중인 컨테이너를 가지게 되었다. 


The underlying technology


도커는 Go로 작성되었고 기능을 제공하기 위해 몇몇의 커널 기능을 이용한다.


Namespaces


도커는 네임스페이스 기술을 이용하여 독립된 워크스페이스를 제공한다. 컨테이너가 실행되면 도커는 컨테이너의 일련의 네임스페이스를 생성한다.


이것은 독립적인 레이어를 제공한다. 각 컨테이너는 자신만의 네임스페이스내에서 실행되고 그것의 외부로 접근하지 않는다.


도커가 리눅스에서 사용하는 네임스페이스는 다음과 같다.


The pid namespace: 프로세스 독립을 위해 사용된다. (PID: Process ID).

The net namespace: 네트워크 인터페이스 관리를 위해서 사용된다. (NET: Networking).

The ipc namespace: IPC 리소스 제어 관리를 위해서 사용된다. (IPC: InterProcess Communication).

The mnt namespace: 마운트 포인트 관리를 위해서 사용된다. (MNT: Mount).

The uts namespace: 커널과 버젼 식별자 관리를 위해서 사용된다. (UTS: Unix Timesharing System).


Control groups


리눅스에서 도커는 cgroups라고 하는 또다른 기술을 이용한다. 독립된 환경에서 실행되는 어플리케이션은 주요한 점은 당신이 원하는 자원만을 사용해야 한다는 것이다. 컨테이너가 호스트의 멀티테넌스라는 것을 확실히 한다. 컨트롤 그룹은 도커에 컨테이너가 공유할 수 있는 하드웨어 리소스를 허락하고 원한다면 제약과 한계를 세팅할 수 있다. 예를 들어 특정한 컨테이너에 메모리르 사용량을 제약할 수 있다.


Union file systems


UFS는 레이어 생성에 의해 조작되는 파일 시스템이다. 도커는 UFS를 이용해서 컨테이너를 위한 빌딩블록을 제공한다. 도커는 몇가지 UFS를 이용할 수 있다. : AUFS, btrfs, vfs, DeviceMapper.


Container format


도커는 컨테이너 포맷이라고 불리는 컴포넌트들을 조합한다. 기본 컨테이너 포맷은 libcontainer인데, 미래에는 다른 컨테이너 포맷을 지원할 수도 있다. 예를 들어 BSD Jails 또는 Solaris Zones이 있다.

Comments