진행하던 프로젝트를 배포하고 성능 테스트를 하기 전에
자주 사용하던 Docker와 가상화의 개념에 대해 학습해 보기로 했다.
VM(가상머신)이란?
가상머신은 물리적 하드웨어 시스템에 구축되어 자체 CPU, 메모리, 네트워크 인터페이스 및 스토리지를 갖추고 가상 컴퓨터 시스템으로 작동하는 가상 환경이다.
Docker? VM?
도커(Docker)는 컨테이너형 가상화 기술을 구현하기 위한 상주 애플리케이션과 이 애플리케이션을 조작하기 위한 명령행 도구로 구성되는 프로덕트다.
즉 컨테이너와 VM을 비교한다고 보면 된다.
공통점은 기본 하드웨어에서 격리된 환경 내에 애플리케이션을 배치한다는 것이다.
차이점은 격리된 환경을 얼마나 격리 시키는지의 차이이다.
- Guest OS: VM에 설치된 OS
- Hypervisor: Guest OS와 Host OS를 분리
- Host operating System: 실물 컴퓨터에 설치된 OS
VM은 컴퓨터의 리소스를 분할하여 사용하기 때문에 속도가 느리고 주변 장치와의 완벽한 호환이 어렵다.
이러한 VM의 단점을 보완하기 위해 프로세스를 격리하는 방식이 고안되었다.
이 방식이 바로 컨테이너이다.
1) Docker 컨테이너
도커 컨테이너에서 돌아가는 애플리케이션은 컨테이너가 제공하는 격리 기능 내부에 샌드 박스가 있지만
여전히 같은 호스트의 다른 컨테이너와 동일한 커널을 공유한다. (하나의 OS에 이미지를 다운 받아 사용하기 때문이다.)
즉 컨테이너는 커널은 공유하고 나머지 CPU, 메모리, 하드디스크는 컨테이너 안에 다 격리되어 있다.
결과적으로 컨테이너 내부에서 실행되는 프로세스는 호스트 시스템에서 볼 수 있다.
2) 가상 머신
가상 머신과 함께 VM 내부에서 실행되는 모든 것은 호스트 운영체제 또는 하이퍼바이저와 독립되어 있다.
프로세스 시작 → 호스트 시스템은 그것을 하드웨어 지원의 일부를 VM에 할당
특정 VM만을 위한 커널을 부팅하고 운영체제 프로세스 세트를 시작한다.
다른 가상화 기술과 함께 Docker를 사용한 이유를 더 자세히 알아보자.
가상화 기술의 종류
1) 호스트 가상화
PC 혹은 Server에 OS(윈도우, 리눅스 등)를 설치하고 그 위에 가상머신을 설치하여
그 Host OS 위에서 가상 머신 모니터가 가상환경을 구성, 관리하는 방식이다.
가상 머신 모니터는 각 가상 환경마다 VM을 생성하고 VM마다 Guest OS를 설치한다.
VM에 특정 하나의 애플리케이션을 사용하기 위해 가볍지 않은 Linux OS를 설치하게 되는 경우가 발생할 수도 있다.
ex) Windows 환경에서 Linux의 가상머신에 Mysql 데이터 베이스를 설치하는 경우
VM의 개수가 많아지면 점점 Guest OS 의 무게를 무시하지 못한다.
Host OS의 무게라도 줄이기 위해 등장한 것이 아래의 하이퍼바이저 가상화이다.
2) 하이퍼바이저 가상화
하이퍼바이저 가상화는 하드웨어 위에 가상화 전문 소프트웨어인 ‘하이퍼바이저’를 설치하고 하드웨어와 가상환경을 제어한다.
Host OS 없이 하드웨어를 직접 제어하기 때문에 효율적으로 리소스를 사용할 수 있다.
하이퍼바이저에 의해 구동되는 VM은 각 VM마다 독립된 가상 하드웨어 자원을 할당받는다.
논리적으로 분리 되어 있어서 한 VM에 오류가 발생해도 다른 VM으로 퍼지지 않는다는 장점이 있다.
하지만 VM별로 OS가 동작하기 때문에 VM동작에 사용되는 오버헤드는 아직 존재한다.
3) 컨테이너 가상화
컨테이너 가상화 기술은 Host OS 상에서 논리적인 구역을 나누어 특정 어플리케이션의 동작을 위한 라이브러리와
애플리케이션 (OS나 참조되는 App)을 컨테이너에 넣고, 개별 서버처럼 사용하는 것이 컨테이너 가상화이다.
VM 별로 OS가 없고 VM을 구동시키기 위한 OS부팅도 없기 때문에 다른 가상화 기술에 비해 가볍고 빠른게 컨테이너 가상화 기술의 특징이다.
컨테이너들을 어떻게 격리시킬 수 있는가?
1) LXC 덕분이다.
LXC는 리눅스 커널 컨테이너 기능을 위한 사용자영역 인터페이스이다.
강력한 API와 간단한 도구들을 통해 리눅스 사용자가 쉽게 시스템 또는 어플리케이션 컨테이너들을 생성/관리할 수 있게 해준다.
도커에서 어떻게 리눅스 기능을?
Docker란 Go언어로 작성된 리눅스 컨테이너 기반으로하는 오픈소스 가상화 플랫폼이다.
2) 네임스페이스
하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술
(별개의 독립된 공간을 사용하는 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술)
3) Chroots
chroot는 프로세스의 루트 디렉토리를 변경하는 것으로, 이를 통해 프로세스가 액세스 할 수있는 디렉토리를 제한하거나 시스템 라이브러리와 관련 라이브러리를 로드 할 수있다.
chroot에서 제어 할 수있는 파일이나 디렉토리에 대한 액세스만으로, 네트워크 및 프로세스 등을 컨트롤 할 수는 없다.
4) CGroups
CPU, 메모리, Network, HD I/O 등 프로세스 그룹의 시스템 리소스 사용량을 관리
어떤 애플리케이션 사용량이 너무 많다면 그 어플리케이션 같은 것을 C Group에 집어 넣어서 CPU와 메모리 사용 제한 가능
(필요한 만큼만 할당해줌)
그럼 Kubernetes는?
많은 기업에서 쿠버네티스를 잘 아는 개발자를 원하는걸 볼 수 있는데
Docker랑 뭐가 다르고 왜 그런걸까?
Docker에서 컨테이너를 사용하면 Machine의 자원을 효율적으로 사용할 수 있는데
만약 컨테이너가 기하급수적으로 증가한다면?
컨테이너를 관리하고 운영하는데 상당히 어려워져서 운영상의 효율성이 저하된다.
이러한 배경으로 나타난게 쿠버네티스이다.
도커는 기술적인 개념, 도구이고 쿠버네티스는 도커를 관리하는 툴이라고 생각하면 된다.
이미지를 컨테이너에 띄우고 실행하는 기술이 도커이고
이런 도커를 기반으로 컨테이너를 관리하는 서비스가 쿠버네티스인 것이다.
도커는 한 개의 컨테이너를 관리하는 데 최적이고
쿠버네티스는 여러 개의 컨테이너를 서비스 단위로 관리하는 데 최적화되어있다.
위와 같은 이유로 나는 많은 컨테이너를 관리할 정도의 프로젝트는 아니기 때문에
쿠버네티스를 사용하지 않았다.