Docker 기본 개념 1

변현섭·2023년 8월 30일
0

도커란 무엇인가

목록 보기
1/8
post-thumbnail

이번 시리즈에서는 Docker에 대해서 다뤄보려합니다. 도커라고 하면 누구나 한번쯤 들어봤을 법 하지만, 도커에 대해 제대로 설명할 수 있는 사람은 많지 않습니다. 그래서 이번 포스팅은 첫 포스팅인만큼, Docker에 대한 개념부터 명확히 이해하는 것을 목표로 해봅시다!

1. 개념

1) 도커와 컨테이너

도커를 한마디로 정의하면, "데이터 또는 프로그램을 격리시키는 기능을 제공하는 소프트웨어"이다. 도커는 주로 서버에서 사용되어, 서버에 설치되어 있는 다양한 프로그램과 데이터를 각각 독립된 환경에 격리시킨다.


조금 더 이해하기 쉽게 설명하자면, 서버의 환경을 마치 코스트코 매장처럼 만드는 것이다. 마치 각각의 팔레트로 물품을 격리시키는 것처럼, 데이터와 프로그램을 컨테이너에 담아 격리한다는 것이다. 그리고 이 때, 이 컨테이너를 다루기 위해 사용하는 소프트웨어가 바로 도커이다.

참고로, 도커는 리눅스 운영체제에서만 사용할 수 있기 때문에 컨테이너에서 동작시킬 프로그램도 리눅스용 프로그램이어야 한다. 물론, 윈도우나 macOS에서도 도커를 사용할 수는 있지만, 이는 내부적으로 리눅스 운영체제를 사용하기에 가능한 것이다.

2) 도커 엔진과 컨테이너 이미지

도커를 사용하려면 먼저 도커의 본체라 할 수 있는 도커 엔진을 설치해야 하는데, 이 도커 엔진이 있어야 컨테이너를 생성하고 구동할 수 있다. 그러나 엄밀히 말하면 도커 엔진만 있다고 해서 컨테이너를 생성할 수 있는 것은 아니고, 도커 엔진과 더불어 컨테이너 이미지도 있어야 한다.

여기서 이미지란, 컨테이너 생성에 필요한 모든 파일과 환경설정을 지니고 있어 별도의 설치나 의존성 추가가 필요하지 않은 상태의 파일을 말한다. EC2를 생성할 때 사용했던 AMI나, VirtualBox에 넣었던 Ubuntu 이미지가 모두 컨테이너 이미지에 해당한다.

2. 격리의 필요성

1) 격리되지 않았을 때의 문제점

도커의 핵심적인 역할은 서버 환경을 격리시키는 것이다. 그렇다면 데이터나 프로그램을 격리해야하는 이유는 무엇일까? 우리가 사용하는 대부분의 프로그램은 단독으로 동작하지 않고, 특정 실행 환경이나 라이브러리, 다른 프로그램을 이용해 동작한다.

쉬운 예시로, 연동되는 프로그램의 버전이 5.0일 때에만 제대로 구동될 수 있는 A라는 시스템이 있다고 하자. 그런데 B라는 시스템은 해당 프로그램의 버전이 8.0 이상일 때에만 사용 가능하다. 이러한 상황에서 B 시스템에 맞추어 프로그램을 업데이트한다면, A 시스템의 동작에 문제가 발생할 것이다.

당연히 연동 프로그램뿐 아니라 실행 환경, 라이브러리, 디렉토리, 설정 파일 등을 공유하는 상황에서도 한쪽 시스템에 맞추어 코드를 수정하다보면, 다른 시스템에서 예상치 못한 오류가 발생할 수 있다. 그 예시는 아래와 같다.

  • 설계할 때까지만 해도 서로 문제를 일으키지 않았지만, 실제로 설치하고나니 오류가 발생하는 문제
  • 연동 프로그램을 공유하는 시스템을 모두 고려해야하기 때문에 버전 선택에 어려움을 겪는 문제
  • 같은 디렉토리를 사용하는 시스템 간의 설정 충돌이 발생하는 문제

도커의 개념이 워낙 생소하다보니 지금까지 말한 내용이 잘 와닿지 않을 수 있다. 조금 더 쉬운 예시를 들어보겠다. 친한 친구들과 함께 한 방에서 자취를 하는 경우를 생각해보자. 밖에서 만날 때에는 큰 문제 없이 잘 지냈지만, 막상 한 공간에 같이 모여 살다보면 이런 저런 문제가 발생하게 된다.

또한 누군가의 생활 패턴에 억지로 맞추어 살다보면, 나의 생활 패턴에는 수 많은 제약이 가해질 것이다. 당연히 혼자 살 때보다 신경쓸 것도, 불편한 것도 많아진다. 이러한 문제를 해결하는 가장 간단한 방법이 무엇일까? 독립된 환경을 구축하는 것 즉, 각방을 쓰는 것이다.

2) 해결 방법

컨테이너는 다른 컨테이너와 완전히 분리되어 있기 때문에 당연히 컨테이너 안의 프로그램도 다른 프로그램과 완전히 격리된 상태이다. 그러므로 여러 프로그램이 하나의 서버에서 실행됨으로써 발생할 수 있는 대부분의 문제를 도커 컨테이너를 이용해 해결할 수 있다.

위에서 들었던 예시를 다시 생각해보자. A 시스템은 5.0 버전의 프로그램을 필요로 하고, B 시스템은 8.0 버전의 프로그램을 필요로 한다. 한 대의 서버에 두 버전을 모두 설치하는 것은 원칙적으로 불가능하다. 그러나 도커 컨테이너는 완전히 독립된 환경이므로, 여러 컨테이너에서 같은 프로그램을 설치 및 실행해도 전혀 문제가 되지 않는다. 이 때 프로그램의 버전은 컨테이너마다 같아도 되고, 달라도 된다.

이로써 위 문제에 대한 해결 방법은 너무나 명확해진다. 시스템 A와 5.0 버전의 프로그램을 A 시스템의 컨테이너로 묶고, 시스템 B와 8.0 버전의 프로그램은 B 시스템의 컨테이너로 묶으면 된다.

3) 서버 비용 절감

상황에 따라 컨테이너를 사용하여 서버 비용을 절감할 수도 있다. 원칙적으로는 한 대의 서버 컴퓨터에는 하나의 웹 서버(Apache, Nginx 등) 밖에 실행할 수 없다. 요구 사양이 별로 높지 않은 여러 개의 프로젝트가 있다고 생각해보자. 하나의 서버 컴퓨터로 여러 개의 프로젝트를 충분히 감당 가능한 상황이더라도, 단지 웹 서버를 실행하기 위한 이유로 별도의 물리 서버를 구축해야 한다.

이로 인해 고사양의 서버 컴퓨터가 있어도 제대로 활용하기 어렵고, 프로젝트마다 서버를 따로 구축해야하기 때문에 불필요한 비용 손실도 감수해야 한다. 이 때 필요한 것이 바로 컨테이너 기술이다. 컨테이너를 사용하면, 하나의 물리 서버에 여러 웹 서버를 올리는 것이 가능해지기 때문에 수 배의 비용을 절감할 수 있게 된다.

뿐만 아니라, 개발에 필요한 시간적 비용을 절감하는 데에도 큰 도움이 될 수 있다. 웹 서버를 공유하면서 생길 수 있는 수 많은 문제(예를 들어 A 프로젝트 개발자가 B 프로젝트의 환경을 잘못 건드리는 등)를 전혀 걱정하지 않아도 되기 때문에 개발 속도가 빨라질 것이다. 또한 컨테이너는 도커만 설치되어 있으면, 운영체제의 차이, 물리적 환경의 차이, 서버 구성의 차이와 전혀 무관하게 다른 곳으로 옮길 수 있기 때문에 운영 서버와 개발 서버의 환경 차이로 인해 발생할 수 있는 문제도 걱정할 필요가 없다.

3. 도커 VS 가상화

도커에 대해 설명할 때 빠지지 않고 등장하는 내용이 바로 가상화 기술과의 비교이다. 도커와 가상화 기술은 모두 컴퓨터 시스템에서 애플리케이션을 격리하고 실행하는 기술이라는 점에서는 동일하지만, 두 기술 사이에는 명확한 차이점이 존재한다.

1) 가상화 기술

먼저 VirtualBox, VMware와 같은 가상화 기술은 말 그대로 가상의 물리 서버를 만들어 내는 것이다. 여기서 "가상"이란, CPU, 메모리 등의 하드웨어를 소프트웨어로 대체한다는 의미이다. 실제로는 소프트웨어이지만, 실질적으로는 컴퓨터와 동등한 것이므로, 운영체제를 설치하거나 소프트웨어를 구동하는 것이 가능하다.

VM을 써본 적이 있다면, 아래의 그림을 쉽게 이해할 수 있을 것이다. 기존 OS(윈도우 등) 위에 하이퍼바이저를 두어 Ubuntu와 같은 Guest OS를 설치하는 방식이 아래의 구조에 해당한다.

2) 도커와 가상화 기술 비교

도커는 방금 설명한 가상화 기술을 토대로 만들어진 새로운 기술이다. 당연히 새로운 기술인만큼 차이점이 존재한다. 아래의 사진을 통해 가상화 기술과 도커의 차이점이 무엇인지 알아보자.

언뜻 보면 비슷한 구조인 듯 하지만, 눈에 띄게 다른 두 가지를 찾아볼 수 있다. 바로 HypervisorGuest OS의 유무이다. 이 두 가지의 차이점으로 인해 도커와 가상화 기술은 서로 다른 특징을 갖게 된다.

① 가상화 수준의 차이

  • 각각의 VM은 완전한 운영 체제, 커널 및 리소스를 모두 가지고 있어 무겁고 느리다는 단점이 있다.
  • 도커의 컨테이너는 호스트 운영체제(내 컴퓨터의 OS)의 커널을 공유하면서, 그 안에는 애플리케이션에 필요한 라이브러리 및 종속성만 포함되므로, 빠르고 경량적인 실행 환경을 제공한다.

② 리소스 사용 및 성능

  • 가상 머신은 완전한 운영 체제를 가지고 있어 더 많은 리소스를 소비하며, 하이퍼바이저 오버헤드로 인해 성능이 다소 떨어질 수 있다.
  • 이에 반해, 도커는 호스트 시스템의 커널을 공유하기 때문에 높은 성능을 자랑하며, 호스트와의 자원 공유로 인해 효율적인 리소스 사용이 가능하다.

    ※ Overhead
    오버헤드란, 작업을 수행하기 위해 추가적으로 필요한 시간, 자원 또는 비용을 의미한다. 주로 성능과 관련된 맥락에서 사용되며, 시스템이나 애플리케이션의 실행과 관련된 부가적인 작업이나 리소스 사용을 설명하기 위해 사용하는 개념이다. 쉽게 말해 A라는 작업을 단순하게 처리하면 10초가 걸리는데, 안전성을 고려하여 부가적인 작업을 추가한 결과 처리시간이 15초가 되었다면, 이 때의 오버헤드는 5초가 된다.

③ 이식성과 확장성

  • 가상 머신은 운영 체제를 갖고 있기 때문에 이식성이 낮으며, 배포 및 관리에 부적합할 수 있다.
  • 도커 컨테이너는 애플리케이션 및 환경의 일관성을 유지하기 때문에 이식성이 높다.

④ 보안과 격리

  • 가상 머신은 보다 강력한 격리 기능을 제공한다. 각 가상 머신이 독립적인 커널을 가지고 있어 보안 측면에서 매우 견고하다고 볼 수 있다.
  • 도커는 컨테이너 간에 격리된 환경을 제공하지만, 호스트 운영 체제의 커널을 공유하기 때문에 사실상 완전한 격리라고 보기는 어렵다. 따라서 보안 측면에서는 주의가 요구된다.

도커는 데이터 또는 프로그램을 격리시키는 소프트웨어이기 때문에, "어떻게 격리시키는지"와 "왜 격리시켜야 하는지"를 제대로 이해했다면, 도커의 이론을 거의 다 이해한 것이나 마찬가지이다.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글