Docker 개요

marco x brown·2019년 12월 29일
1

Docker를 그렇게 많이 테스트해보고 사용해봤지만 정작 등장 배경과 개념 등 기초 지식에 대해 명확하게 아는 것이 별로 없었다. 뜬구름 잡기 식으로 배웠기 때문에 기초가 탄탄하지 않아서 이번 기회에 초석을 다져보고자 한다.

Docker는 시스템 가상화의 일종으로 최근에 굉장히 각광받고 있는 기술이다. 사실 최근도 아니고 꽤 오래되었다. 인프라 위에서 각 애플리케이션을 분리시킬 수 있고 컨테이너라는 분리된 각 애플리케이션끼리 통신도 할 수 있다. 코드를 작성하고 운영 환경에서 실행하는 시점 간의 딜레이를 절감시킬 수 있는 기술이다.

Docker Platform, Engine

Docker는 컨테이너라는 느슨히 독립된 환경에서 프로그램을 패키징하고 실행하도록 지원한다. 격리와 보안을 통해 많은 컨테이너들을 동시에 실행할 수 있고, Hypervisor의 추가적인 로드없이 호스트 시스템의 커널에서 직접 실행되기 때문에 가볍고 빠르다. 다시 말해 Virtual Machine과 컨테이너의 가장 큰 차이점은 OS라고 볼 수 있는데, Virtual Machine의 경우 각기 다른 OS들을 동시에 구동할 수 있는 반면에 컨테이너 환경은 컨테이너를 띄운 호스트 OS의 커널을 따르게 된다. (호스트 OS가 Linux인 경우 컨테이너도 Linux)

Docker는 컨테이너의 lifecycle을 관리하기 위한 도구와 플랫폼을 제공하기도 한다. 애플리케이션을 테스트하고 배포하기 위한 하나의 단위가 되기도 하고, 프로덕션 환경이 로컬이든 클라우드이든 어떤 경우이든 동일하게 배포할 수 있다.

Docker Engine데몬 프로세스라고 부르는 장기 실행 프로그램의 일종인 서버와, 데몬과 통신할 수 있도록 하는 인터페이스를 제공하는 REST API, CLI로 구성된다. CLI는 Docker REST API를 사용하여 스크립트 또는 커맨드를 통해 데몬을 컨트롤하거나 데몬과 통신한다.

dockerd 커맨드로 수행되는 데몬 프로세스는 이미지, 컨테이너, 네트워크, 볼륨 등의 Docker 객체들을 생성하고 관리한다.

Docker Architecture

Docker는 클라이언트-서버 구조로 이루어져 있다. 클라이언트인 CLI(Docker)를 통해 각 커맨드로 데몬 프로세스와 통신하고, 데몬 프로세스가 Docker 레지스트리에 저장되어 있는 이미지들을 불러와 컨테이너를 실행하거나 커스터마이징한 이미지를 Docker 레지스트리에 다시 업로드하는 흐름을 가진다.

Docker 데몬

다른 Docker 데몬과 통신하거나 Docker API 요청을 기다리고 이미지, 컨테이너, 네트워크, 볼륨 등을 관리하는 역할을 한다. dockerd

Docker 클라이언트

클라이언트는 docker 커맨드를 통해 한 개 이상의 데몬과 통신할 수 있으며 사용자가 Docker와 상호작용할 수 있는 가장 우선적인 방법이다. docker

Docker 레지스트리

Docker 이미지 저장소. 기본적으로 Docker Hub라는 퍼블릭 레지스트리로 설정되어 있고 프라이빗 레지스트리도 생성할 수 있다. Docker Datacenter(DDC)를 사용하는 경우, Docker Trusted Registy(DTR)로부터 pull, push 할 수 있다.

Docker 객체

  • 이미지
    이미지는 컨테이너를 생성하기 위한 read-only 템플릿이며, 기존 이미지를 커스터마이징하여 새로운 이미지를 만들 수도 있다. 이미지를 생성하고 실행하기 위해 필요한 단계들을 정의한 Dockerfile이라는 파일을 사용하여 이미지를 빌드할 수 있다. Dockerfile 내의 각 커맨드는 이미지 안에 하나의 각 레이어를 생성하는데, Dockerfile을 변경하고 이미지를 다시 빌드하면 변경된 레이어만 반영되어 여타 가상화 기술에 비해 굉장히 가볍고 빠르게 만들 수 있다.

  • 컨테이너
    실행가능한 이미지의 인스턴스이다. 기본적으로 호스트 머신과 다른 컨테이너들과 상대적으로 잘 독립되어 있으며, 컨테이너의 네트워크, 스토리지 또는 서브시스템이 다른 컨테이너 또는 호스트 머신과 얼마나, 어떻게 독립적으로 실행되는지까지 제어할 수 있다.

    컨테이너가 데이터를 영구적으로 보관하지 않으므로 컨테이너를 삭제하면 안에 있는 데이터와 상태들까지도 삭제된다. 이 때 volume을 사용하면 컨테이너를 삭제하더라도 데이터 또는 상태를 보존할 수 있다.

    $ docker run -it ubuntu /bin/bash

    이 커맨드를 실행하는 시점에 해당 이미지가 없을 경우, docker pull ubuntu 커맨드까지 자동으로 수행한다. 즉, docker run 커맨드에 이미지 pull 기능까지 포함되어 있다는 것이다.

    docker container create 커맨드처럼 컨테이너를 생성하고, 컨테이너의 로컬 파일시스템 안에서 파일 또는 디렉토리를 생성하거나 수정, 읽기할 수 있도록 read-write 파일시스템을 할당한다.

    기본적으로 컨테이너는 호스트 머신의 네트워크 연결을 통해 외부 네트워크와 연결할 수 있다. 위의 커맨드에서 네트워크 관련 옵션을 사용하지 않았으므로 기본 네트워크에 연결하는 네트워크 인터페이스를 생성한다.

    -i 옵션과 -t 옵션으로 컨테이너가 호스트 머신의 터미널에 붙기 때문에 키보드를 통한 입출력이 가능하다.

  • 서비스
    서비스라는 개념을 통해 여러 Docker 데몬들로 구성된 집합 규모로까지 확장할 수 있으며, Docker Swarm과 같은 서비스를 통해 사용자에게는 단일 애플리케이션처럼 보이게 된다.

Docker 핵심 기술

Namespaces

독립된 워크스페이스인 컨테이너를 제공하기 위해 네임스페이스라는 기술이 적용되었다. 컨테이너를 실행하면 Docker가 다음과 같은 해당 컨테이너의 네임스페이스 집합을 생성한다.

pid: 프로세스 격리 (PID: Process ID)

net: 네트워크 인터페이스 관리 (NET: Networking)

ipc: IPC 리소스 접근 관리 (IPC: InterProcess Communication)

mnt: 파일시스템 마운트 포인트 관리 (MNT: Mount)

uts: 독립적인 커널과 버전 식별자 (UTS: Unix Timesharing System)

Control Groups

Linux 기반의 Docker Engine은 Control Groups(cgroups)에 의존한다. 특정 컨테이너에 메모리 가용량을 제한하는 것처럼, Docker Engine이 사용가능한 하드웨어 자원을 공유할 수 있도록 허용하거나 선택적으로 제한을 둘 수 있다. 다시 말해 자원 관리와 관련된 요소이다.

Union file systems

Docker를 통해 효율적인 애플리케이션 운영이 가능하도록 하는 핵심 기술 중에 Union 파일 시스템이 있는데 각 컨테이너에 레이어로 계층화하여 특정 이미지의 버전 관리 또는 이미지를 재사용할 수 있도록 한다. UnionFS는 각 파일과 디렉토리들을 branch로 그룹화하고 각 branch들은 다른 branch 위에 stack으로 쌓는다. 이미지를 통해 컨테이너를 생성하면 UnionFS이 이 이미지 위에 쓰기 가능한 레이어를 생성하여 기존 이미지에 영향을 주지 않고 재사용이 가능하도록 하게 해준다.

Container format

Docker Engine은 container format이라는 wrapper 안에 namespaces, control groups, UnionFS들을 결합시킨다. 기본 container format은 libcontainer이다. 사실 이 부분이 제일 와닿지 않고, 어려운 부분이다.

\<참고>

https://docs.docker.com/engine/docker-overview/

https://tech.peoplefund.co.kr/2017/04/03/what-is-docker-ko.html

profile
개발자로 크는 중

0개의 댓글