왜 Docker인가?

Numberbeen·2023년 1월 2일
0

DevOps Bootcamp

목록 보기
25/30

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

컨테이너

컨테이너의 장점

  • 물자를 싣고 내릴 때에, 선박이 입항해 있는 시간을 획기적으로 단축시킨다.
  • 물자를 싣고 내릴 때 필요한 인력을 대폼 감소시킨다.

개발자들은 이와 같이 물자의 수송에 획기적인 단축을 가져다 준 컨테이너 기술을 "소프트웨어 수송, 즉 배포에 사용할 수 없을까?" 하는 생각을 하기 시작했다. 그 결과로 리눅스 컨테이너(lxc)라는 것을 만들어 냈다.

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

도커를 한마디로 말하자면

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

왜 Docker인가? (1)

컨테이너 방식의 장점

  1. 👉 의존성 충돌 문제를 해결해준다.
  2. 개발과 배포 환경을 일치시킨다.
  3. 수평 확장을 쉽게 해준다.
  4. 각 서버에 새로운 내용을 배포하기 쉽게 만들어준다.

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

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

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

어떤 자원들을 독립적으로 소유할까요? 다음 세 가지를 기억하자.

  1. 프로세스
  • 특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 액세스 할 수 있다.
  • 컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에게 영향을 줄 수 없다.
  1. 네트워크
  • 기본적으로 컨테이너 하나에 하나의 IP 주소가 할당되어 있다.
  1. 파일 시스템
  • 컨테이너 안에서 사용되는 파일 시스템은 구획화 되어있다. 그래서 해당 컨테이너에서의 명령이나 파일 등의 액세스를 제한할 수 있다.

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

이러한 기술을 어디선가 본거 같다. 바로 가상머신(VM) 이다. 하나의 호스트 컴퓨터 위에 여러 개의 독립적인 컴퓨터가 작동할 수 있게 하는 기술이다.

사실 도커를 비롯한 리눅스 컨테이너 기술은 가상 머신의 접근 방법과는 조금 다르다.
자세한 내용은 다음 챕터에서 다루고 지금은, 컨테이너 역시 가상 머신과 비슷한 수준의 격리성을 제공한다는 정도만 알고 넘어가도 좋다.

왜 Docker인가? (2)

컨테이너 방식의 장점

  1. 의존성 충돌 문제를 해결해준다.
  2. 👉 개발과 배포 환경을 일치시킨다.
  3. 수평 확장을 쉽게 해준다.
  4. 각 서버에 새로운 내용을 배포하기 쉽게 만들어준다.

개발팀의 문제

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

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

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

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

💡 도커는 이러한 문제를 해결해 준다. 도커가 실행 중이라면, 어떠한 운영체제든 상관없이 같은 명령어로 애플리케이션을 설치하고 실행할 수 있다.

지금은 단일 소프트웨어 패키지 하나의 사례를 들었지만, 애플리케이션 구성 자체가 컨테이너화되면 (이때 보통 Docker Compose라는 툴을 이용) YAML 파일 하나 + 명령어 하나로 모든 애플리케이션 실행 환경 구성이 완료된다.

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

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

배포 시의 문제

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

그래서 이제는 배포의 패러다임이 달라졌습니다.

서버에 파일 하나하나를 업로드하는 방식은 마치 물자를 하나하나 배에 옮기는 이전의 방식이라고 볼 수 있습니다. 서버도 이제는 컨테이너에 담긴 애플리케이션을 실행하는 방식으로 서비스를 제공한다.

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

왜 Docker인가? (3)

컨테이너 방식의 장점

  1. 의존성 충돌 문제를 해결해준다.
  2. 개발과 배포 환경을 일치시킨다.
  3. 👉 수평 확장을 쉽게 해준다.
  4. 👉 각 서버에 새로운 내용을 배포하기 쉽게 만들어준다.

이 콘텐츠는 웹 서비스의 인프라스트럭처에 대한 이해를 바탕으로 합니다. 지금 당장 모든 내용을 이해할 필요는 없지만 가볍게 읽어보자.

수평 확장과 새로운 내용의 배포는 한꺼번에 묶어서 설명합니다.

우리가 매일같이 사용하는 글로벌 웹 서비스는 전 세계인들이 사용하므로 그 트래픽이 어마어마하다.

예를 들어, 지금 이 시간에도 전 세계의 수많은 사람들이 google.com 에 접속할 텐데, 과연 수많은 사람들이 검색 서버라는 단 하나의 컴퓨터에 접속하고 있는 것일까?

그렇지 않다.

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

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

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

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

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

Docker 핵심 키워드

컨테이너

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

이미지

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

이미지를 이용해 어러 개의 컨테이너를 생성할 수 있으며, 이를 이용해 앞서 설명한 애플리케이션의 수평 확장이 가능하다.

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

레지스트리

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

컨테이너와 VM의 비교

컨테이너 기술과 가상머신(VM) 은 둘 다 프로세스, 네트워크, 파일 시스템을 격리할 수 있다는 장점을 공유하지만 이 둘의 작동원리는 많이 다르다.

VM을 사용해본 경험이 있다면, VM을 만들고 실행하는 과정이 많은 컴퓨팅 자원을 필요로 한다는 점을 체감하였으리라 생각된다. 이에 비해, 도커는 한 호스트 컴퓨터에 여러 개의 컨테이너를 띄워도 크게 컴퓨터에 무리가 가지 않는다.

또 하나의 특징은, Docker Hub Registry를 통해 이미지를 살펴보면, 도커 이미지는 (운영체제 이미지도 존재하지만) 보통 애플리케이션 단위로 만들어져 있음을 알 수 있습니다. 반면 VM을 사용하기 위해서는 해당 VM 위에 운영체제(OS, Operating System)를 설치해야 하는 과정을 반드시 거치게 되어 있다.

왼쪽의 VM의 구성 요소에 OS가 존재하는데 비해, 오른쪽의 도커 컨테이너에는 OS를 포함하고 있지 않다. 다만, 도커라는 플랫폼 위에 컨테이너들이 올라가 있고, 그 아래 호스트 OS가 존재한다.

이를 통해, 각 컨테이너는 호스트 OS의 커널(Kernel, 시스템 콜과 같이 OS의 핵심 기능을 구현한 프로그램)을 공유하고 있음을 짐작할 수 있다.

도커는 애플리케이션을 컨테이너화해서 실행하는 데에 주 목적이 있으므로, 특별히 컨테이너에 OS를 올려서 사용하지 않는다. 호스트 OS의 입장에서 컨테이너 하나는 프로세스 하나에 불과하다.

컨테이너에 OS를 올리지 않는데, Docker Hub에 존재하는 각종 OS 이미지는 무엇인가?

잘 알려진 리눅스 배포판인 우분투, CentOS 등은 결국 동일한 리눅스 커널 위에서 만들어진 것. 각자가 고유의 디렉토리 구조, 패키지 시스템(apt, yum), 쉘(bash, zsh) 등을 사용했을 뿐입니다. OS 이미지는 컨테이너 내 애플리케이션 구성의 편의를 위해 존재하는 이미지이며 우분투, CentOS 이미지를 사용한다고 해도 결코 컨테이너에 커널 수준의 OS가 올라가지 않는다.

하이퍼바이저는 VM을 생성하고 구동하는 소프트웨어를 의미. 하이퍼바이저에도 유형이 다양하게 존재하지만, 지금은 일단 VMware, VirtualBox 와 같은 프로그램이 하이퍼바이저라는 것 정도만 알아도 충분하다.

윈도우나 macOS용 도커를 살펴보면 컨테이너 안쪽은 리눅스로 작동되는데 윈도우나 macOS는 리눅스가 아닌데, 어떻게 컨테이너 안에서 리눅스 기반으로 작동하는 것인가?

윈도우나 macOS는 근본적으로 리눅스 커널을 쓰고 있지 않으므로, 해당 운영체제의 경우 리눅스 커널을 VM의 형태로 실행시키는 하이퍼바이저(Hyper-V, LinuxKit, HyperKit)를 자체적으로 구동합니다. 윈도우용 또는 macOS용 도커는 하이퍼바이저 위의 리눅스 커널을 사용하는 것입니다.

한가지 재미있는 것은 윈도우용 도커는 윈도우 커널을 사용한 윈도우 전용 컨테이너를 실행할 수 있는 기능을 제공하며 컨테이너는 커널을 공유하므로, 윈도우 커널을 사용하는 컨테이너는 리눅스용 도커에서 사용할 수 없다.

profile
내기 이해한 것을 보관하는 곳

0개의 댓글