‘Docker란 무엇인가’가 무엇인지 모르겠다

Gyu·2022년 4월 15일
5
post-thumbnail

‘Docker란 무엇인가’가 무엇인지 알겠는데 모르겠다.

몇 년 전부터 도커는 핫한 기술이었으며, 지금은 거의 업계 표준이 되면서 개발자라면 필수로 알아야할 기술이 되었습니다. 이직 준비를 공부를 하기 위해 도커에 대해 검색 해보니, 아래의 내용들을 알 수 있었습니다.

  • 도커는 리눅스의 컨테이너라는 기술(LXC)를 이용한 소프트웨어로 지금은 자체 라이브러리인 libcontainer를 사용하고있다.
  • 도커를 이용하면 개발환경에 구애받지 않고 손쉽게 내가 사용하던 개발환경을 구축할 수 있다.
  • 도커는 일반적인 Hypervisor 가상화 방식과는 다르게 경량 가상화로 실행이 빠르다. 그로 인해 한 개의 서버만 있으면 여러개의 서비스 실행이 가능해지므로 불필요한 서버 확장이 필요없다.
  • 도커를 이용하면 배포가 쉽고 수정도 쉽다.

하지만 리눅스의 ㄹ도 모르는 비전공 주니어 프론트 개발자인 저는 “컨테이너...? 가상화....? 무슨 말인지 알겠는데 무슨 말인지 모르겠다...” 였습니다. 이 글은 저와 같이 도커를 공부해보려고 하는데 도커란 무엇인가 챕터부터 이게 뭔 말인지 정확히는 모르겠고 느낌적인 느낌만 알 것 같은 분들을 위해 작성되었습니다.

리눅스와 리눅스 컨테이너

저처럼 리눅스의 ㄹ도 모르는 분들은 도커를 알기위해서 먼저 리눅스가 뭔지 부터 알아야합니다. 왜냐하면 도커는 리눅스의 컨테이너라는 기술를 이용한 소프트웨어이기 때문입니다. 그럼 리눅스와 리눅스 컨테이너가 뭔지부터 간단히 살펴 보겠습니다.

리눅스(Linux)란?

리눅스란 가장 대표적인 오픈 소스 운영체제입니다. 운영체제(Operating System)는 크게 PC에서 돌아가는 운영체제와 서버에서 사용되는 운영체제가 있습니다. PC에서 사용되는 운영체제에는 윈도우, MacOS, 리눅스가 있고, 서버에 사용되는 운영체제로는 윈도우즈서버, 리눅스, 유닉스가 있습니다. 리눅스는 PC와 서버에서 둘 다 사용되지만 서버에서 더 많이 사용되고 있습니다.

리눅스는 핀란드 컴퓨터 공학과 학생이던 리누스 토발즈에 의해 개발되었습니다. 리누스 토발즈는 유닉스에 관심이 많았는데, 유닉스 운영체제를 모델로하며 유닉스 시스템의 작은 버전인 미닉스보다 좋은 운영체제를 만들자는 목표를 두고 1991년 0.01버전으로 새로운 운영체제를 개발하고 본인의 이름을 따서 리눅스라고 이름을 지었습니다. 리누스 토발즈는 리눅스 첫 공식 버전인 0.02는 1991년 10월에 발표한 후 전 세계 많은 개발자와 전문가들의 도움을 받아 지속적으로 리눅스 개발을 진행하게 되었습니다.

리누스 토발즈는 커널이라 불리는 리눅스 핵심 부분만 작성하여 배포했으며, 일반적으로 사람들이 이야기하는 리눅스는 리누스 토발즈가 개발한 커널에 컴파일러, 셀, 기타 응용 프로그램들이 조합된 배포판을 말합니다. 리눅스는 폐쇄적인 유닉스와 다르게 누구든지 자유롭게 프로그램을 변경하여 유동시킬 수 있는 프리웨어입니다. 때문에 다양한 회사나 개발자가 만든 다양한 배포판이 존재합니다. 한 번쯤 들어봤을 우분투, 페도라, CentOS도 수 많은 배포판 중 하나입니다.

리눅스에 대한 자세한 설명은 여기를 참고하세요.

💡 커널(Kernel)이란?
사전적 의미로"알맹이, 핵심"이라는 뜻으로, 컴퓨터 운영체제에서 커널은 운영체제의 핵심부로 CPU, 메모리, 파일, 네트워크, 입출력 장치 등의 컴퓨터 자원을 관리하는 프로그램을 말합니다.

자세한 설명은 여기를 참고하세요.

컨테이너 탄생 배경

리눅스는 여러 명의 사용자에 의한 동시 접근을 허용하는 멀티유저(다중사용자) 운영체제입니다. 즉 리눅스에서는 많은 사람들이 동시에 한 컴퓨터를 사용하는게 가능하다는 뜻입니다.

리눅스 사용자는 크게 root 사용자(시스템 운영 관리자, Super User)와 일반 사용자(Normal User, Guest User)로 구분하고, 일반 사용자의 경우 로그인 가능 사용자와 로그인은 불가하지만 시스템의 필요 때문에 생성된 시스템 계정으로 나뉩니다.

일반적으로 리눅스 콘솔창에서 'ls /' 명령어를 입력하면 루트 디렉토리에 대한 목록이 나옵니다. 하지만 일반 사용자가 입력할 경우, 관리자가 사용자에게 어떤 권한을 주느냐에 따라 달라지게 됩니다. 접근이 될 수도 있고, 안 될 수도 있는 거죠. 만약 관리자가 사용자에게 접근을 허용하지 않게 되면, 많은 제약이 따릅니다. 이러한 제약을 좀 더 유연하면서 보안도 유지되는걸 고민해서 탄생한 것이 chroot 입니다. chroot를 사용하게 되면 일반 사용자에 한해서 기본 root디렉토리가 변경됩니다.

만약 관리자가 사용자에 대하 chroot로 루트 디렉토리를 /home 디렉토리로 변경하고 사용자가 'ls /' 명령어를 입력하면, 터미널에 다음과 같이 표시됩니다.

'Guest@ : ls /'
/home

즉 일반 사용자 입장에서의 root 디렉토리는 /home 디렉토리가 되는 것입니다.

chroot를 사용하면 루트디렉토리만 바뀌는 것 뿐만 아니라 관리자가 chroot를 설정하면서 설정한 루트 디렉토리(/home) 아래에 사용자가 필요로 하는 참조하는 파일을 제공할 수 있게 됩니다. 이로인해 사용자는 서버의 불필요한 접근을 할 필요 없이 자신의 일만 수행하면 됩니다. 때문에 보안을 유지하면서 사용자에세 유연성을 제공하는 것이 가능해졌습니다. chroot는 대부분의 리눅스에서 설정이 가능하지만 설정이 까다롭습니다. 이 개념을 기반으로 2001년 VServer Project를 통해 리눅스에 격리된 공간이 구축되었으며 이것이 발전해 컨테이너로 탄생하게 됩니다.

컨테이너란?

위와 같은 배경으로 만들어진 컨테이너는 리눅스의 namespace와 cgroup 이 두 가지 기능을 기반으로 만들어집니다.

namespace

namespace는 동일한 시스템에서 별개의 독립된 공간을 격리된 환경에서 운영하는 가상화 기술입니다. 아파트가 각 호실별로 격리된 주거환경을 제공하는 것과 비슷한 개념으로 생각하면 됩니다. namespace로 격리된 프로세스들은 같은 컴퓨터 안에 존재하지만 격리 되어있기 때문에 서로 간섭할 수 없습니다.

namespace를 이용하면 하나의 시스템에서 동일한 PID가 두 개인것처럼 프로세스를 만들 수 있습니다. 즉 PID가 같아도 서로 다른 프로세스가 되는 것이죠.

이렇게 격리된 프로세스는 다음 6개가 독립적으로 존재할 수 있다는 특징을 갖고있습니다.

  1. mnt (파일시스템 마운트): 호스트 파일시스템에 구애받지 않고 독립적으로 파일시스템을 마운트하거나 언마운트 가능
  2. pid (프로세스): 독립적인 프로세스 공간을 할당
  3. net (네트워크): namespace간에 network 충돌 방지 (중복 포트 바인딩 등)
  4. ipc (SystemV IPC): 프로세스간의 독립적인 통신통로 할당
  5. uts (hostname): 독립적인 hostname 할당
  6. user (UID): 독립적인 사용자 할당

cgroup

namespace는 CPU나 메모리 등의 물리적 자원을 제한하지 않습니다. 때문에 격리된 프로세스에 하드웨어 자원을 배분하기 위해서는 cgroup이라는 기능을 사용해야 합니다.

cgroup은 control group의 약자로 하드웨어 자원을 배분하는 기능을 수행합니다. cgroup를 사용하면 CPU, RAM 등의 자원을 사용자가 원하는 만큼 격리된 프로세스에 할달 해줄 수 있습니다. 이렇게 할당하게되면 컴퓨터 성능을 좀 더 효율적으로 사용할 수 있으며, 추후 컨테이너에 올라가는 응용프로그램마다 필요에 따라 자원을 더 할당할 수 있습니다.

이렇게 namespace와 cgroup으로 만들어진 컨테이너를 LXC(LinuX Container)라고 부릅니다. LXC를 사용하면 독립된 공간의 프로세스 위에 사용자가 원라는 기능을 올릴 수 있게됩니다. 가령 사용자가 원하는 OS를 올리고 해당 OS에 JAVA서버, node.js, DB 등을 올리는 작업을 말이죠.

Docker의 탄생 배경

전통적인 서버 운영 방식

일반적으로 서버를 관리하는 일은 매우 복잡하고 어려운 작업입니다. 사실 저는 프론트 개발자라 잘 모르지만 그렇다고 합니다. 예전에는 데이터센터나 서버실에 서버를 두고 직접 관리하던 온프레미스(On-premise) 방식으로 서버를 관리했습니다. 이러한 방식에서 서버에 OS를 설치하고 서버를 세팅하는 일은 쉬운 일이 아니었습니다. 또한 하나의 서버에 여러 개의 프로그램을 설치하는 경우 서로 사용하는 라이브러리의 버전이 다르거나 동일한 포트를 사용하는 경우 설치가 매우 까다로웠습니다.

때문에 전통적인 방식에서는 주로 하나의 서버에 하나의 운영체제, 하나의 프로그램을 운영했습니다. 이렇다보니 각 서버가 갖고 있는 시스템 자원 중 약 50~70% 정도만 사용할 수 있었습니다. 즉, 물리적 서버가 갖고 있는 성능을 100% 활용해서 사용할 수 없었습니다. 또한 프로그램이 늘어날 수록 서버가 늘어날 수 밖에 없었습니다. 서버를 구입하고 운영하는 데에 많은 비용이 소모되는데, 그런 서버가 늘어나는데 서버의 성능을 100% 활용하지 못한다는 것은 기업 입장에서 큰 손해였습니다. 때문에 기업은 자신들이 갖고 있는 물리적 서버를 최대한 효율적으로 사용하길 원했고, 각 서버가 100%의 성능을 발휘할 수 있길 원했습니다.

가상화

도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다. 그런데 여기서 말하는 가상화란 정확히 뭘까요? 전통적인 서버 운영 방식을 먼저 설명드린 이유는 모두 가상화를 설명하기 위한 나름의 빅픽쳐(밑밥)이었습니다.

위에서 설명한 것처럼 기업은 서버 운영을 효율적으로 하기 위해 한 대의 물리적인 서버를 마치 여러 대의 서버처럼 활용하거나, 여러 서버를 하나의 서버처럼 묶어서 사용하기를 원했고 이로 인해 등장한 기술이 "가상화"입니다.

가상화는 가상화를 관리하는 소프트웨어(주로 Hypervisor)를 사용하여 프로세서, 메모리, 스토리지 등과 같은 단일 컴퓨터의 하드웨어 요소를 일반적으로 가상 머신(VM, Virtual Machine)이라고 하는 다수의 가상 컴퓨터로 분할할 수 있도록 해주는 컴퓨터 하드웨어 상의 추상화 계층을 구축하는 기술을 말합니다. 실제 기반 컴퓨터 하드웨어의 단지 일부에서만 실행됨에도 불구하고, 각각의 VM은 자체 운영체제(OS)를 실행하며 마치 독립적인 컴퓨터인 것처럼 작동합니다.

💡 추상화란?

일반적으로 컴퓨터를 사용할 때 여러 사용자를 등록하여 사용할 수 있다. 이렇게 여러 사용자를 등록해서 사용할 때, 각 사용자는 마치 자신이 하나의 하드웨어를 독점하여 활용하는 것처럼 느끼게된다. 이처럼 하나 뿐인 하드웨어를 마치 여러 개인 것처럼 보여지도록 하는 기술을 추상화하고 한다.

예를들어 각각 용도가 다른 3개의 물리 서버가 있다고 합시다. 하나는 메일 서버이고, 다른 하나는 웹 서버이고, 나머지 하나는 내부 레거시 애플리케이션을 실행하는 서버입니다. 각 서버는 잠재적인 실행 용량의 일부에 불과한 30% 용량만 사용하고 있습니다. 그러나 내부 운영을 위해서는 레거시 애플리케이션이 계속 필요하므로 레거시 애플리케이션과 이를 호스팅하는 세 번째 서버를 유지해야 합니다.

전통적으로는 위의 방식을 따릅니다. 1개의 서버와 1개의 운영 체제, 1개의 태스크와 같이 개별 서버에서 개별 태스크를 실행하는 것이 더 쉽고 안정적인 경우가 많습니다. 1개의 서버로 여러 개의 태스크를 처리하기란 쉽지 않았습니다. 그러나 가상화를 사용하면 메일 서버를 2개의 고유한 서버로 분할해 독립적인 태스크를 처리하고 레거시 애플리케이션을 마이그레이션할 수 있습니다. 마찬가지로 하드웨어도 더 효율적으로 사용할 수 있습니다.

보안을 고려하여 첫 번째 서버를 다시 분할해 다른 태스크를 처리하면 사용률을 30%에서 60% 또는 90%까지도 높일 수 있습니다. 이렇게 하고 나면 이제 빈 서버를 재사용해 다른 태스크를 처리하거나 모든 서버를 사용 중지해 냉각 및 유지관리 비용을 줄일 수 있습니다.

*사진 출처 : https://www.redhat.com/ko/topics/virtualization/what-is-virtualization

가상화에 대한 자세한 설명은 여기를 참고하세요.

가상화 발전 과정

전통적인 배포방식, 가상화로된 배포방식 그리고 컨테이너 방식 이렇게 세 가지를 비교하여 가상화의 발전과정에 대해 알아보겠습니다.

전통적인 배포 방식

  • 하나의 물리 서버에 애플리케이션을 배포하는 방식입니다.
  • 애플리케이션 간 라이브러리나 미들웨어 버전의 충돌이 발생할 수 있습니다.
  • 한 물리 서버에서 여러 애플리케이션의 리소스 한계를 정의할 방법이 없었기에, 리소스 할당의 문제 발생합니다.
  • 물리 서버 하나에서 여러 애플리케이션을 실행하면, 리소스를 과다 사용하는 애플리케이션이 다른 애플리케이션의 성능이 저하를 유발합니다.
  • 서로 다른 여러 물리 서버에서 각 애플리케이션을 실행하는 것은 리소스가 충분히 활용되지 않으며, 많은 유지 비용이 듭니다.

가상화를 이용한 배포 방식

  • Host OS(실물 컴퓨터에 설치된 OS) 위에 가상화 소프트웨어(Hypervisor)를 설치해서 가상환경을 구축합니다.
  • VM간에 애플리케이션을 격리하고 애플리케이션의 정보를 다른 애플리케이션에서 자유롭게 액세스 할 수 없으므로, 일정 수준의 보안성을 제공합니다.
  • 리소스를 보다 효율적으로 활용할 수 있으며, 쉽게 애플리케이션을 추가하거나 업데이트할 수 있고 하드웨어 비용을 절감할 수 있어 더 나은 확장성 제공합니다.
  • 간편하게 사용할 수 있어 클라이언트 PC에서 개발환경을 구축하거나 테스트를 위해 주로 사용합니다.
  • 가상환경에 Guest OS(VM에 설치된 OS)를 통째로 올입니다. OS는 용량도 많이 차지하고, 사용자가 사용하지 않는 불필요한 기능도 많습니다. 게다가 OS 자체가 무겁고 잡아먹는 자원이 많이 때문에 느리다는 치명적인 단점이 있습니다. (컨테이너와 다르게 비교적 오버헤드가 크다.)
  • OS 위에 OS를 실행하는 것이므로 리소스(CPU, 메모리 등)를 할당하는 작업이 필요합니다.

💡 오버헤드(overhead)란?

어떤 처리를 하기 위해 들어가는 간접적인 처리 시간 · 메모리 등을 말한다. 예를들어, 10초 걸리는 기능이 간접적인 원인으로 20초걸린다면 오버헤드는 10초가 되는것이다. 오버헤드는 반드시 존재한다. 다만 이 오버헤드를 줄이는 것이 좋다.

컨테이너 방식

  • 컨테이너는 컨테이너 실행을 담당하는 소프트웨어인 컨테이너 런타임이라는 게 존재하고, 컨테이너 런타임 위에 Guest OS 없이 애플리케이션이 올라갑니다.
  • 컨테이너에서 OS가 실행되긴 하지만 사용자가 사용할 응용프로그램만 작동되도록 정말 최소단위만 올라갑니다. 때문에 컨테이너에서 실행되는 OS의 커널 크기가 작고 빠르다. 또한 Guest OS가 없기 때문에 OS 실행 없이 별도의 환경에서 애플리케이션 실행이 가능합니다.
  • 서버 한대에서 여러 기능을 하는 응용프로그램들, 소위 마이크로서비스식 서버를 구축할 수 있으며, 기존 서버 커널 하나로 모든 컨테이너들의 관리가 가능하므로 관리도 쉽습니다.

서버 관리 방식의 변화와 Docker의 등장

시간이 흐르면서 서버의 환경은 계속 바뀌었습니다. CentoOS에 익숙해지면 우분투를 써야하는 일이 생기고, AWS에 익숙해지면 Azure를 써야하는 일이 생깁니다. 무슨 말인지 정확히 모르겠지만 어떤 기술에 익숙해질만하면 새로운 기술을 써야하는 상황이 생긴다고 이해하면 될 것 같습니다. (이건 모든 개발자들의 숙명인듯...)

그러던 중 DevOps라는 것이 등장합니다. DevOps는 development(개발)'와 'operations(운영)'가 합쳐진 단어어로, 개발팀과 운영팀 간의 프로세스를 자동화하고 통합하는 일련의 관행, 도구 및 문화적 철학입니다. 무슨 말인지 알겠는데 무슨 말인지 모르겠죠? 과거 설치 기반 프로그램이 대부분이던 시절에는 서비스 패치를 위해 몇 달간의 작업 후 배포하는 방식을 사용했습니다. 그런데 점점 웹기반 서비스로 바뀌고 한국인의 빨리빨리 정신이 깃든 애자일 방법론이라는 것에 관심이 많아 지면서 빈번한 배포가 필요해졌습니다. 하지만 개발팀은 서비스 개발에 매진하고, 운영팀은 보안과 안정적인 인프라 구축에 집중을 하므로 빈번한 배포가 어려웠습니다. 때문에 빈번한 배포 전략을 위해 두 팀이 병합되어 개발, 테스트, 배포, 운영에 이르는 애플리케이션 수명주기를 개발하게 되는데 이를 데브옵스라고합니다.

DevOps에 대한 자세한 내용은 여기를 참고하세요.

또한 MSA(Micro Service Architecture)라는 것이 유행하기 시작합니다.(제발 그만 유행해...) MSA는 서비스간의 의존성을 없애고 기능을 쪼개는 것을 중점적으로 설계한 아키텍처입니다. 예를 들어, 은행 시스템을 하나의 통합된 프로그램으로 개발하지 않고… 입/출금 서비스, 조회 서비스, 대출 서비스 등 기능별로 작게 쪼개서 MSA 형태로 되어 있다고 가정하겠습니다. 이 때 새로운 대출 유형이 생겨 개발이 필요하면, 은행 시스템 전체를 수정할 필요 없이 대출 서비스의 수정만으로 작업을 경량화 할 수 있습니다. 이로 인해 서비스 단위 개발이 가능하고 지속적인 통합과 배포(CI/CD)를 효율적으로 할 수 있기 때문에 서비스간 결합도를 줄이고 응집도를 높일 수 있다는 장점이 있지만, 서비스들을 관리하기 복잡하다는 단점이 있습니다.

MSA가 유행하면서 프로그램을 잘게 쪼개어 버리게 되고 이로인해 관리가 더 복잡해졌습니다. 새로운 툴은 계속해서 나오고 클라우드의 발전으로 설치해야 할 서버가 수백, 수천대에 이르는 노답 상황에서 리눅스의 컨테이너라는 기술(LXC)를 이용하며, 컨테이너 기반의 오픈소스 가상화 플랫폼인 도커가 등장합니다. 이로 인해 서버 관리 방식이 완전히 바뀌게 됩니다.

리눅스 컨테이너와 Docker 컨테이너의 차이점

도커는 처음에는 생성, 관리, 배포 등 컨테이너 관련 작업을 효율적으로 하기 위해 리눅스 컨테이너 기반으로 만들어졌습니다. 하지만 도커가 곧 리눅스 컨테이너가 아닙니다. 맨 처음에 언급했듯이 현재 도커는 LXC 기반이 아닌 자체 라이브러리인 libcontainer를 사용하고 있습니다. 이는 도커가 좀 더 Docker Engine에 맞게 실행되게 하기 위함입니다.

도커와 LXC의 차이점을 통해 도커에 대해 좀더 알아보겠습니다.


*사진 출처 : https://www.redhat.com/ko/topics/containers/what-is-docker

컨테이너에 실행 가능한 애플리케이션 개수

LXC는 하나의 컨테이너에 여러 개의 애플리케이션을 띄울 수 있지만, 도커는 하나의 컨테이너에 하나의 애플리케이션을 사용하기를 권장하고 있습니다. 컨테이너당 애플리케이션을 하나씩 띄워 놓으면 다음과 같은 장점이 있습니다.

  • 다른 프로젝트에서 쉽게 재사용 가능
  • 보안 및 격리 관점에서 더 많은 유연성을 가져올 수 있음.
  • 업데이트 시 서로간의 간섭을 받지 않음
  • 마이크로서비스 아키텍처를 구성하는것에 대해 효율적이다.

스냅샷 기능

LXC는 스냅샷 기능이 없지만, 도커는 스냅샷 기능이 있습니다. 스냅샷이란 마치 사진을 찍듯이 특정 시점에 데이터 저장 장치의 상태를 포작해 별도의 파일이나 이미지로 저장하는 기술로, 스냅샷 기능을 이용하여 데이터를 저장하면 유실된 데이터 복원과 일정 시점의 상태로 데이터를 복원할 수 있습니다.

도커에서 이 스냅샷 기능을 이용하면 구축된 환경을 이미지 파일로 저장 후 언제든지 사용할 수 있습니다. 여기서 이미지 파일은 jpg, png 같은 이미지 파일이 지칭하는 것이 아니라 도커의 최소관리 단위를 뜻하는 말로 필요한 프로그램, 라이브러리, 소스를 설치한 뒤 만든 하나의 파일을 말합니다. 이 파일은 컨테이너 실행에 필요한 모든 파일과 설정값 등을 포함하고 있으며 상태값을 가지지 않고 변하지 않습니다. 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장됩니다. 같은 이미지에서 여러 개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제 되더라도 이미지는 변하지 않고 그대로 남아있습니다.

말그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없습니다. 이제 새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성만 하면 됩니다. 한 서버에 여러 개의 컨테이너를 실행할 수 있고, 수십, 수백, 수천대의 서버도 문제없습니다. 만약 초기 셋팅을 이미지 파일로 만든 후 새로운 패키지나 업데이트를 했는데 알 수 없는 이유로 프로그램이 작동이 안된다면 초기에 만들어 놓은 이미지 파일로 쉽게 되돌아 갈 수 있습니다.

도커는 새로운 컨테이너를 구축할 때 이 이미지를 사용하므로 구축 프로세스가 훨씬 빠르고, 중간 변경 사항이 이미지 사이에서 공유되므로 속도, 규모, 효율성이 더 개선됩니다. 컨테이너의 시작과 종료가 수 초 밖에 되지 않기 때문에 도커는 컨테이너를 이미지화 시켜 배포를 쉽고 빠르게 할 수 있습니다.

게다가 도커 이미지는 깃헙같은 Docker Hub에 등록하거나 Docker Registry 저장소를 직접 만들어 관리할 수 있습니다.

Docker의 장점

모듈성

도커의 컨테이너 방식은 전체 애플리케이션을 분해할 필요없이, 애블리케이션의 일부를 분해하고 업데이트 또는 복구할 수 있게 해줍니다. 사용자는 MSA 기반 접근 방식 외에도 SOA(service-oriented architecture)의 작동 방식과 동일하게 멀티플 애플리케이션 사이에서 프로세스를 공유할 수 있습니다.

레이어 저장 방식

도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 보통 용량이 수백메가MB에 이릅니다. 처음 이미지를 다운받을 땐 크게 부담이 안되지만 기존 이미지에 파일 하나 추가했다고 수백메가를 다시 다운받는다면 매우 비효율적일 수 밖에 없습니다.

도커는 이런 문제를 해결하기 위해 레이어라는 개념을 사용하고 유니온 파일 시스템을 이용하여 여러 개의 레이어를 하나의 파일시스템으로 사용할 수 있게 해줍니다. 이미지는 여러 개의 읽기 전용read only 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생성됩니다.

예를들어 a+b+c의 집합인 도커 이미지 A가 있다고 가정할 때, 이미지 A를 베이스로 만든 이미지 B는 a+b+c+B가 됩니다. 또한 도커 이미지 C를 이미지 B를 기반으로 만들었다면, 이미지C는 a+b+c+B+C 레이어로 구성됩니다. 이미지C 소스를 수정하면 a, b, c, B를 제외한 C(v2)만 레이어만 다운 받으면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있습니다.

컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기 레이어를 추가합니다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용합니다.

신속한 배포

도커 이미지 설명할 때 언급했지만 도커기반 컨테이너는 배포 시간을 몇 초로 단축할 수 있습니다. 각 프로세스에 대한 컨테이너를 생성함으로써 사용자는 유사한 프로세스를 새 앱과 빠르게 공유할 수 있습니다. 또한, 컨테이너를 추가하거나 이동하기 위해 OS를 부팅할 필요가 없으므로 배포 시간이 크게 단축됩니다. 이뿐만 아니라 배포 속도가 빨라 컨테이너에서 생성된 데이터를 비용 효율적으로 쉽게 생성하고 삭제할 수 있고 사용자는 우려를 할 필요가 없습니다.

마무리

도커에서 가장 중요한 개념은 도커 컨테이너와 도커 이미지입니다. 이 두 개념을 정확히 몰라도 도커를 사용하는데 큰 문제는 없겠지만, 단순히 도커를 다룰 줄 아는 사람이 되기 보다는 도커를 알고 다룰 줄 아는 사람이 되고 싶었습니다. 그래서 ‘도커가 뭐지?’라는 질문이 ‘리눅스가 뭐지?’라는 질문이 되었고, 그 결과 이런 포스팅이 탄생했습니다. 저와 같은 분들이 분명히 계실거라 생각하고, 이 글이 그런 분들에게 많은 도움이 되었으면 좋겠습니다.

기회가 된다면 도커 빌드 포스팅도 작성해 보겠습니다.

참고 블로그
초보를 위한 도커 안내서 - 도커란 무엇인가?
Docker란 무엇인가? 왜 사용할까?
Linux) Doker와 Container의 탄생과 설명, 차이점
도커 Docker 기초 확실히 다지기
Red Hat - Docker(도커)란?

profile
애기 프론트 엔드 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 20일

감사합니다! 너무 잘 읽었습니다

답글 달기