Everyday Learning Sarah

Docker 핵심 개념 본문

Etc

Docker 핵심 개념

Seoha Kim 2021. 9. 4. 13:55

1. 도커를 왜 사용해야할까?

Docker는 격리된 환경에서 프로세스를 실행시키기 위해 사용하는 컨테이너 기반의 가상화 플랫폼입니다. 파이썬 패키지들에 대해서만 격리된 환경을 제공하는 Anaconda와 다르게 Docker는 VM 수준의 가상화를 훨씬 빠르고 가볍게 제공하여 어떤 OS건, 어떤 환경에서건 동일한 프로그램의 실행과 관리를 가능케합니다.

 

일반적인 VM은 하이파이저를 반드시 거치고, 게스트 운영체제를 위한 라이브러리, 커널 등을 전부 포함하기 때문에 이미지의 크기가 커집니다. VM은 완벽한 운영체제를 생성할 수 있다는 단점도 있지만, 일반 호스트에 비해 성능 손실이 있을 수도 있으며, 수 기가바이트에 달하는 가상 머신 이미지를 애플리케이션으로 배포하기에 부담스럽습니다.

 

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

 

정리하자면 도커의 장점은 다음과 같습니다.

  1. 애플리케이션의 개발과 배포가 편해집니다.
    • 도커 컨테이너 자체에 특별한 권한을 주지 않는한 호스트의 OS에는 영향을 주지 않습니다.
    • 새롭게 패키지를 설치할 필요나 각종 라이브러리 설치의 의존성을 고려할 필요 없이, '도커 이미지'를 만들어 배포하기만 해도 됩니다.
    • 커널을 포함하고 있지 않기 때문에 이미지 크기가 그다지 크지 않습니다. 이미지는 레이어 단위로 구성되며, 중복되는 레이어를 재사용할 수 있어 애플리케이션 배포 속도가 매우 빨라집니다.
  2. 여러 애플리케이션의 독립성과 확장성이 높아집니다.
    • 여러 모듈이 독립된 형태로 구성되어 언어에 종속되지 않고, 관리가 쉬워집니다.
    • 예를 들어, 웹 서비스에 부하가 발생할 시에 웹 서버 컨테이너를 동적으로 늘려서 부하를 분산할 수 있습니다.
    • 또한 웹 서비스와 데이터 베이스 이미지를 독립적으로 관리하기 때문에 유지 보수에도 용이해집니다

2. 도커 이미지와 컨테이너

Docker의 핵심 용어로 컨테이너이미지만을 언급하고 넘어가자면, 컨테이너란 격리되어 실행되는 환경의 단위로 하나의 VM과 같이 이해 가능합니다. 이미지란 해당 컨테이너가 가지는 격리된 환경 정보입니다. 즉 Anaconda와 비교하여 설명하자면

  • Anaconda의 EnvDocker 컨테이너
  • Anaconda의 config.yamlDocker 이미지

와 같이 생각하시면 쉽습니다. 다만 중요한 점은 컨테이너는 하나의 프로세스라는 점에서 파이썬 패키지들의 저장 경로를 격리함으로써 독립된 환경을 제공하는 Anaconda와 다릅니다. (Anaconda env는 프로세스가 아닙니다)

 

2.1 도커 이미지

Docker Image는 가상 머신을 생성할 때 사용하는 iso 파일과 비슷합니다. 이미지는 여러 개의 레이어로 된 바이너리 파일로 존재하고, 컨테이너를 생성하고 실행할 때 읽기 전용으로 사용됩니다. 도커에서 사용되는 이미지의 이름은 기본적으로 [저장소 이름]/[이미지 이름]:[태그] 형태로 구성됩니다.

→ 예: plask/ubuntu:14.04

  • 저장소 이름: 이미지가 저장된 장소를 의미합니다. 생략할 경우 Docker hub의 official image를 뜻합니다.
  • 이미지 이름: 해당 이미지가 어떠한 역할을 하는지를 나타냅니다. 생략할 수 없습니다.
  • 태그: 일반적으로 버전을 명시합니다. 생략할 경우 latest로 인식합니다.

도커 이미지는 여러개의 레이어로 구성되어 있으며, 이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 새로운 이미지의 실제 크기는 변경 전 이미지 크기+변경 과정에서 추가된 레이어의 크기가 됩니다. 이미지 레이어를 재사용하기 때문에 효율적으로 효율적으로 애플리케이션을 배포할 수 있습니다. 이미지를 생성했다면 도커를 배포할 방법이 필요한데 Docker Hub와 Docker Private Registry를 이용하는 방법이 있습니다.

2.2 도커 컨테이너

Docker Container는 이미지 목적에 맞는 파일을 들어있는 파일 시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간입니다. 대부분 도커 컨테이너는 생성될 때 사용된 이미지의 종류에 따라 알맞은 설정과 파일을 가지고 있기 때문에 도커 이미지의 목적에 맞도록 사용하는 것이 일반적입니다. 컨테이너를 이미지를 읽기 전용으로 사용하되 이미지에서 변경된 사항만 컨테이너 계층에 저장하므로 컨테이너에서 무엇을 하든지 원래 이미지는 영향을 받지 않습니다. 또한 컨테이너는 각기 독립되어 있으므로 특정 컨테이너에서 어떤 애플리케이션을 설치하거나 삭제해도 다른 컨테이너와 호스트는 변화가 없습니다.

 


3. 도커 볼륨

도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며 컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존합니다. 이미 생성된 이미지는 어떠한 경우로도 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일 시스템 등을 저장합니다.

그러나 해당 컨테이너를 삭제하면 컨테이너 계층에 저장되어 있던 데이터 베이스의 정보도 삭제된다는 점입니다. 도커의 컨테이너는 생성과 삭제가 매우 쉬우므로 실수로 컨테이너를 삭제하면 데이터를 복구할 수 없게 됩니다. 이를 방지하기 위해 컨테이너의 데이터를 영속적 데이터로 활용하는 방법이 있는데 Docker Volume을 활용하는 방법입니다.

Docker Volume을 사용하는 방법은 여러개가 있습니다.

  1. 호스트와 볼륨을 공유하는 방법
  2. 볼륨 컨테이너를 활용하는 방법
  3. 도커가 관리하는 볼륨을 생성하는 방

4. 도커 허브와 도커 프라이빗 레지스트리

4.1 도커 허브

Docker Hub는 maven repository와 같이 외부에 공개되어 있는 도커 이미지 레포지토리로, 도커 이미지를 위한 클라우드 서비스라고 생각하면 쉽습니다. docker pull 명령을 이용하여 컨테이너를 로컬에 받아 오거나, Docker image 빌드 시 베이스 이미지 등을 받아오는데 주로 사용됩니다. 결제하지 않으면 비공개 저장소의 수가 제한되어 있다는 단점이 있으나 공개 저장소는 무료로 사용할 수 있으므로 만든 이미지를 다른 사용자에게도 공개해도 없다면 좋은 선택입니다.

4.2 도커 프라이빗 레지스트리

Docker Private Registry는 사용자가 직접 이미지를 저장소를 만드는 방법입니다. 그러나 사용자가 직접 이미지 저장소 및 사용되는 서버, 저장 공간 등을 관리해야 하므로 도커 허브보다는 사용법이 까다롭습니다. 그러나 회사의 내부망 같은 곳에서 도커 이미지를 배포해야 한다면 도커 사설 레지스트리가 더 좋은 방안이 될 수 있습니다.


5. Dockerfile

개발한 애플리케이션을 컨테이너화할 때 가장 먼저 생각나는 방법은 아래와 같습니다.

아무것도 존재하지 않는 이미지로 컨테이너를 생성 → 애플리케이션을 위한 환경을 설치하고 소스코드 등을 복사해 잘 동작하는 것을 확인 → 컨테이너를 이미지로 커밋

이 방법을 사용하면 일일이 수작업으로 패키지를 설치하고 소스코드를 git에서 복제하거나 호스트에서 복사해야 한다는 단점이 있습니다. 직접 컨테이너에서 애플리케이션을 구동해보고 이미지로 커밋하기 때문에 이미지의 동작을 보장할 수 있다는 장점도 있습니다.

도커는 위와 같은 일련의 과정을 손쉽게 기록하고 수행할 수 있는 빌드(build) 명령어를 제공합니다. Dockerfile은 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 셸 스크립트 등을 하나의 파일에 기록해두면 도커는 이 파일을 읽어 이미지로 만들어냅니다.

도커 파일을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거로움을 덜 수 있을 뿐더러 git과 같은 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화할 수 있습니다. 또한 도커 이미지를 도커 허브에 배포하는 대신, 도커 파일을 배포할 수도 있습니다.


6. 도커 데몬

도커의 구조는 크게 두 가지로 나뉩니다. 하나는 클라이언트로서의 도커이고, 다른 하나는 서버로서의 도커입니다. 실제로 도커 서버는 실제로 컨테이너를 생성하고 실행하며 이미지를 관리하는 주체이고, 이는 dockerd 프로세스로서 동작합니다. 도커 엔진은 외부에서 API를 받아서 도커 엔진의 기능을 수행하는데, 도커 프로세스가 실행되어 서버로서 입력을 받은 준비가 된 상태를 도커 데몬이라고 이야기합니다. 도커 데몬은 API의 입력을 받아 도커 엔진의 기능을 수행하는데, 이 API를 사용할 수 있도록 CLI를 제공하는 것이 도커 클라이언트입니다.

사용자가 docker로 시작하는 명령어를 입력하면 도커 클라이언트를 사용하는 것이며, 도커 클라이언트는 입력된 명령어를 로컬에 존재하는 도커 데몬에게 API로서 전달합니다. 이때 도커 클라이언트는 /var/run/docker.sock에 위치한 유닉스 소켓을 통해 도커 데몬 API를 호출합니다.

즉, 터미널이나 PuTTY 등으로 도커가 설치된 호스트에 접속해 docker 명령어를 입력하면 아래와 같은 과정으로 도커가 제어가 됩니다.

  1. 사용자가 docker version 같은 도커 명령어를 입력합니다.
  2. /user/bin/docker는 /var/run/docker.sock 유닉스 소켓을 사용해 도커 데몬에게 명령어를 전달하빈다.
  3. 도커 데몬은 이 명령어를 파싱하고 명령어에 해당하는 작업을 수행합니다.
  4. 수행 결과를 도커 클라이언트에게 반환하고 사용자에게 결과를 출력합니다.

우분투에서는 도커가 설치되면 자동으로 서비스로 등록되므로 호스트가 재시작되더라도 자동으로 실행됩니다. 레드햇 계열의 운영체제는 도커를 설치해도 자동으로 실행되도록 설정되지는 않으므로, 따로 설정을 해주어야 합니다.

 

Comments