Docker 개요

chris·2022년 11월 12일
0

dokcer

목록 보기
1/2
post-thumbnail

Docker는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼이다.
Docker는 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 이 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는 데 필요한 모든 것이 포함되어 있다.
Docker를 사용하면 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행될 것임을 확신할 수 있다.
Docker는 2013년 3월 산타클라라에서 열린 Pycon Conference에서 dotCloud의 창업자인 Solomon Hykes가 The future of Linux Containers라는 세션을 발표하면서 처음 세상에 알려졌다.

가상머신과 도커 컨테이너

Virtual Machines

기존의 가상화 기술은 Hypervisor를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해 사용하는 방식이었다.
이러한 여러개의 운영체제는 가상 머신이라는 단위로 구별되고, 각 가상머신에는 Ubuntu, CentOS 등의 운영체제가 설치되어 사용된다. Hypervisor에 의해 생성되고 관리되는 운영체제는 Guest OS라고 하며, 각 Guest OS는 다른 Guest OS와는 완전히 독립된 공간과 시스템 자원을 할당받아 사용한다.
각종 시스템 자월을 가상화하고 독립된 공간을 생성하는 작업은 Hypervisor를 반드시 거치기 때문에 일반 호스트에 비해 성능의 손실이 발생한다.
뿐만 아니라 가상 머신은 Guest OS를 사용하기 윈한 라이브러리, 커널 등을 전부 포함하기 때문에 가상 머신을 배포하기 위한 이미지로 만들었을 때 이미지의 크기 또한 커진다.

Container

Docker 컨테이너는 가상화된 공간을 생성하기 위해 리눅스의 자체 기능인 chroot, namespace, cgroup을 사용함으로써 프로세스 단위의 격리 환경을 만들기 때문에 성능 손실이 거의 없다.
컨테이너에 필요한 커널은 호스트의 커널을 공유해 사용하고, 컨테이너 안에는 Application을 구동하는 데 필요한 라이브러리 및 실행 파일만 존재하기 때문에 컨테이너를 이미지로 만들었을 때 이미지의 용량 또한 가산 머신에 비해 대폭 줄어든다.

Docker를 사용해야 하는 이유

Application의 개발과 배포가 편해진다.

Docker 컨테이너는 Host OS위에서 실행되는 격리된 공간이다. 따라서 컨테이너 자체에 특별한 권한을 주지 않는 한 컨테이너 내부에서 수많은 소프트웨어를 설치하고 설정 파일을 수정해도 Host OS에는 영향을 끼치지 않는다.

컨테이너 내부에서 여러 작업을 마친 뒤 이를 운영 환경에 배포하려고 한다면, 해당 컨테이너를 Docker Image로 만들어 운영 서버에 전달하기만 하면 된다. 운영 서버에 필요한 패키지를 새롭게 설치할 필요도 없으며, 각종 라이브러리 설치 등으로 인한 의존성을 걱정 할 필요도 없다. 서비스를 개발했을 때 사용했던 환경을 다른 서버에서도 컨테이너로 똑같이 복제할 수 있기 때문에 개발/운영 환경의 통합이 가능해진다.

여러 Application의 독립성과 확장성이 높아진다.

마이크로서비스 구조는 여러 모듈을 독립된 형태로 구성하기 때문에 언어에 종속되지 않고 변화에 빠르게 대응할 수 있으며, 각 모듈의 관리가 쉬어진다는 장점이 있다. 컨테이너는 수 초 내로 생성, 시작이 가능할 뿐만 아니라 여러 모듈에게 독립된 환경을 동시에 제공할 수 있기 때문에 마이크로서비스 구조에서 가장 많이 사용되고 있는 가상화 기술이다.

Docker의 구조

Docker의 구조는 크게 두 가지로 나뉜다. 하나는 Client로서의 Docker이고, 다른 하나는 Server로서의 Docker이다.

실제로 컨테이너를 생성하고 실행하며 이미지를 관리하는 주체는 Docker Server이고, 이는 dockerd 프로세스로서 동작한다. Docker Engine은 외부에서 API 입력을 받아 Docker Engine의 기능을 수행하는데, Docker 프로세스가 실행되어 서버로서 입력을 받을 준비가 된 상태를 Docker Daemon이라고 한다.

Docker Daemon은 API 입력을 받아 Docker Engine의 기능을 수행하는데 이 API를 사용할 수 있도록 CLI(Command Line Interface)를 제공하는 것이 Docker Client이다.

Docker 명령어를 입력후 실행하면 다음과 같은 과정으로 도커가 제어된다.

Docker Engine은 Docker Daemon, REST API, API를 통해 Docker daemon과 통신하는 CLI로 모듈식으로 구성된다.
컨테이너를 빌드, 실행, 배포하는 등의 무거운 작업은 Docker Daemon이 하며, Docker Client는 이러한 Docker Daemon과 통신한다. 통신할 때에는 UNIX socket(/var/run/docker.sock) 또는 네트워크 인터페이스를 통한 REST API를 사용한다.

docker client

docker client는 개발자들이 Docker를 사용하는 Docker ClI나 Docker Compose로 docker run과 같은 명령어를 dockerd에게 REST API 형태로 전달한다.

dockerd

dockerd는 Daemon Process 형태로 실행되고 있으며 Docker CLI로부터 RESTful API 형식의 요청을 수신하여 처리하며 UNIX, TCP, FD의 세 가지 소켓 유형을 통해 API 요청을 수신할 수 있다.
dockerd는 Container build, Security, Volume, Networking, Secrets, Orchestration, Distributed state와 같은 docker 기능을 담당하고 있다.
dockerd는 또한 containerd에 의존적이며 containerd 없이 실행할 수 없다.

containerd

containerd도 dockerd와 같이 Daemon Process 형태로 실행된다.
Docker Client로부터 Container 관련 요청을 dockerd를 거쳐 gRPC통신을 통해 containerd로 전달된다. 그리고 containerd는 컨테이너의 실행을 위해 runc를 사용한다.

runc

runc는 libcontainer(Docker사가 multi-platform 서비스를 만들기 위해 go 언어로 작성된 패키지)용 CLI Wrapper로, 독립된 container runtime이다.
docker가 container 관련된 기능을 쉽게 사용할 수 있도록 해주는 가볍고 이식가능한 툴이다.
docker에서 runc의 단 하나의 목적은 바로 Container 생성이다.

shim

containerd는 containerd-shim을 통해 runc를 호출하고 runc는 container를 생성하고 종료된다.
containerd-shim은 프로세스를 subreaper로 만들어서 생성된 container의 stdin/out/err 및 Init Process의 Exit Code를 담당하는 Process가 containerd-shim이 되도록 한다.
container와 containerd의 모든 통신은 containerd-shim을 통해서 이루어진다.

Image

모든 컨테이너는 Image를 기반으로 생성되므로 Image를 다루는 방법은 도커 관리에서 빼놓을 수 없는 부분이다.
Image는 컨테이너를 빌드하기 위한 read-only 바이너리 파일이다. Image는 추가적인 구성과 함께 또 다른 Image의 베이스가 될 수 있다. 컨테이너 Image는 비공개 컨테이너 레지스트리를 사용하여 기업내에 있는 팀끼리 공유하거나 퍼블릭 레지스트리인 도커 허브를 사용하여 세계에 공유할 수 있다. Image는 전에는 가능하지 못했던 방식으로 개발자들 사이에 협업을 할 수 있게 해주기 때문에 가장 중요한 부분이다.

Docker Hub는 Docker가 공식적으로 제공하고 있는 Image Registry로서 Docker 계정을 가지고 있다면 누구든지 Image를 올리고 내려받을 수 있다.
단, Docker Hub는 누구나 이미지를 올릴 수 있기 때문에 공식(Official) 라벨이 없는 이미지는 사용법을 찾을 수 없거나 제대로 동작하지 않을 수 있다.
docker search nginx 명령으로 Docker Hub에서 nginx Image를 검색해보면 다음과 같은 결과를 얻을 수 있다.

Docker의 Image 이름은 단순한 문자열이다. Docker Hub를 기준으로 Docker Image 이름은 <NAMESPACE>/<IMAGE_NAME>:<TAG> 형식으로 구성된다. 그래서 nginx:latest의 좀 더 정확한 이름은 library/nginx:latest이다. 여기서 library는 Docker Hub의 공식 이미지가 저장되어있는 특별한 네임스페이스이다.

Docker container의 lifecycle

References

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리
리눅스 네임스페이스(Linux Namespace)란?
Docker Engine, 제대로 이해하기 (1)

profile
software engineer

0개의 댓글