[Docker] 가상머신, 하이퍼바이저, 도커 전체 개념

J_Coder·2025년 1월 15일

Docker

목록 보기
1/4
post-thumbnail

5줄 요약

  1. 도커를 사용하면 개발 환경을 구축하기 편하다.
  2. 도커를 사용하면 별도의 스테이징 서버 인스턴스를 안 파도 된다.
  3. 도커를 사용하면 협업에서 개발 환경을 통일할 수 있다.
  4. 도커를 사용하면 배포하고 관리하기 편하다.
  5. 가상 머신과 컨테이너는 다르다.

학습 배경

  • Linux에 대해 선행적으로 알고 있어야 이해하기 쉽다.

학습 계기

  • 요즘 개발에서 Docker는 기본 소양이 된 것 같고, Docker를 이용한 배포 경험자를 찾는 취업 공고들을 봐서 Docker를 제대로 학습해보고자 작성한다.

  • 네이버 부스트 캠프에서 만든 최종 프로젝트 🎋Denamu의 인프라 아키텍처를 바꿔야했다.
    API 서버의 인스턴스를 바꿔야 했어서 다시 환경을 구축하기에는 많은 비용이 지출될 것이라고 판단했다.
    다음에 또 서버 환경을 바꿔야할 수도 있기 때문에 컨테이너로 관리하면 서버 이전하는 데 편리할 것이라 생각했다.

  • 만약 서비스 운영이 종료됐을 때, 포트폴리오로 사용할 수 있게 하려면 최소한 도커로 만들어둬야겠다고 생각했다.

  • 프론트엔드 분들이 API 요청을 메인 서버에 요청하여 동작을 테스트 하는 문제가 있었다.
    스테이징 서버나 개발 서버를 따로 생성하려 했지만, 의미없는 인스턴스 비용이 지출될 것이라 판단했다.

  • 개발 환경이 바뀌었을 때, ex) 데스크톱 -> 노트북 환경 셋팅하는 데 꽤 시간이 걸렸다. MySQL, Redis 구축 등

  • 서버 수평 확장을 했을 때 서버를 관리하기 위해 오케스트레이션 툴을 사용하면 편하지 않을까?라는 생각이다.

  • 컨테이너를 통한 CI/CD, 무중단 배포 블루 그린 전략을 학습해보고 싶었다.


가상 머신(Virtual Machine)

  • 정의: 가상화의 한 종류로 물리적 하드웨어를 소프트웨어로 가상화한 환경을 의미한다.

간단하게 말한다. 윈도우, 맥 같은 운영체제 안에 운영체제 설치해서 동작시키기다.
더 간단하게? 컴퓨터 안에 컴퓨터다.
마트료시카같이 인형 안에 인형이 있다고 생각하면 된다. 컴퓨터 안에 컴퓨터가 있다.

이렇게 되어 있으면 나는 윈도우를 사용하다가, Linux 운영체제가 필요하면 소프트웨어로 만들어진 컴퓨터 한 대를 만들고 그 안에 Linux를 설치하여 사용하면 윈도우로 게임을 하면서 Linux에 필요한 내용을 개발할 수 있다.

이런식으로 사용이 가능하다.
이 화면을 보면 컴퓨터 안에 컴퓨터가 무슨 말인지 알 것이다.

지금 이 화면은 윈도우 라는 Host OS(주인 OS) 위에 Ubuntu라는 운영체제가 Guest OS(자식 OS)로 동작하고 있는 것이다. 내가 Ubuntu Guest 운영체제를 종료한다 해서 내 진짜 본체는 꺼지지 않는다.
그냥 하나의 프로그램이라 생각하면 된다.

가상 머신은 이런 Guest OS를 돌리는 컴퓨터다. 얘도 소프트웨어다. 즉, 가상머신 안에서 Guest OS가 돌아가는 것이다.

가상 머신은 운영체제나 하이퍼바이저라는 녀석 위에서 돌아가는 하나의 머신이다.
가상 머신이기에 소프트웨어로 구현되어 있고, CPU, 메모리, 디스크, 네트워크 인터페이스를 갖춘 독립적인 컴퓨터처럼 동작한다.

하나의 물리적 하드웨어(진짜 컴퓨터 부품들 CPU, 메모리, 디스크 등) 위에 여러 개의 가상 머신이 실행되기에 하드웨어가 망가지는 게 아닌 이상 서로 영향을 주지 않는다.

필요성

왜 필요할까?
나는 윈도우를 사용한다. 하지만, 서비스 프로덕션(운영) 환경에서는 클라우드 서비스를 이용해서 서버 컴퓨터 OS를 우분투(리눅스 배포판)로 사용한다. 그리고 리눅스 운영체제가 필요할 때가 있다. (학습, 개발 등등...) 그럴 때마다 운영체제를 직접 내 PC에 설치해서 운영을 해야 할까?

정말 비효율적이다.

컴퓨터 끄고 리눅스 설치되어 있는 저장 장치로 부팅 우선 순위 바꾸고, 윈도우 필요하면 또 다시 똑같은 짓을 반복해야 한다.
그리고 A라는 서비스를 직접 설치되어 있는 리눅스에서 작업하다가, B 서비스에 대한 리눅스 환경이 필요하면 운영체제를 날리고 다시 설치해야 한다. 정말 정말 귀찮다.

그래서 필요한 것이 가상화를 통해 가상 머신들을 구축하는 것이다. 이러면 필요할 때마다 가상 머신의 전원을 켜면 되고, 필요 없어진 가상 머신은 지워버리면 된다. 필요하면 바로 만들어버리면 된다.

컴퓨터를 복사하는 신이 되는 거다. 내 마음대로 컴퓨터 만들기

가상 머신 종류

호스트형 가상화 (가상화 타입2)

가상화 타입 2를 먼저 설명하는 이유는?
이미 위에서 사례를 들어버려서, 먼저 설명하는 게 맞다고 생각했다.

밑에서 부터 차근 차근 보겠다.
컴퓨터는 현실 세계에 있는 만질 수 있는 컴퓨터 하드웨어들이다.
Host OS(메인 OS)는 나는 Window를 사용하고 있다.
그리고 HyperVisor 라는 녀석이 있다. 얘는 가상 머신을 실행하고 관리하는 소프트웨어, 펌웨어다.

HyperVisor 위에 VM(n) 묶음들은 가상 머신(Virtual Machine)이다.
나는 Virtual Machine을 Oralce VM Virtual Box로 만들었다.

이미지에 있는 목록이 Virtual Machine 들이다.
Oracle Virtual Box는 소프트웨어 내에서 HyperVisor가 포함되어 있다.
윈도우 Hyper-V를 켜지 않아도 되지만, 다른 Virtual Machine 컨트롤 하는 소프트웨어들은 안 될수도 있다.

윈도우 OS에 있는 Hyper-V는 이렇게 켤 수 있다.

만약 체크하는 곳이 막혀있다면 메인보드 바이오스에서 가상화 옵션을 켜줘야 한다. SVM Mode 옵션 위치가 바이오스마다 다르니 다른 블로그 게시글을 참고해주길 바란다.

+ 윈도우 Hyper-Visor를 켰을 때 그래픽카드 성능 저하가 있다는 이슈를 발견했다.
게임 프레임 드랍이 있을 수도 있다고...? 내 게임 티어 꼴이 왜 이런가 싶으면 Hyper-V를 켜놨다는 거로 정신 승리하면 되겠다.
2012년에 발생한 이슈라는데, 2022년까지도 RTX 4090 사용자들에게서 발생했다니 나도 한 번 측정해보고 포스팅 해봐야겠다. 재밌는 걸 찾았다.

+ Oracle Virtual Box를 사용하면 Window Hyper-V를 꺼도 된다고 한다. Oracle Virtual Box는 자체 HyperVisor가 존재한다고 한다. 위에 게임 프레임 드랍이 있을 수 있다니 일단은 끈다. 안드로이드 앱 개발할 때 켰었는데, 이젠 안 하니 꺼도 되겠다. 끄고도 진짜 돌아간다. 여러 블로그 포스팅들을 보니 오히려 Window Hyper-V를 켰다가 Virtual Machine이 안 돌아가는 문제를 겪는 사람들도 있는 것 같으니 한 번 꺼보고 다시 시도해보도록 하자.

베어메탈형 가상화 (가상화 타입1)

호스트형 가상화에서 HostOS 계층만 빠진 방식이다.
호스트 OS 없이 직접 하드웨어 위에서 실행되는 하이퍼 바이저다.

호스트 운영 체제를 거치지 않고 물리적 서버의 하드웨어와 직접 상호작용하기 때문에 성능이 더 우수하다.

VMware ESXi라고 하는 유명한 녀석이 있다. 이것을 이용해서 대학교 연구실 NAS 서버와 블로그 서버가 구축되어 있었다.

호스트형 vs 베어메탈형

특성호스트형 하이퍼바이저베어메탈형 하이퍼바이저
성능운영 체제와 자원 공유로 인한 오버헤드성능이 좋다.
보안운영 체제의 보안 취약점운영 체제 취약점이 없어 안전하다.
적용 환경대규모 데이터 센터, 클라우드 서비스, 고성능 컴퓨팅 환경개발, 테스트, 소규모 가상화 환경

하이퍼바이저(Hypervisor)

대충 하이퍼바이저가 무슨 역할을 하는 기능인지 감이 올 것이다.

  • 정의: 가상화를 관리하는 소프트웨어, 펌웨어
  • 역할: 하드웨어 자원을 가상 머신에 분배하고 관리. 여러 가상 머신들이 물리적인 하드웨어 위에서 동시에 실행되도록 허용하는 역할

컨테이너

🚨 컨테이너 = Docker 라고 생각하는 경우가 있는데, 컨테이너와 Docker는 다른 것이다.🚨
컨테이너는 Docker가 나오기 한참 전에 나온 기술이다. Docker는 애플리케이션 컨테이너를 동작할 수 있도록 관리하는 툴일 뿐이다. 그러니 Docker라는 단어를 잠깐 빼고 생각하자.

  • 정의: 컨테이너는 운영체제 안에서 소프트웨어를 실행하는 환경을 가상화하는 방식의 일종이다. 운영체제의 커널은 동일하지만, 격리된 환경에서 애플리케이션을 실행한다.

컨테이너는 1979년 chroot(change root)를 발표로 프로세스의 루트 디렉토리를 변경하는 방식으로 프로세스가 액세스 할 수 있는 디렉토리를 제한하는 용도로 사용됐을 뿐, 네트워크, 프로세스 등은 컨트롤할 수 없었다.

2000년 Unix OS인 FreeBSD에서 OS 가상화 기능을 발표하며 컨테이너의 시작을 알렸다.

컨테이너는 시스템 컨테이너, 애플리케이션 컨테이너가 존재한다.

시스템 컨테이너

  • 정의: 하드웨어 가상화 없이 운영체제를 실행하여 다수 프로세스가 같은 환경을 공유

VM과 애플리케이션 컨테이너 그 사이 어딘가

LXC(Linux Containers)라는 시스템 컨테이너를 운용할 수 있는 기술이 존재하고, Docker의 기반이었다. 현재는 runC라는 기술을 기반으로 한다.

하나의 컨테이너 내에서 여러 프로세스를 실행하고 전체 운영 체제를 제공하는 역할을 한다.

커널 수준에서 격리가 이루어지는 것이라 VM 처럼 운영체제를 바꾸는 행위는 불가능하다.

애플리케이션 컨테이너

  • 정의: 특정 애플리케이션이나 서비스 실행을 위한 환경을 제공

하나의 컨테이너 내에서 하나의 애플리케이션을 실행하는 것을 권장한다.

대표적으로 이번 포스팅에 설명할 Docker라는 엔진이 있다.


VM vs Container

VM

장점

  • 완전한 격리성을 갖춘다. 독립적인 운영 체제와 커널을 갖추고 있다. Virtual Machine 간에 완전한 보안 격리가 제공된다.
  • 다양한 운영 체제를 한 컴퓨터에서 실행할 수 있다.

단점

  • 무겁다. Container는 이미 돌아가고 있는 OS위에 돌리기에 빠르게 돌아가지만, VM은 별도의 운영체제를 돌려야 한다.
  • 부팅이 느리다. OS도 켜야해서 부팅할 때 느리다.
  • 각 VM이 독립적인 커널을 가져야 하기에 자원 낭비가 발생할 수 있다.

Container

장점

  • VM에 비해 OS를 안 돌려도 돼서 가볍다. 단순 프로세스를 껐다 켜는 수준이라 빠르다.
  • OS를 안 돌려도 돼서 집적도를 높일 수 있다.

단점

  • 호스트 OS의 커널을 공유하기에 VM보다 보안 격리가 약하다.
  • 호스트 OS에 의존한다.

Docker

  • 정의: 도커는 컨테이너 기반의 가상화 플랫폼으로 애플리케이션 컨테이너 관리하는 툴이다.


리눅스를 기반으로 만들어져 있기에 리눅스에서 돌릴 수 있다. 윈도우 같은 경우 WSL을 사용하여 Docker 엔진을 돌릴 수 있다.

업계 표준이 되어서 Docker = 컨테이너라고 생각하는 사람들이 있다.
아무튼 컨테이너를 관리해주는 엔진이다.

이미지

  • 정의: 컨테이너를 만들기 위한 형식이다.

불변성을 띄고 있어서 이미지 자체를 바꿀 수는 없다. 기존 이미지를 기반으로 새로운 이미지를 생성해야 한다.

Docker 이미지는 여러 계층으로 구성된다.
계층 구조를 가지고 있어서, 특정 계층이 바뀌었을 경우 그 계층만 빌드하면 되기에 빌드 속도를 개선할 수 있다.

이미지 파일을 프로젝트 안에 넣고 Build 할 경우 프로젝트 파일들을 캡쳐한 상황이 이미지로 만들어진다.
어디서든 컨테이너를 실행할 경우 만들어진 이미지의 명령어들을 수행한다.

볼륨

  • 정의: 컨테이너 내부의 데이터를 외부와 링크시켜준다.

컨테이너를 삭제하면 작업했던 데이터가 모두 삭제된다.

DB를 삭제하고 다시 DB 컨테이너를 만들면 그 내부 데이터는 전부 삭제된 상태다. 이때 다시 만든 DB 컨테이너와 기존 DB에 연결되어 있던 볼륨을 링크시켜주면 다시 데이터들이 복구가 된다. 볼륨은 컨테이너와 독립적으로 존재하여 데이터의 영속성을 지키는 역할을 한다.

Docker Hub

  • 정의: 이미지들을 저장, 공유, 관리할 수 있는 클라우드 기반 레지스트리 서비스

https://hub.docker.com/
에 접속하면 Docker Hub에 접근이 가능하다.
Docker에서 공식적으로 지원하는 이미지들도 있고, 개인이 올려둔 이미지들이 있다.

레지스트리

Git의 Repository 랑 비슷하다고 생각하면 된다. 이미지의 버전 관리를 할 수 있는 것으로 이미지를 Push, Pull이 가능하고 버전을 태그로 관리한다.

Docker 응용

도커가 아니더라도 컨테이너를 왜 사용하는지 알아보자.
위에서도 독립적인 프로세스 환경을 제공한다 했는데, 이게 왜 필요할까?

개발할 때, 개발 환경 구축을 뚝딱할 수 있다.
예를 들어보자.

  • 클라우드에 운영(프로덕션) 서버를 동작시키고 있는 상황에 추가적인 기능 개발을 해야한다.

  • 기능 개발한 게 불안정 할 수 있기에 프로덕션 서버에 바로 적용했다가는 사용자들이 떠나갈 수 있다.

  • 스테이징 서버(모의 서버)를 구축하기에는 별도의 인스턴스 비용이 발생할 것이다.

  • 그렇다고 내 PC에 DB를 설치할 필요가 크게 없는데 DB를 설치하는 것은 낭비고 찝찝하다.

  • Docker 이미지로 안 만들어져있다면 프로젝트 레포지토리를 pull해서 의존성 설치하고, 환경변수 넣고 여간 귀찮은 일이 아니다.

  • 혹여나 환경이 안 맞으면 돌아가지 않을 수도 있다.

  • 서버를 하나 더 증축한다 하면 Docker 이미지만 Pull해서 컨테이너로 돌리면 끝이다.

  • 평소 PC로 작업하다가 노트북 같은 새로운 개발 장비가 들어오면 여기에 환경 구축을 할 때 상당히 오래 걸린다. 이때 Docker를 사용하면 간편하게 옮길 수 있다.

컨테이너 관리 툴로 Podman이라는 귀여운 물개도 있으니 참고바란다.
Docker만이 있는 건 아니지만 시장을 너무 점유해서 Docker가 표준이 됐다.


컨테이너 오케스트레이션

  • 정의: 컨테이너 여러 개를 관리하는 도구

애플리케이션 컨테이너 같은 경우 1 컨테이너 = 1 애플리케이션을 권장한다.
서비스를 만들때 서버만 해도 최소 DB, API 서버 하면 2개의 애플리케이션이라 2개의 컨테이너를 생성해야 한다.

매번 2개의 컨테이너를 수동적으로 관리하기에는 쉽지 않다.
그리고 한 프로젝트에서 나온 애플리케이션들이기에 한 번에 관리하는 게 편하지 않을까?

또한, 컨테이너끼리는 네트워크를 공유하지 않기 때문에 별도의 네트워크를 도커에서 만들어줘야 하는데, 오케스트레이션을 사용할 경우 네트워크 설정도 가능해진다.

서버를 수평 확장으로 여러 개 증설했을 때 분산된 컨테이너들을 모아서 관리도 해준다.

즉, 수동으로 컨테이너들을 관리하는 것은 비효율적이기에 이것들을 자동화할 수 있게 하는 역할을 한다.

대표적으로 Kubernetes가 존재한다. 그리고 Docker Swarm, Docker Compose 등이 있다.


결론

간략하게 컨테이너 생태계를 알아봤다.

컨테이너가 있음으로써 개발 환경 구축을 할 때 많은 비용이 들지 않을 것 같다.
나도 컴퓨터 포맷하고 윈도우 다시 설치하면 Docker 컨테이너로 개발 환경을 구축해서 메인 OS에 최대한 영향을 안 끼치게 해야겠다.

앞으로는 이번 포스팅에서 설명한 내용에 대해 더 자세하게 설명하거나 관련있는 포스팅을 할 예정이다.

profile
컴퓨터 분야를 가리지 않고 즐기는 백엔드 개발자 지망생입니다.

0개의 댓글