부트캠프를 진행하면서 가장 어렵게 느껴졌던 주차를 하나 꼽으라면 클라우드 주차였다.
처음 보는 용어가 많았고, 단순히 정의를 읽는 것만으로는 머릿속에 구조가 잘 그려지지 않았다.
특히 VM과 컨테이너를 배우면서
"VM은 운영체제를 각각 사용하고, 컨테이너는 운영체제를 공유한다."
라는 설명을 자주 들었는데, 정작 운영체제가 정확히 무엇인지 이해하지 못한 상태에서는 이 설명도 제대로 와닿지 않았다.
그래서 VM과 컨테이너를 다시 공부하기 전에 먼저 운영체제(OS)와 Kernel이 무엇인지부터 정리해보고자 한다.
결국 VM과 컨테이너의 중요한 차이 중 하나는 운영체제, 더 정확히는 Kernel을 어떻게 사용하느냐에 있기 때문이다.
운영체제(Operating System, OS)는 애플리케이션과 컴퓨터 하드웨어 사이에서 CPU, Memory, Disk, Network 등의 자원을 관리하는 핵심 소프트웨어이다.
대표적인 운영체제로는 다음과 같은 것들이 있다.
하지만 이렇게 정의만 읽으면 크게 와닿지 않는다.
컴퓨터에서 동시에 여러 프로그램을 실행한다고 가정해보자.
Chrome
IntelliJ
MySQL
Spring Boot
Discord
이 프로그램들은 모두 CPU와 Memory를 사용하고, 파일을 읽고 쓰며, 경우에 따라 Network도 사용한다.
그렇다면 각 프로그램이 CPU나 Memory 같은 하드웨어를 마음대로 사용해도 될까?
그렇지 않다.
여러 프로그램이 동시에 같은 자원을 사용하려고 하면 충돌이 발생할 수 있기 때문이다.
그래서 중간에서 컴퓨터 자원을 관리해주는 존재가 필요하다.
그 역할을 하는 것이 운영체제(OS)이다.
Application
↓
Operating System (OS)
↓
Hardware
애플리케이션이 CPU나 Memory 같은 하드웨어를 직접 제어하는 것이 아니라, OS를 통해 필요한 자원을 요청하고 사용한다.
더 쉽게 이해해보자면 프로그램, 즉 application은 회사 직원이고 OS는 관리자 역할이다. 어떤 회사의 직원이 회사의 금고/전기실/서버실을 마음대로 사용하고 확인할 수 있겠는가? 관리자의 허락과 조정 하에 확인할 수 있는 것과 같다고 생각한다.
백엔드 개발자의 관점에서는 우선 다음 다섯 가지 정도 알아두면 좋을 것 같다고 한다.
컴퓨터에서는 여러 프로그램이 동시에 실행된다.
하지만 하나의 CPU를 모든 프로그램이 동시에 마음대로 사용할 수는 없다.
OS는 어떤 Process가 CPU를 언제, 얼마나 사용할 것인지 결정한다.
이러한 작업을 CPU Scheduling이라고 한다.
예를 들면 다음과 같은 느낌이다.
Chrome → CPU 사용
Spring Boot → CPU 사용
IntelliJ → CPU 사용
MySQL → CPU 사용
실제로는 매우 짧은 시간 단위로 CPU 사용 권한을 전환하면서 여러 프로그램이 동시에 실행되는 것처럼 보이게 한다.
프로그램이 실행되려면 Memory(RAM)가 필요하다.
예를 들어 Spring Boot 애플리케이션을 실행하면 OS는 해당 프로그램이 사용할 Memory 공간을 할당한다.
Spring Boot
↓
"Memory가 필요합니다."
↓
Operating System
↓
RAM 일부 할당
그리고 프로그램이 종료되면 사용하던 Memory를 다시 회수한다.
즉 OS는 어떤 프로그램이 Memory를 얼마나 사용하고 있는지 관리한다.
프로그램을 실행하면 OS는 실행 중인 프로그램을 Process라는 단위로 관리한다.
예를 들어 다음 명령어를 실행한다고 해보자.
java -jar app.jar
app.jar 파일 자체가 Process인 것은 아니다.
파일을 실행하면 Java 프로그램이 실행되고, OS는 실행된 프로그램을 하나의 Process로 관리한다.
app.jar
↓ 실행
Java Application
↓
Process
그래서 Linux 서버에서는 ps 같은 명령어를 사용해 현재 실행 중인 Process를 확인할 수 있다.
우리가 사용하는 파일도 OS가 관리한다.
예를 들어 다음과 같은 파일이 있다고 해보자.
/home/ec2-user/app.jar
나는 SSD의 정확히 어느 위치에 데이터가 저장되어 있는지 알 필요가 없다.
OS가 파일 시스템(File System)을 통해
등을 처리해준다.
Spring Boot 서버를 실행하면서 다음과 같은 메시지를 본 적이 있다.
Tomcat started on port 8080
Spring Boot 애플리케이션이 Network Card를 직접 제어해서 8080 Port를 만드는 것은 아니다.
애플리케이션이 OS에 Network 자원을 요청하고, OS가 이를 관리한다.
Spring Boot
↓
"8080 Port를 사용하겠습니다."
↓
Operating System
↓
Network
그래서 이미 다른 Process가 8080 Port를 사용하고 있을 때과 같은 문제가 발생했다.
Port 8080 was already in use
결국 Port 역시 OS가 관리하는 자원이라는 것을 알 수 있다.
Application
↓
Operating System
↓
Hardware
OS는 애플리케이션이 CPU, Memory, Disk, Network 같은 하드웨어 자원을 안전하고 편리하게 사용할 수 있도록 관리하는 중간 관리자이다.
그렇다면
운영체제 안에서 실제로 CPU, Memory, Process 같은 핵심 자원을 관리하는 부분은 무엇일까?
바로 Kernel이다.
Kernel은 운영체제의 핵심 부분으로, CPU, Memory, Process, Device 등의 하드웨어 자원을 직접 관리한다.
운영체제 전체와 Kernel은 같은 의미가 아니다.
운영체제가 더 큰 개념이고, Kernel은 운영체제 내부에 존재하는 핵심 구성 요소이다.
Operating System
│
├── System Program
├── Library
├── Shell
├── Utility
│
└── Kernel ⭐
쉽게 비유하면 다음과 같다.
Operating System = 회사 전체
Kernel = 회사의 핵심 운영팀
회사에는 여러 부서가 있지만 실제로 회사의 핵심 자원을 통제하고 배분하는 운영 조직이 있는 것처럼, 운영체제에서도 Kernel이 하드웨어 자원을 직접 관리한다.
Spring Boot 애플리케이션이 실행되고 있다고 해보자.
Spring Boot가 직접 CPU에게
"CPU 2번 Core를 지금부터 내가 사용하겠다."
라고 명령하지 않는다.
Spring Boot가 직접 RAM의 특정 주소를 마음대로 사용하는 것도 아니다.
그 사이에는 Kernel이 있다.
Spring Boot Application
↓
System Call
↓
Kernel
↓
CPU / Memory / Disk / Network
애플리케이션은 Kernel에게 필요한 작업을 요청하고, Kernel은 실제 하드웨어를 제어한다.
이때 애플리케이션이 Kernel에게 기능을 요청할 때 사용하는 통로를 System Call(시스템 호출)이라고 한다.
예를 들어 애플리케이션이
모두 결국 Kernel의 도움을 받아 이루어진다.
둘의 관계를 단순하게 표현하면 다음과 같다.

즉, OS > Kernel 다.
Kernel은 OS 전체가 아니라 OS의 가장 핵심적인 부분이다.
VM과 컨테이너를 비교할 때
"VM은 OS를 각각 가지고 있고, Container는 OS를 공유한다."
라고 배웠다.
하지만 조금 더 정확하게 이해해보자면 아래와 같다.
VM
→ 각각 독립적인 OS와 Kernel을 가진다.
Container
→ Host OS의 Kernel을 공유한다.
바로 이 차이가 VM과 컨테이너의 구조와 무게, 실행 속도 등에 큰 영향을 준다.
비전공자에 컴퓨터의 ㅋ도 모르고 용어도 몰랐기에 이해하기 어려운 부분이었다. 이 길은 절대 내 길이 아니다라고 생각했던 때가 있었는데 이렇게 공부하고 있다니 역시 인생은 알 수 없구나!!
다시 복습하면서 공부하니 좀 더 이해가 잘 된다.
다음 포스트에는 VM과 컨테이너를 정리해보자!