6 분 소요


Docker architecture를 정리한 글입니다.




Docker 소개

Docker Engine은 개발(Developing), 제공(Shipping), 실행(Running)을 위한 오픈 소스 플랫폼입니다.
Docker를 사용하면 애플리케이션을 인프라에서 분리할 수 있기 때문에 소프트웨어를 빠르게 제공할 수 있습니다. 또, 애플리케이션을 관리하는 것처럼 인프라를 관리할 수도 있습니다.
Docker는 코드를 신속하게 전달, 테스트 및 배포할 수 있기 때문에, 코드 작성과 프로덕션에서의 실행까지의 과정을 빠르게 진행할 수 있습니다.


그림. VM vs 컨테이너




Docker 플랫폼

Docker는 컨테이너라는 느슨하게 격리된 환경에서 애플리케이션을 패키징하고 실행할 수 있습니다.
격리와 보안을 통해 주어진 호스트에서 여러 컨테이너를 동시에 실행할 수 있습니다.
컨테이너는 하이퍼바이저의 추가적인 부하가 없기 때문에 가볍지만, 호스트 시스템의 커널 내에서 직접 실행됩니다.

Docker는 컨테이너의 수명을 관리하기 위한 도구와 플랫폼을 제공합니다.

  • 컨테이너를 사용하여 애플리케이션 및 관련된 컴포넌트를 개발합니다.
  • 컨테이너는 애플리케이션을 배포하고 테스트하는 단위가 됩니다.
  • 준비가 되면 애플리케이션을 컨테이너 또는 오케스트레이션된 서비스로 프로덕션 환경에 배포합니다.
    프로덕션 환경이 로컬 데이터 센터, 클라우드 공급자 또는 둘의 하이브리드든 상관없이 동일하게
    작동합니다.




Docker Engine

Docker Engine은 다음 컴포넌트로 구성된 클라이언트-서버 애플리케이션입니다.

  • 서버는 데몬 프로세스(Daemon Process, dockerd)입니다.
  • REST API는 프로그램이 Docker 데몬과 통신하고 지시하는 데 사용하는 인터페이스입니다.
  • 클라이언트는 커맨드라인 인터페이스(CLI, docker)입니다.


Docker engine


CLI는 스크립팅이나 직접 명령을 실행하여 Docker API를 통해 Docker 데몬을 제어하거나 상호 작용합니다.
다른 수 많은 Docker 애플리케이션들은 기본 API 와 CLI를 사용합니다.
데몬은 이미지, 컨테이너, 네트워크 및 볼륨과 같은 Docker 객체를 만들고 관리합니다.

참고: Docker는 오픈 소스 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다.

자세한 내용은 Docker 아키텍처를 참조하세요.




Docker는 어디에 사용할 수 있나요?

빠르고 일관된 애플리케이션 제공

Docker를 사용하면, 표준화된 환경인 컨테이너에서 작업하기 때문에 개발 주기가 간단하게 됩니다.
컨테이너는 CI/CD(지속적 통합 및 지속적 배포) 작업 흐름에 적합합니다.

다음은 예제 시나리오입니다:

  • 개발자는 로컬에서 코드를 작성하고 Docker 컨테이너를 사용하여 동료와 작업을 공유합니다.
  • 그들은 Docker를 사용하여 애플리케이션을 테스트 환경으로 푸시하고 자동 및 수동 테스트를 실행합니다.
  • 개발자가 버그를 발견하면 개발 환경에서 버그를 수정하고 테스트 및 검증을 위해 테스트 환경에 재배포할 수 있습니다.
  • 테스트가 완료되면 업데이트된 이미지를 프로덕션 환경에 푸시하는 것으로 간단하게 수정 사항을 적용할 수 있습니다.


반응형(Responsive) 배포 및 확장

Docker의 컨테이너 기반 플랫폼은 효율적으로 워크로드(Workload)를 처리합니다.
Docker 컨테이너는 개발자의 랩톱, 데이터 센터의 물리 또는 가상 머신, 클라우드 공급자 또는
혼합된 환경에서 실행할 수 있습니다. 또, Docker의 이식성과 가볍다는 특성은 비즈니스 요구에 따라 바로 애플리케이션이나 서비스를 확장(Scaling up)하거나 축소(Tearing down)하여, 워크로드를 동적으로 쉽게 관리할 수 있습니다.

워크로드(Workload): 컴퓨팅 블록이 처리하는 작업량의 의미로 정리했습니다.


동일한 하드웨어에서 더 많은 워크로드 실행

Docker는 가볍고 빠릅니다. 하이퍼바이저 기반 가상 머신을 대체하여, 독립적이고 효율적이기 때문에 더 많은 컴퓨팅 용량을 사용하여 비즈니스 목표를 달성 할 수 있습니다.
Docker는 더 적은 리소스로 더 많은 작업을 수행해야 하는 고밀도 환경과 중소 규모의 배포 환경에 적합합니다.




Docker 아키텍쳐

Docker는 클라이언트-서버 아키텍처를 사용합니다.
Docker 데몬은 컨테이너를 빌드, 실행 및 배포하는 무거운 작업을 수행하고, Docker 클라이언트는
Docker 데몬과 통신합니다.
Docker 클라이언트와 데몬은 동일한 시스템에서 실행될 수도 있고, Docker 클라이언트를 원격 Docker 데몬에 연결할 수도 있습니다.
Docker 클라이언트와 데몬은 UNIX 소켓 또는 네트워크 인터페이스를 통해 REST API를 사용하여 통신합니다.


Docker architecture



Docker 데몬(dockerd)

Docker 데몬은 Docker API 요청을 수신하고 이미지, 컨테이너, 네트워크 및 볼륨과 같은 Docker 객체를 관리합니다.
데몬은 다른 데몬과 통신하여 Docker 서비스를 관리할 수도 있습니다.


Docker 클라이언트(docker)

Docker 클라이언트는 Docker 사용자가 Docker와 상호 작용하는 가장 기본적인 방법입니다.
docker run과 같은 명령을 사용할 때 클라이언트는 이 명령을 dockerd로 전송하여 실행합니다.
docker 명령은 Docker API를 사용하고, 여러 데몬과 통신할 수도 있습니다.


Docker 레지스트리

Docker 레지스트리는 Docker 이미지 저장소입니다.
Docker Hub는 누구나 사용할 수 있는 공용 레지스트리이며 Docker는 기본적으로 Docker Hub에서 이미지를 찾습니다. 자신의 개인 레지스트리를 구성할 수도 있습니다.

docker pull 또는 docker run 명령을 사용하면 필요한 이미지를 레지스트리에서 가져옵니다.
docker push 명령을 사용하면 레지스트리로 이미지를 푸시합니다.


Docker 객체들

Docker를 사용하면 이미지, 컨테이너, 네트워크, 볼륨, 플러그인 및 기타 객체를 생성하고 사용합니다.
이러한 객체에 대해서 간단히 설명하겠습니다.

이미지(Image)

이미지는 Docker 컨테이너를 만들기 위한 명령이 있는 읽기 전용 템플릿입니다.
종종 이미지는 다른 이미지를 기반으로 몇 가지 사용자 정의가 추가됩니다.
예를 들어, 우분투 이미지를 기반으로 하는 이미지를 빌드할 수도 있지만, Apache 웹 서버와 애플리케이션, 애플리케이션에 필요한 설정이 추가될 수 있습니다.

자신의 이미지를 만들 수도 있고 다른 사람이 만들어 레지스트리에 게시한 이미지만 사용할 수도 있습니다.
자체 이미지를 빌드하려면, 이미지를 생성하고 실행하는 데 필요한 단계를 정의한 Dockerfile을 사용합니다.
Dockerfile의 각 명령어는 이미지에 레이어를 만듭니다. Dockerfile을 변경하고 이미지를 다시 빌드하면 변경된 레이어만 다시 빌드됩니다. 이것은 다른 가상화 기술과 비교할 때 이미지를 매우 가볍고 작고 빠르게 만드는 요인 중 하나입니다.


컨테이너(Containers)

컨테이너는 이미지의 실행 가능한 인스턴스입니다.
Docker API 또는 CLI 를 사용하여 컨테이너를 생성, 시작, 중지, 이동 또는 삭제할 수 있습니다.
컨테이너를 하나 이상의 네트워크에 연결하거나 스토리지를 연결하거나 현재 상태를 기반으로 새 이미지를 만들 수도 있습니다.

기본적으로 컨테이너는 다른 컨테이너 및 호스트 시스템과 비교적 잘 격리되어 있습니다.
컨테이너의 네트워크, 저장소 또는 기타 하위 시스템을 다른 컨테이너나 호스트 시스템에서 분리하는 방식을 제어할 수도 있습니다.

컨테이너는 이미지 뿐만 아니라 생성하거나 시작할 때 제공하는 구성 옵션(Configuration Option)으로 정의됩니다. 컨테이너가 제거되면 영구(persistent) 저장소에 저장되지 않은 변경 사항들은 사라집니다.


docker run 명령 예

다음 명령은 우분투 컨테이너를 실행하고, 로컬 커맨드라인 세션에 대화 형으로 연결하고,
/bin/bash 를 실행합니다.

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

기본 레지스트리 구성을 사용한다고 가정하면, 이 명령은 다음과 같이 동작합니다:

  1. 로컬에 우분투 이미지가 없다면, Docker는 구성된 레지스트리에서 이미지를 가져옵니다.
    (docker pull ubuntu 명령을 직접 실행한 것과 같은 동작입니다.)
  2. Docker는 새 컨테이너를 만듭니다. (docker container create 명령을 직접 실행한 것과 같은 동작입니다.)
  3. Docker는 읽기-쓰기 파일 시스템을 최종 레이어로 컨테이너에 할당합니다.
    이를 통해 실행 중인 컨테이너는 로컬 파일 시스템에서 파일과 디렉토리를 만들거나 수정할 수 있습니다.
  4. Docker는 네트워킹 옵션을 지정하지 않았으므로 컨테이너를 기본 네트워크에 연결하는 네트워크 인터페이스를
    만듭니다. 여기에는 컨테이너에 IP 주소 할당이 포함됩니다.
    기본적으로 컨테이너는 호스트 머신의 네트워크 연결을 사용하여 외부 네트워크에 연결할 수 있습니다.
  5. Docker는 컨테이너를 시작하고 /bin/bash 를 실행합니다.
    컨테이너가 대화식으로 실행(-i-t 플래그)되고 터미널에 연결되기 때문에, 출력이 터미널에 기록되는 동안 키보드를 사용하여 입력을 제공할 수 있습니다.
  6. exit를 입력하여 /bin/bash 명령을 종료하면 컨테이너가 중지되지만 제거되지는 않습니다.
    다시 시작하거나 제거할 수 있습니다.


서비스(Service)

서비스를 사용하면 여러 Manager와 Worker들로 구성된 스웜(Swarm)으로 동작하는, Docker 데몬들로 컨테이너를 확장할 수 있습니다.
스웜의 각 구성원은 Docker 데몬이며 모든 데몬은 Docker API를 사용하여 통신합니다.
서비스를 사용하면 주어진 시간에 가용해야 하는 서비스 복제본 수 같은 상태를 정의할 수 있습니다.
기본적으로 서비스는 모든 Worker 노드에서 로드밸런싱됩니다.
사용자 입장에서 Docker 서비스는 단일 애플리케이션으로 보입니다. Docker Engine은 Docker 1.12 이상에서 스웜 모드를 지원합니다.


기본 기술(The underlying technology)

Docker는 Go로 작성되었으며 Linux 커널의 특징들을 사용하여 기능을 제공합니다.


네임스페이스(Namespace)

Docker는 격리된 작업 공간인 컨테이너를 제공하기 위해 namespaces 라는 기술을 사용합니다.
컨테이너를 실행하면 Docker는 해당 컨테이너에 대한 네임스페이스 집합을 만듭니다.


이러한 네임스페이스는 격리 계층을 제공합니다.
컨테이너의 각 특성들은 별도의 네임스페이스에서 실행되며 접근은 해당 네임스페이스로 제한됩니다.


Docker Engine은 Linux에서 다음 네임스페이스를 사용합니다.

  • pid 네임스페이스: 프로세스 격리 (PID : 프로세스 ID).
  • net 네임스페이스: 관리 네트워크 인터페이스 (NET : 네트워킹).
  • ipc 네임스페이스: IPC 자원에 대한 액세스 관리 (IPC : 프로세스 간 통신).
  • mnt 네임스페이스: 파일 시스템 포인트 (: 마운트 MNT)를 탑재 관리.
  • uts 네임스페이스: 격리를 커널과 버전 식별자. (UTS : 유닉스 Timesharing(시분할) 시스템).


컨트롤 그룹(Control groups)

Linux의 Docker Engine은 컨트롤 그룹(cgroups)이라는 다른 기술도 의존하고 있습니다.
cgroup은 응용프로그램을 특정 리소스 집합으로 제한합니다.
컨트롤 그룹을 통해 Docker Engine은 사용 가능한 하드웨어 리소스를 컨테이너에 공유하고 선택적으로 제한 및 제약 조건을 적용할 수 있습니다.
예를 들면, 특정 컨테이너에서 사용할 수 있는 메모리를 제한할 수 있습니다.


통합 파일 시스템(Union file systems)

Union 파일 시스템(UnionFS)은 레이어를 만들어 매우 가볍고 빠른 파일 시스템입니다.
Docker Engine은 UnionFS를 사용하여 컨테이너의 빌딩 블록을 제공합니다. Docker Engine은 AUFS, btrfs, vfs 및 DeviceMapper를 포함한 여러 UnionFS 변형을 사용할 수 있습니다.


컨테이너 형식(Container format)

Docker Engine은 네임스페이스, 컨트롤 그룹 및 UnionFS를 컨테이너 형식이라는 래퍼로 결합했습니다.
기본 컨테이너 형식은 libcontainer 입니다.
앞으로 Docker는 BSD Jails 또는 Solaris Zones 와 같은 기술과 통합하여 다른 컨테이너 형식도 지원할 예정입니다.




참고자료

공통

  • Docker overview
  • Understanding Volumes in Docker
    데이터를 저장(지속)하고 컨테이너 간에 데이터를 공유할 수 있도록 Docker는 볼륨 개념을 고안했습니다.
    간단히 설명하면, 볼륨은 기본 통합 파일 시스템(Default union file system) 외부에 있고 호스트 파일 시스템에서
    일반 디렉토리 및 파일로 존재하는 디렉토리(또는 파일)입니다.

시작하기

댓글남기기