컨테이너와 VM 살펴보기

image.png

1. VM vs 컨테이너: 격리 방식의 차이

구분VM (가상 머신)컨테이너
격리 수준머신 수준 (독립된 OS, 독립된 커널)프로세스 수준 (호스트 OS 커널 공유)
구조하이퍼바이저 → Guest OS → 앱호스트 OS → 컨테이너 런타임 → 앱
크기GB 단위 (Guest OS 포함)MB 단위 (앱 + 의존성만)
시작 시간분 단위초 단위

핵심 차이: 컨테이너는 프로세스 수준으로 작은 크기의 실행 환경을 다룰 수 있다.

💡 VM은 “집 한 채를 통째로 빌리는 것”이고, 컨테이너는 “공유 오피스에서 내 자리 하나를 쓰는 것”이라고 생각하면 외우기 쉽다. 건물(커널)은 같이 쓰되, 내 공간(namespace)은 칸막이로 분리되어 있고, 전기·인터넷 사용량(cgroups)에 제한이 있는 것.

주요 용어

  • 하이퍼바이저: 물리 서버의 하드웨어 자원(CPU, 메모리, 디스크)을 가상화하여 여러 VM에 분배하는 소프트웨어. (예: VMware ESXi, KVM, Hyper-V)
  • Host OS: 물리 서버에 설치된 운영체제
  • Guest OS: VM 안에 설치된 운영체제. VM이 무거운 핵심 원인 — VM마다 Guest OS 전체를 설치해야 한다.

💡 예시: 물리 서버에 Ubuntu를 깔고(Host OS), VMware로 VM 3개를 만들어 각각 CentOS, Windows, Ubuntu를 설치하면 → Host OS는 Ubuntu 1개, Guest OS는 CentOS·Windows·Ubuntu 3개가 되는 것. 반면 컨테이너는 Guest OS 자체가 필요 없다.


2. 컨테이너 격리를 가능하게 하는 리눅스 핵심 기술

image.png

기술역할비유
namespace각 컨테이너가 볼 수 있는 범위를 분리 (PID, 네트워크, 파일시스템 등)“뭘 볼 수 있는가” (격리)
cgroups (Control Groups)컨테이너별 CPU, 메모리, 디스크 I/O 등의 리소스 사용량 제한”얼마나 쓸 수 있는가” (자원 제한)

Kubernetes에서 Pod의 resources.limits/requests 설정이 내부적으로 cgroups를 통해 동작한다. 💡 namespace와 cgroups를 헷갈리면 이렇게 외우자: namespace는 눈가리개 (다른 컨테이너가 안 보이게), cgroups는 밥그릇 크기 (먹을 수 있는 양 제한). 둘 다 없으면 컨테이너는 그냥 일반 프로세스랑 다를 바가 없다.


3. 프로세스란?

  • 프로그램: 디스크에 저장된 코드 덩어리 (정적, 실행 전 상태)
  • 프로세스: 프로그램이 실행되어 메모리에 올라간 상태

프로세스가 생성되면 OS가 할당하는 것들:

  • 고유 PID (프로세스 식별 번호)
  • 독립된 메모리 공간 (코드, 데이터, 스택, 힙)
  • CPU 시간 (스케줄러가 배분)
  • 열린 파일, 네트워크 소켓 등의 리소스

비유: 프로그램은 레시피, 프로세스는 실제로 요리하고 있는 행위. 같은 레시피로 2번 요리하면 프로세스 2개. ps aux 쳐서 나오는 한 줄 한 줄이 전부 프로세스다.


4. 1 컨테이너 = 1 프로세스 (One Concern per Container)

왜 컨테이너 하나에 하나의 관심사만?

이유설명
라이프사이클 관리PID 1 프로세스가 종료되면 컨테이너 런타임이 컨테이너 전체를 종료시킴 → 무관한 서비스까지 영향
스케일링서비스별 독립 스케일링 가능 (HPA로 웹서버만 늘리기 등)
로깅/모니터링stdout/stderr 로그가 섞이지 않아 디버깅이 깔끔
장애 격리한 서비스의 장애가 다른 서비스에 영향을 주지 않음

PID 1과 컨테이너 종료 메커니즘

  1. PID 1 프로세스 종료
  2. 컨테이너 런타임이 감지 → 컨테이너 종료 결정
  3. 컨테이너의 namespace 정리 → 나머지 프로세스도 종료

일반 리눅스에서는 메인 프로세스가 죽어도 서브 프로세스가 고아 프로세스로 살아남을 수 있지만, 컨테이너에서는 런타임이 PID 1의 종료를 컨테이너 전체의 종료 신호로 해석한다. 이게 OS의 동작이 아니라 컨테이너 런타임(Docker)의 설계 결정이라는 점이 핵심이다.

”그러면 PID 1을 sleep으로 띄워놓고 서브프로세스 여러 개 돌리면 되지 않나?”

이런 발상으로 실제로 사용되는 도구가 supervisord다. supervisord는 Python으로 만들어진 프로세스 매니저 프로그램으로, 여러 프로세스를 동시에 실행하고 감시·재시작까지 해주는 역할을 한다. 일반 리눅스 서버에서는 유용한 도구지만, 컨테이너 안에서 PID 1로 띄워 여러 서비스를 관리하는 방식은 대표적인 안티패턴이다.

왜 안티패턴인가? — 컨테이너 설계 원칙에 어긋난다

Docker 공식 문서에서는 “Each container should have only one concern”이라고 명시하고 있다. 이는 객체지향의 단일 책임 원칙(SRP) 의 컨테이너 버전인 Single Concern Principle이다. 클래스가 하나의 변경 이유만 가져야 하듯, 컨테이너도 하나의 관심사만 다뤄야 한다. 또한 The Twelve-Factor App 방법론의 6번 원칙도 “프로세스는 stateless하고 share-nothing이어야 한다”고 말한다.

supervisord 방식이 이 원칙들에 어긋나는 구체적인 이유

  • Kubernetes가 장님이 된다. supervisord(PID 1)는 살아있지만 내부 웹서버가 죽은 상태일 때, Kubernetes는 “이 Pod 정상이네~“라고 판단한다. liveness probe로 커버할 수 있지만, 그건 불필요하게 복잡도를 올리는 행위다.
  • 독립적 스케일링 불가. 웹서버 트래픽이 폭주해도 DB까지 함께 복제된다. 자원 낭비.
  • 로그가 뒤죽박죽. stdout에 여러 서비스 로그가 섞이면 장애 원인 추적이 지옥이 된다.
  • 배포가 통째로. 웹서버만 업데이트하고 싶어도 이미지를 통째로 다시 빌드해야 한다.

image.png

⚠️ 예외: 레거시 앱을 컨테이너로 마이그레이션하는 과도기에는 어쩔 수 없이 supervisord를 쓰기도 한다. 하지만 이는 “어쩔 수 없이”지 “권장”이 아니다. 최종 목표는 서비스를 분리하는 것. 💡 한 줄 요약: 할 수는 있지만, 하면 할수록 컨테이너를 쓰는 의미가 사라진다. 그냥 VM 쓰는 거랑 다를 바가 없어진다. 🎯 면접 포인트: “1 프로세스”라고 말하면 초급, “One concern per container” 라고 말하면 원칙을 이해하고 있다는 인상을 준다.


5. 컨테이너 기술의 특징

특징설명
가벼운 실행환경Guest OS 없이 앱+의존성만 담아 MB 단위, 초 단위 시작
높은 이식성이미지에 실행 환경이 모두 포함 → “It works on my machine” 문제 해결
거대한 생태계Docker Hub, Kubernetes, ArgoCD, Harbor, Jenkins 등

💡 “It works on my machine” — 개발자가 가장 많이 하는 변명이자, 컨테이너가 해결한 가장 큰 문제. 내 로컬에서 돌아간 이미지는 서버에서도, 동료 PC에서도, AWS에서도 똑같이 돌아간다.


6. 컨테이너 이미지

  • 여러 레이어(layer)로 구성된 파일 시스템
  • Docker의 핵심 철학: Build, Ship, Run
    • Build: 이미지를 빌드하고
    • Ship: 레지스트리를 통해 배포하고
    • Run: 어디서든 실행한다

레이어 구조의 상세 내용은 Docker 파트에서 다룰 예정

이해도 확인 문제

Q1. 컨테이너 A에서 ps aux를 쳤더니 PID 1~5까지 5개의 프로세스가 보인다. 그런데 같은 호스트의 컨테이너 B에서 ps aux를 치면 A의 프로세스가 하나도 안 보인다. 이 격리를 가능하게 하는 리눅스 기술은 무엇이고, 만약 컨테이너 A가 CPU를 100% 먹어도 B가 멀쩡한 이유를 가능하게 하는 기술은 무엇인가?


Q2. 어떤 팀이 하나의 컨테이너 안에 nginx와 Flask 앱을 supervisord로 묶어서 운영하고 있다. Flask 앱이 죽었는데 Kubernetes 대시보드에는 Pod가 “Running” 상태로 표시된다. 왜 이런 현상이 발생하는지 PID 1의 동작 원리와 연결지어 설명하라.


Q3. 동료가 “컨테이너는 가벼운 VM이다”라고 말했다. 이 표현이 왜 부정확한지, VM과 컨테이너의 격리 방식 차이를 들어 반박하라.

복기 포인트

Q2: “스케줄링”이 아니라 “스케일링”. 면접에서 이 두 단어 혼용하면 감점 포인트.

Q3: 핵심 한 방 추가 — “같은 기술의 경량 버전이 아니라, 완전히 다른 접근 방식” 이라는 결론을 명확히 말해줘야 한다.

Comments

💬 Sign in with GitHub to leave a comment. Comments are public and stored in GitHub Discussions.