All Articles

Docker Introduction

Docker는 이미 많이 알려져있고 쓰이는 기술이다. 해외는 물론이고 국내에도 Docker 사용자가 늘고 있다. 그리고 docker를 소개하는 글은 넘치고 넘친다. 그럼에도 불구하고 docker 소개글을 쓰는 이유는 최근에 나에게 docker에 대해서 물어보시는 분들이 많이 생겨서 이 글을 쓰게 된다.

Docker는 무엇인가? Docker 라는 회사가 container virtualization 을 개발하였고 그래서 docker가 container virtualization 기술의 또다른 이름으로 오해하시는 분들이 있는데 container virtualization은 docker 이전에 이미 개발되어 존재 하고 있었다. Docker는 가상화 컨테이너에 application 배포를 자동화 시켜주는 오픈소스 엔진이다.

Docker는 container 가상화 실행 환경 위에 application 배포 엔진을 더함으로서 사용자의 코드를 어디서든 빠르고 가볍게 실행시킬수 있는 기술을 제공한다. 이는 요즘 널리 사용되는 MSA(Micro Service Architecture)와 CI/CD 와 아주 잘 조화되어서 많은 각광을 받게 된다. 실제로 docker는 한 컨데이너 당 하나의 application이나 프로세스를 실행하는 것을 권한다. MSA의 철학과 일맥상통 하는것이다.

Hypervisor 가상화 VS Container 가상화

img
출처: 구글 이미지

Hypervisor는 물리적인 서버 에서 하나 혹은 그 이상의 독립적인 운영체제가 돌아가는 구조이다. 즉 물리적 서버의 OS 위에 여러 다른 독립적인 OS가 가상적(virtually)으로 돌아가는 구조이다. 각각의 OS는 서로에 대해서 알지 못하며 base OS (물리적 서버의 OS)도 알지 못한다. 하나의 물리적 서버에서 실행되고 있지만 가상적으로서 완전한 독립적 OS로 운영 되는 것이다. 이러한 가상화의 장점은 물리적 서버의 리소스를 더 효율적으로 사용할수 있다는 것에 있다. 한 서버에 하나의 OS만 운영을 하는 경우 해당 OS가 서버의 모든 리소스를 항상 full로 사용하기 어려우므로 서버 리소드들이(예를 들어 CPU) idle 상태로 낭비되어 지는 경우가 있을수 있다. 반면에 hypervisor 가상화를 사용하여 하나의 서버에 여러 OS를 실행시키면 CPU를 idle 상태로 두지않고 필요한 OS나 서비스에 할당이 되어질 수 있음으로 리소스를 훨씬 효율적으로 쓰게 되는것이다. 그럼으로 고급 사양의 좋은 서버에 여러 가상화 OS들을 운영하는 것이 저급이나 중급 사양의 여러 서버를 운영하는것보다 훨씬 효율적이라는 것이다. 단점은 기술적을 너무 무겁다(heavy-weight)는 것이다. 독립적인 OS를 실행시키는 것이기 때문에 booting 시간이 길 수 밖에 없으며 리소스를 많이 차지할수 밖에 없다.

Docker 같은 컨테이너 가상화 기술은 hypervisor 가상화와 틀리게 OS의 커널 위의 유저 공간(user space)에서 실행된다. 즉 완전히 독립적인 운영체제를 가상화 하는 것이 아니라 독립적인 user space를 가상화 한다고 생각하면 쉽다. 즉 하나의 호스트 서버에서 여러 독립적인 user space 인스탄스들을 가상적으로 실행할 수 있게 되는 것이다. 이러한 가상화 기술의 장점은 hypervisor 가상화 보다 훨씬 가볍기 때문에 빠르고 쉽게 독립적인 가상 환경을 실행시킬수 있다 (또한 hypervisor는 base OS와 가상화 OS 사이에 커널 시스템 호출을 연결 시켜주는 emulation layer가 필요한데 docker는 hypervisor 처럼 emulator가 필요없이 그냥 일반적인 시스템 API interface를 사용한다). 예를 들어 docker image만 있으면 어디서든 쉽고 빠르게 test 환경, sandbox 환경 및 production 배포를 할 수 있다. 그럼으로 최근에 널리 퍼져있는 MSA(Micro Service Architecture)와 CI/CD에 아주 잘 어울리는 가상화 기술로서 각광을 받고 있다. 단점은 독립적인 OS가 아닌 user space 가상화를 하는 형태이다 보니 운영체제가 전혀 틀린 호스트에서는 실행을 시킬수가 없다. 예를 들어 Windows 를 linux 호스트에서 실행시킬수 없다 (하지만 사실 개발자라면 windows는 어차피 대부분 사용 안할테니 크게 상관없다). 그리고 완전히 독립적인 운영체제 가상화가 아니다 보니 보안적인 측면에서 hypervisor 보다 약할수 밖에 없다.

Docker 구조

Docker는 크게 4가지 부분으로 되어 있다.

  • Docker client 와 server (server는 docker engine으로 불리기도 한다)
  • Docker 이미지
  • Docker registries
  • Docker containers

Docker client 와 server

Docker는 클라이언트 와 서버 구조로 이루어저 있다. 클라이언트가 서버에 명령을 전달하고 서버가 실행시키는 구조이다. docker binrary 커맨드가 docker 클라이언트 이고 dockerd 가 docker daemon 혹은 docker engine이다. Docker engine과 interact하기 위한 Restful API도 제공된다. 클라이언트와 서버는 동일한 호스트 안에서 운영 될수도 있으며 서로 다른 호스트에서 운영 될수도 있다.

Docker 이미지

Docker의 life cycle에서 docker 이미지는 “build”의 부분에 해당된다. Docker container에서 실행시키고 싶은 application을 docker 이미지로 빌드해서 실행시키게 된다.

Docker registries

Docker registires는 docker 이미지를 저장하는 repository라고 보면 된다. Source code를 github에 저장하여 관리하듯 docker 이미지는 dockerhub 같은 docker registries에 저장한다고 생각하면 된다. Github가 마찬가지로 public registry 가 있고 private registry가 있다.

Docker containers

Docker container에서 docker 이미지가 실행된다. 즉 docker 이미지를 실행시키는 가상화 공간 이다. Docker container는 하나 혹은 그 이상의 프로세스를 실행 시킬수 있다 (하지만 하나의 프로세스만 실행시키는 것을 권장).

Docker Compose And Swarm

Docker에서는 여러 docker container들로 이루어진 stack이나 cluster를 관리 하는 서비스도 제공하는데 바로 docker compose 와 docker swarm이다.

  • Docker compose는 복수의 docker container들을 모아서 종합적인 application stack을 정의 하고 운영할수 있도록 해주는 서비스이다. Compose 파일을 사용하여 전체적인 application 서비스를 설정한후, application을 이루고 있는 각각의 컨테이너들 (예를 들어, web 서버 컨테이너, api 서버 컨테이너 등등)을 따로 실행시킬 필요 없이 한번에 생성하고 실행할 수 있도록 해준다.
  • Docker swarm은 docker containers 들로 이러우진 cluster를 관리할수 있도록 해주는 서비스이다. 즉 docker container를 위한 clustering tool 이다.

Docker VS Configuration Management Tools

Docker가 Chef나 Puppet, Ansible 같은 CM tool들을 대체하는가 에 대해서 물어보시는 분들이 많다. Docker를 사용함으로서 많은 CM(configuration management) 부분이 해결되는것은 맞지만 그래도 여전히 CM의 역활이 남아있다. 예를 들어, docker를 사용하기 위해서는 docker가 호스트에 설치되어 있어야 한다. 이러한 부분은 CM tool을 사용하여 관리할 수 있다.

그 외 Docker의 특징들

  • Docker는 modern한 리눅스 커널이 설치되어 있는 x64 호스트에서는 다 실행 가능하다 하지만 커널 버젼 3.10 이상에서 실행되는 것이 overhead가 적기 때문에 권장된다.
  • 최근에는 docker를 Windows 나 Mac에서도 사용 가능하다. 하지만 Windows 및 Mac에서 docker를 직접 실행시키면 내부적으로 가상머신이 실행되어 그 안에서 docker가 실행되기 때문에 개발용 및 테스트 용으로는 괜찮지만 production 용도로는 적합하지 않다.
  • Docker 컨테이너는 독립된 root 파일 시스템이기도 하다 그러므로 파일 시스템 분리가 이루어져 있다.
  • 또한 docker 컨테이너는 호스트와 분리된 프로세스 환경을 가지고 있으므로 독립적인 프로세스를 실행할수 있다.
  • 파일 시스템과 프로세스 환경과 마찬가지로 네트워크 또한 분리 되어 있어서 독립적인 가상 네트워크 인터페이스 와 IP 주소를 가질 수 있다.
  • Resource isolation and grouping - 커널의 cgroups 기능을 통해서 docker container마다 독립적인 CPU와 메모리 가 할당 될수 있다.
  • Docker 파일 시스템은 copy-on-write 을 사용하여서 효율적이며 빠른 디스크 IO를 실행한다. Docker의 copy-on-write은 중요한 특징중 하나이므로 다음에 더 자세히 설명하겠다.
  • Docker 컨테이너에서 STDOUT, STDERR, STDIN을 통해서 생성되는 로그들은 전부 수집되어서 분석하거나 trouble-shooting을 가능하게 해준다.
  • 그뿐만 아니라, 실행되고 있는 docker container의 shell에 접속해서 interact할 수도 있다.