왜 도커(Docker)가 필요한가?

taeheeyoon·2022년 6월 16일
19

DevOps

목록 보기
1/2
post-thumbnail

시작하며

안녕하세요. 도커에 대해 들어본 적이 있으신가요?
아마 자주 사용하시는 분부터 아직 들어본 적 없는 분까지 있을 것으로 예상이 되는데요.
이번 글에서는 제가 도커를 공부하면서 알게되었던 지식을 공유드리고자 합니다. 저도 배우는 입장이기 때문에 댓글로 피드백 주시면 감사하겠습니다. 그럼 도커의 탄생배경부터 시작하겠습니다.

컨테이너 기술과 Docker의 탄생 배경

부산항, 인천항과 같은 무역항에 방문해 본 적이 있나요? 가장 흔히 볼 수 있는 풍경 중 하나는, 대형 트럭이 컨테이너를 싣고 부두를 왔다 갔다 하는 장면일 겁니다. 이러한 컨테이너는 대형 화물선에 실려서 다른 무역항으로 이동합니다.

컨테이너라는 게 생긴 뒤로, 물류에는 혁신이 일어났습니다. 컨테이너가 있기 전엔 어떻게 물자를 날랐을까요? 한국 전쟁 당시의 사진을 한번 보세요. 컨테이너의 장점이 보다 뚜렷해집니다.

사진으로 짐작할 수 있듯, 컨테이너는 장점이 많습니다.

  • 물자를 싣고 내릴 때에, 선박이 입항해 있는 시간을 획기적으로 단축시켜준다
  • 물자를 싣고 내릴 때 필요한 인력(분류하는 사람, 짐 옮기는 사람, 감독하는 사람)을 대폭 감소시킨다
    개발자들은 이와 같이 물자의 수송에 획기적인 단축을 가져다 준 컨테이너 기술을 "소프트웨어 수송, 즉 배포에 사용할 수는 없을까?" 하는 생각을 하기 시작했습니다. 그 결과로 리눅스 컨테이너(lxc)라는 것을 만들어내기에 이르렀습니다.

리눅스 컨테이너 기술은 그 자체로 훌륭하고 완성된 기술이었지만, 애플리케이션을 쉽게 컨테이너화할 수 있는 생태계 혹은 커뮤니티가 없었습니다. 2013년에 등장한 도커(Docker)는 바로 Docker Hub라는 소프트웨어 저장소와 함께 빠르게 성장했고, 그 결과 개발자들은 쉽게 애플리케이션을 포장하고, 컨테이너 방식으로 실행할 수 있게 되었습니다.

"컨테이너 방식으로 애플리케이션을 실행한다"라는 개념이 아직은 잘 와닿지 않을 수 있습니다. 컨테이너 기술의 장점은 한마디로 얘기하면 다음과 같습니다.

실행 환경에 구애받지 않고 애플리케이션을 실행할 수 있다!

이는 달리 얘기하면, 애플리케이션 실행이 어떠한 환경에 구애를 받는다는 말입니다.

Docker 컨테이너의 특징

1. 의존성 충돌 문제를 해결해 준다

어떤 애플리케이션은, 해당 애플리케이션을 실행하기 위해 반드시 어떤 환경이 구축되어 있어야 합니다. 쉽게는 윈도우용 프로그램을 실행하려면 윈도우 운영체제가 필요하듯 말입니다.

윈도우에서 어떤 애플리케이션을 설치하다보면, .NET Framework를 설치해야 한다는 문구를 종종 볼 수 있습니다.

우리는 이와 같이 어떤 프로그램(A) 실행에 다른 프로그램(B)이 반드시 필요한 경우, "프로그램 A는 프로그램 B에 의존 관계를 가지고 있다"고 말합니다.

자, 그런데 말입니다, 이러한 경우도 있습니다.

예를 들어, 워드프레스(wordpress)라는 프로그램이, php라는 프로그램에 대해 의존 관계를 가질 때에, 특정 php 버전을 요구하는 경우가 생길 수 있습니다.

그런데 동일한 컴퓨터에 php를 반드시 필요로 하는 drupal이라는 프로그램을 실행시켜야 하는데, 만일 drupal이 php 7 버전이 아닌 6 버전을 사용할 때에만 제대로 작동한다고 가정해 봅시다.

일반적으로 한 컴퓨터에 여러 버전의 동일한 애플리케이션이 설치되지 않으므로, 이 경우에는 php의 의존 관계를 가지고 있는 다른 두 애플리케이션 중에 하나는 제대로 된 실행을 보장할 수 없습니다.

이런 상황을 우리는 "의존성이 충돌한다"라고 말합니다.

컨테이너 기술은 바로 이 문제를 해결합니다. 컨테이너 기술은 애플리케이션을 컨테이너 내에 구성합니다. 즉, 컨테이너에서 실행 중인 애플리케이션은 어떠한 의존성도 공유하지 않고, 각자 고유의 의존성을 포함하고 있다는 이야기입니다.

이는 각 컨테이너가 철저하게 실행 환경이 격리되어 있기 때문에 가능한 것입니다.

컨테이너는 무엇을 격리하나요?

컨테이너 기술을 바탕으로 한 컴퓨터 안에 여러 대의 컨테이너가 존재하고, 이를 통해 애플리케이션 실행 환경이 격리되어 있음을 앞서 배웠습니다.

하나의 컴퓨터 내에 서로 다른 버전의 php가 설치될 수 있는 것은, 컨테이너 하나하나가 애플리케이션 실행과 관련해서 격리를 제공하기 때문입니다.

실생활에서의 컨테이너를 활용한 코로나19 격리 병동

그렇다면, 컨테이너는 무엇을 격리하고, 어떤 자원들을 독립적으로 소유할까요? 다음 세 가지를 기억하세요.

  1. 프로세스
  • 특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 액세스할 수 있습니다.
  • 컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에게 영향을 줄 수 없습니다.
  1. 네트워크
  • 컨테이너에 사용자가 임의로 IP 주소를 n개만큼 할당할 수 있습니다.
  • 자기만의 네트워크 영역을 가집니다. 영역이 고유하므로 동일한 IP를 각 컨테이너마다 부여할 수 있습니다. 예를 들어 A컨테이너에 192.168.1.10, B컨테이너에 192.168.1.10을 할당할 수 있습니다.
  • 컨테이너는 고유한 네트워크영역이라는 특성때문에 외부와 통신할 때 포트포워딩이라는 기술을 사용합니다. 컨테이너가 외부와 통신하려면 공유기 포트포워딩 처럼 컨테이너 포트포워딩 기능을 사용합니다.
  1. 파일 시스템
  • 컨테이너 안에서 사용되는 파일 시스템은 컨테이너마다 격리되어 있습니다. 그래서 컨테이너끼리의 파일 시스템이나 명령은 서로 영향을 주지 않습니다.

컨테이너는 가상 머신인가요?

이러한 기술을 어디선가 보신 분도 있을 겁니다. 바로, 가상 머신(Virtual Machine, 이하 VM)입니다. 하나의 호스트(주인) 컴퓨터 위에 여러 개의 독립적인 컴퓨터가 작동할 수 있게 하는 기술입니다. 이러한 애플리케이션으로는 VMware, VirtualBox, Parallels 등이 있습니다.

사실, 도커를 비롯한 리눅스 컨테이너 기술은 가상 머신의 접근 방법과는 조금 다릅니다. 지금은, 컨테이너 역시 가상 머신과 비슷한 수준의 격리성을 제공한다는 정도만 알고 넘어가도 좋습니다.

2. 개발과 배포 환경을 일치시킨다

개발팀의 문제

Node.js나 Python 등을 이용하여 웹 서비스를 개발하는 개발팀을 상상해 봅시다. 여러 개발자가 하나의 애플리케이션을 만들기 위해, 보통 비슷한 개발 환경을 구축하기 마련입니다.

특정 버전 이상의 Node.js, 특정 버전의 MySQL 등을 개발자 각자가 본인의 운영체제에 설치하고, 그 후에 개발을 진행합니다. 하지만 보통의 경우 그 과정이 빠르게 진행되지 않습니다.

애플리케이션을 실행시키기 위해 OS나 Node.js나 Python과 같은 런타임 환경의 버전을 얼추 비슷하게 맞춰야 하는 것은 물론이고, 시스템 환경 변수를 애플리케이션에 맞게 구성해야 제대로 작동하는 경우도 종종 볼 수 있습니다.

리눅스만 하더라도, 배포판에 따라 전혀 다른 애플리케이션 설치 과정이 진행됩니다.

환경 구축 과정 중에 발생하는 사소한 실수나 사전 설치 항목의 부재는 문제 해결에 많은 시간을 소모하게 합니다. 특히 새로운 프로젝트에 투입되는 개발자의 경우, 그저 애플리케이션을 돌리고 싶었을 뿐인데, 그 길까지 가는 과정이 매우 험난합니다.

도커는 이러한 문제를 해결해 줍니다. 도커가 실행 중이라면, 어떠한 운영체제든 상관없이 같은 명령어로 즉시 환경을 구축하고 실행할 수 있습니다.

Docker compose를 사용하면 명령어 단 한줄로 여러개의 도커 컨테이너를 동시에 실행할 수 있습니다. 예를 들어 프론트엔드 개발자라면 백엔드, DB를 명령어 단 한줄만으로 로컬 환경 구축이 완료됩니다.

따라서 도커는 다음 문제를 해결할 수 있습니다.

  • OS에 상관없이 즉시 애플리케이션 실행 환경을 만들 수 있습니다.
  • 개발을 컨테이너 위에서 진행할 경우, 모든 개발팀이 동일한 환경 하에 개발을 진행할 수 있습니다.

배포 시의 문제

앞서 설명한 실행 및 개발 환경의 일치 이슈는 서비스 배포 환경에서도 동일하게 적용될 수 있습니다. 웹 서비스의 배포란 "어떤 애플리케이션이 특정 런타임 환경 위에서 실행되고, 사용자에게 이를 제공한다"는 것인데, 이는 앞서 말한 실행 환경 구성과 본질적으로 다를 것이 없기 때문입니다. 그저 서비스를 인터넷상에 공개적으로 노출하느냐, 내 컴퓨터 상에서 프라이빗하게 작동하느냐의 차이일 뿐입니다.

그래서 이제는 배포의 패러다임이 달라졌습니다. 앞서 보았던 선박 그림 기억하시나요? 서버에 파일 하나하나를 업로드하는 방식은 마치 물자를 하나하나 배에 옮기는 이전의 방식이라고 볼 수 있습니다. 서버도 이제는 컨테이너에 담긴 애플리케이션을 실행하는 방식으로 서비스를 제공합니다.

따라서 Amazon Web Service의 EC2 상에 도커를 설치하거나, 또는 좀 더 편리하게 도커 컨테이너를 EC2 서버에서 실행할 수 있게 하는 서비스인 ECS를 이용하여 보다 쉽게 애플리케이션을 배포할 수 있습니다.

3. 수평적 확장과 배포가 쉬워진다.

우리가 매일같이 사용하는 글로벌 웹 서비스는 전 세계인들이 사용하므로 그 트래픽이 어마어마합니다. 예를 들어, 지금 이 시간에도 전 세계의 수많은 사람들이 google.com 에 접속할 텐데, 과연 수많은 사람들이 검색 서버라는 단 하나의 컴퓨터에 접속하고 있는 것일까요?

그렇지 않습니다. 서비스 제공자들은 이러한 트래픽 분산을 위해 프록시 서버를 운영하며, 프록시 서버는 여러 대의 동일한 검색 서버 중 한 군데를 이용할 수 있도록 돕습니다. (이러한 서버를 리버스 프록시의 한 종류인 '로드 밸런서'라고 부릅니다)

"동일한 서비스가 여러 컴퓨터에서 작동한다"라는 말에서 도커의 필요성을 느꼈다면 이미 여러분은 도커를 이해하고 있는 겁니다.

컨테이너 기술의 가장 큰 장점은 실행 환경의 일치입니다. 더 많은 트래픽으로 인한 서버 증설에 컨테이너 기술은 아주 활발하게 이용되고 있습니다. 동일한 애플리케이션 구성(이미지)을 바탕으로 새로운 서버에 해당 애플리케이션을 컨테이너로 실행하고, 로드 밸런서에 이 서버를 추가하기만 하면 됩니다. (심지어 AWS는 서버를 만들고 삭제하는 일을 자동으로 해줍니다!)

이러한 기술을 응용하여, 새로운 버전의 애플리케이션을 여러 서버 중 몇 대에만 운영하여 테스트하는 방법도 가능합니다. 이를 통해 새 버전의 애플리케이션에서 발생할 수 있는 문제들을 미리 확인하고, 이러한 문제가 사용자 전체에게 영향을 끼치지 않도록 만들 수도 있습니다.

쿠버네티스와 같이 "오케스트레이션 도구"라고 부르는 것들이 이러한 일을 해주는 도구입니다. 이는 결국 컨테이너 기술 덕분에 가능한 것입니다.

Docker 용어 정리

컨테이너

컨테이너는 앞서 설명한 대로, 애플리케이션이 의존성, 네트워크 환경, 파일 시스템에 구애받지 않고, 도커라는 기술 위에 실행될 수 있도록 만든 애플리케이션 상자입니다.

이미지

실행되는 모든 컨테이너는 이미지로부터 생성됩니다. 이미지는 애플리케이션 및 애플리케이션 구성을 함께 담아놓은 템플릿으로, 이를 이용해 즉시 컨테이너를 만들 수 있습니다.

이미지를 이용해 여러 개의 컨테이너를 생성할 수 있습니다. 이를 이용해 앞서 설명한 애플리케이션의 수평 확장이 가능합니다.

이미지는 기본 이미지(base image)로부터 (마치 git을 사용하는 것처럼) 변경 사항을 추가/커밋해서 또 다른 이미지를 만들 수도 있습니다. 예를 들어 node.js로 작성된 애플리케이션을 이미지로 만들고 싶은 경우, nodejs 이미지를 기본 이미지로 삼고 내가 만든 애플리케이션을 추가해 넣고, 이미지화할 수 있습니다.

Node.js 웹 앱의 도커라이징(컨테이너화)

도커라이징(Dockerizing)은, 애플리케이션을 도커 컨테이너에서 돌릴 수 있도록 이미지로 만드는 과정을 의미합니다. 도커라이징이라는 말보다는 컨테이너화 라는 말이 훨씬 많이 쓰입니다.

다음은 node 및 express를 이용한 단순한 앱을 컨테이너화 하는 튜토리얼입니다. 한번 따라해보세요 :)

Node.js 웹 앱의 도커라이징

레지스트리

이미지는 레지스트리에 저장됩니다. 대표적인 이미지 레지스트리로는 Docker Hub, Amazon ECR이 있습니다. 도커 CLI에서 이미지를 이용해 컨테이너를 생성할 때, 호스트 컴퓨터에 이미지가 존재하지 않는다면, 기본 레지스트리로부터 다운로드 받게 됩니다.

마치며

도커의 탄생 배경과 간단한 개념, 용어에 대해 알아보았습니다. 다음 글에서는 이번 글에 이어서 컨테이너와 VM의 비교에 대한 글을 보충해서 올릴 생각입니다. 읽어주셔서 감사합니다.

Reference

www.docker.com
Docker란 무엇입니까?
컨테이너화란?
Node.js 웹 앱의 도커라이징
docker docs

profile
생각하는 대로 살지 않으면, 사는 대로 생각하게 된다.

1개의 댓글

comment-user-thumbnail
2022년 6월 25일

좋은 글 감사합니다!

답글 달기