이 그림 많이 보신 적 있으시죠?
Host OS위에 하이퍼바이저(Hypervisor)가 존재하고 있습니다.
그렇다면 하이퍼바이저는 뭘까요?
하이퍼바이저는 가상 머신을 생성하고 구동하는 프로그램입니다.
Virtual Machine(VM)이라 불리는 가상 머신은 물리적 컴퓨터의 디지털 버전입니다. 컴퓨터 공학에서 Virtual, 가상이라는 단어는 소프트웨어와 같은 개념입니다. Machine은 보통 CPU 자원을 뜻할 때 사용하지만 여기서는 컴퓨터 자체를 얘기합니다. 그래서 가상머신은 프로그램 및 운영체제를 실행하고, 데이터를 저장하고, 네트워크에 연결하고, 기타 컴퓨팅 기능을 수행합니다.
이제 아시겠죠? 가상 머신을 생성한다는 것은 기존의 컴퓨터 위에 새로운 컴퓨터를 만드는 개념입니다. 어떻게 이게 가능할까요? 그것은 하이퍼바이저가 기존 Host System으로부터 자원을 할당받기 때문입니다.
하이퍼바이저가 가상 머신을 생성하기 위해서는 Host System으로부터 적절한 자원 즉 CPU, RAM, HDD등을 할당받고 완전히 격리된 환경을 사용하게 됩니다. 그 곳에서 하이퍼바이저는 적절히 분배한 자원에 설치하고 싶은 OS를 이용하여 VM을 생성하고 구동합니다. 사용자는 하이퍼바이저를 이용해 설치한 OS에 접속하여 완전히 다른 컴퓨터처럼 이용할 수 있습니다.
예를 들어 철수는 Linux 환경에서만 돌아가는 애플리케이션(ex.Apache HTTP Server)을 실행하고 싶습니다. 하지만 철수의 Host OS는 아쉽게도 Windows이죠. 그래서 철수는 하이퍼바이저를 설치하여 손쉽게 Linux 가상 머신을 만들 수 있습니다. 기존의 컴퓨터에서 사용하는 자원을 VM에게 분배해주면 Linux가 잘 돌아가서 애플리케이션을 실행할 수 있는 것이죠. 하지만 용량이 좋지 않은 컴퓨터를 사용하는 철수는 이 VM 때문에 많은 시스템 자원을 잃었습니다.
그래서 철수는 Docker를 사용하기로 마음먹었습니다.
Apache HTTP Server는 크로스 플랫폼을 지원하지만 리눅스에 최적화된 기능을 사용하기 때문에 리눅스에서 사용하는 것이 실용적이다.
도커는 컨테이너를 실행할 수 있는 Container Runtime 중 가장 유명한 오픈 소스 플랫폼입니다. Container Runtime이요? 그게 뭔가요?
컨테이너는 가상화 기술 중 하나로 컨테이너 이미지가 실행될 때 Host OS로부터 보장받은 격리된 공간을 제공해주는 기술입니다.
참고: 격리된 공간을 보장받는 방법은 리눅스의 cgroups와 namespace들을 이용하는 것이다. 간략히 말해서 cgroups는 프로세스들을 그룹으로 나누는 기술이고 namespace를 이용하면 컴퓨터 자원들의 범위를 논리적으로 구분할 수 있다.
컨테이너 이미지는 컨테이너를 실행하기 위한 파일과 설정 등을 모아 놓은 패키지입니다. 즉, 컨테이너가 실행되기 위해 필요한 모든 것을 포함하고 있습니다. 따라서 다른 의존성을 설치할 필요가 없습니다.
컨테이너 이미지는 보통 Docker Hub과 같은 이미지 레지스트리에 저장됩니다. 사용자는 이미지 레지스트리에서 이미지를 검색하거나, 이미지를 업로드하고 다운로드하여 사용할 수 있습니다.
컨테이너 런타임은 컨테이너를 실행하는 데 필요한 도구와 라이브러리를 포함하는 소프트웨어입니다. 즉 컨테이너 실행환경입니다.
컨테이너 런타임에는 가장 유명한 Docker, 그리고 Containerd, CRI-O등이 있다.
컨테이너를 사용하는 이유 중 하나는 개발환경과 운영환경의 통일입니다. 개발환경, 테스트환경, 배포환경에서 Container Runtime만 가지고 있으면 같은 실행 환경을 유지할 수 있습니다. 마치 다른 OS에서 jvm만 가지고 있다면 java 프로그램을 실행할 수 있는 것 처럼요! 키워드는 호환성과 이식성입니다.
컨테이너를 사용하는 또 다른 이유는 철수가 Docker를 사용하는 이유에 있습니다.
Docker같은 컨테이너 런타임은 HostOS의 커널 및 시스템 자원을 공유합니다. 즉 애플리케이션 실행을 위해 새로운 컴퓨터를 설치할 필요가 없다는 것이죠. 한 컨테이너가 실행되려면 Host System의 자원을 커널에게 요청하고 적절한 자원을 할당 받아 컨테이너를 실행합니다. 그리고 컨테이너가 중단되면 시스템 자원을 반납합니다. 따라서 하이퍼바이저를 이용해 애플리케이션에 접근할 때보다 훨씬 가볍고 빠릅니다. 하이퍼바이저 오버헤드가 없기 때문입니다.
하이퍼바이저 오버헤드란, 가상화를 위해 하이퍼바이저가 처리해야 하는 추가적인 작업으로 인해 발생하는 성능 저하를 의미한다. 하이퍼바이저가 가상 머신에 CPU, 메모리, 디스크 등의 자원을 할당하고, 가상 머신 간의 통신을 관리하면서 추가적인 계산과 I/O 작업을 처리해야 하기 때문에 오버헤드가 발생한다.
그림에서도 오른쪽이 훨 가벼워 보이지 않나요?
그런데 Docker는 Linux기반으로 만들어졌고 Linux에서 구동됩니다. 그러면 Windows 운영체제인 철수는 어떻게 Docker를 사용할까요?
정답은 Docker Desktop을 사용하면 됩니다.
Windows환경에서 Docker Desktop을 설치하면 Docker Desktop이 Hyper-V 가상화 기술을 이용해 Linux Kernel(즉 VM)을 설치하고 도커를 구동할 수 있게 만듭니다. 여기서 설치하는 VM은 하이퍼바이저가 설치하는 VM 보다 자원이용량이 적습니다. 도커 엔진을 실행하기 위핸 최소한의 환경만 제공하는 것이죠. 이렇게 구동된 도커 엔진에서 리눅스 기반 앱의 이미지를 실행시킬 수 있는 것입니다.
Docker Desktop은 Windows 및 macOS 시스템에서 Docker를 설치하고 실행할 수 있는 공식적인 소프트웨어입니다. Docker Desktop을 사용하면 로컬 개발 환경에서 쉽게 Docker 컨테이너를 만들고 실행할 수 있습니다.
다운로드: https://www.docker.com/products/docker-desktop/
자 이제 철수가 Apache HTTP Server를 실행하는 절차를 알아봅시다.
이렇게 Docker Desktop은 Windows 운영체제와 Linux 가상 머신 간의 자원 관리를 수행하면서, 안정적인 컨테이너 실행 환경을 제공합니다. 이를 통해 Windows및 MacOS 운영체제에서도 Linux용 애플리케이션을 실행할 수 있게 됩니다.
또한 Docker Desktop은 쿠버네티스 클러스터를 지원해주는 기능도 있습니다.
재밌는 사실은 Docker Desktop을 이용해 쿠버네티스 클러스터를 이용하고 실제로 container runtime은 도커를 사용하지 않아도 된다는 것입니다.
오늘은 HyperVisor부터 Docker Desktop까지 제가 공부한 내용을 정리해보았습니다. 오타나 틀린 내용은 댓글로 지적해주시면 감사하겠습니다.
이미지 출처
참고