회사에서는 하나의 물리서버를 보다 효율적으로 사용하기를 바람
이런 필요에 의해 가상화 기술이 발전하게 됨 ⇒ VM이나 컨테이너와 같은 기술이 생김
물리적인 하드웨어를 논리적으로 구분하는 것 = 가상화
하나의 하드웨어에서 여러개의 시스템을 효율적으로 사용할 수 있게 해줌
가상머신 vm - 하이퍼바이저를 이용해 리소스 전체를 가상화하는 방법
컨테이너 container - OS 수준에서 프로세스를 컨테이너 형태로 격리하는 방법
⇒ virtual machine 은 물리적인 컴퓨터와 동일한 기능을 제공하는 소프트웨어 컴퓨터임

하드웨어를 제어하기 위한 명령어 : 커널
애플리케이션이 OS 커널에 요청을 보내는 방식이 다르고 (시스템 콜), 이를 하드웨어가 이해할 수 있는 CPU 명령어 셋으로 변환하는 과정이 필요함
Hypervisor은?
-> 이때 !!! 각 OS 마다 말하는 명령을 하드웨어가 이해할 수 있게 하나의 명령어로 번역해줌
Windows - NT Kernel
Linux - Linux Kernel
mac - Darwin
프로그램과 하드웨어(CPU) 사이에 CPU에 직접적으로 명령을 실행하기 위한 함수 리스트가 존재함 (ex. Linux system call)
만약 프로그램에서 파일을 연다고 생각해보자.
프로그램 파일 열기 클릭
Kernel 파일 Open 함수 실행
CPU 내부적으로 파일을 여닫고 하는 과정들에 포함되는 명령어 셋들을 실행
=> OS 마다 차이가 발생하는 부분은 2번 과정
3번은 명령어 셋들이 호출되는 과정이 다를 뿐 최종적으로 CPU에 전달되는 명령어는 동일함
VM과 하드웨어 간의 I/O명령을 처리하는 인터페이스
물리적인 하드웨어를 논리적으로 가상화하는 것을 담당하는 기술이 하이퍼 바이저
가상머신을 생성하고 구동하는 프로그램 (=가상머신 모니터) → 다수의 운영체제를 동시에 실행하기 위한 논리적 플랫폼
host(=ESXI에 리소스를 제공하는 물리적 컴퓨터)에서 여러 가상의 GuestOS(=VM에서 실행되는 운영체제)를 실행하기 위한 플랫폼
VM 위에 올라간 OS들의 명령을 하드웨어가 이해할 수 있게 하나의 명령어로 번역해주고, 반대로 각 OS들에게 하드웨어의 리소스들을 나눠주면서 조율해줌 (운용역할도 진행)
⇒ VMware를 설치하고 CentOS를 올렸다면, CentOS에서 명령들을 하드웨어와 중재하는 역할을 한다고 이해하면 될듯
추가로, PC에서 핸드폰용 Android Emulator, iOS Emulator을 돌릴때 혹은 x86_64 OS에서 ARM / ARM64 OS를 테스트하고 싶을 때 사용하기도 함.

컨테이너의 시작은 화물을 어떻게 하면 효율적으로 옮길 수 있을까 → 표준화된 컨테이너 박스를 만들고, 무엇을 넣어도 표준화된 운송선만 있으면 똑같이 세워서 효율적으로 운송할 수 있음
이 컨셉을 IT에 적용한 것이 컨테이너
소프트웨어 코드, 애플리케이션 코드가 작동하기 위해 필요한 컴포넌트와 함께 표준화된 방식으로 패키징해서, 컨테이너 엔진만 있으면 돌아갈 수 있도록 하는 구조를 컨테이너라고 함.
⇒ 컴퓨팅 환경 간의 이식성이 높아짐
가상화 레이어 없어서 실행 속도가 프로세스 실행 수준으로 빠름
리눅스 커널의 기능인 Namespace(자원 격리), cgroups(자원 제한)을 사용해 프로세스 단위로 격리함
하이퍼 바이저로 구동된 OS는 각자 다른 Kernel을 가질 수 있음
컨테이너는 호스트와 동일한 커널을 사용함
하드웨어 → 하이퍼바이저 → 가상머신 (Guest OS Kernel + App)
하드웨어 → HostOS (Kernel) → container 엔진 (Docker) → Application