콘텐츠로 이동

L4 OS/Linux 입구

분류: Layer 4 - OS/Linux

1. 이 레이어는 무엇을 가능하게 하나

섹션 제목: “1. 이 레이어는 무엇을 가능하게 하나”

L4는 “서버가 내 코드를 어떻게 실행하고, 보호하고, 제한하는가”를 보는 레이어다.

서버를 실행하면 OS는 프로세스를 만들고 포트와 파일을 연결하며 로그를 기록한다. 컨테이너나 ECS task가 OOMKilled로 재시작되는 현상도 OS가 프로세스와 자원 한도를 다루는 방식에서 시작한다.

이 레이어의 목표는 커널 구현자가 되는 것이 아니다. 장애나 성능 문제를 만났을 때 “이건 코드 버그인가, 프로세스 문제인가, 파일/권한 문제인가, 메모리 한도 문제인가, 스케줄링 문제인가, 격리 설정 문제인가”를 나눠서 볼 수 있게 되는 것이다.

이 도입부의 첫 회독에서는 1~8절을 순서대로 읽는다. 명령어나 커널 내부 이름을 외우는 대신, 각 장애를 프로세스·파일·권한·메모리·CPU·격리 중 어느 경계의 문제로 좁히는 데 집중한다.

종료 조건은 아래 여섯 가지다. 7절의 체크리스트도 같은 기준을 다시 확인한다.

  • 로컬 dev server도 OS 입장에서는 하나의 프로세스라고 설명할 수 있다.
  • 포트 충돌이 두 프로세스가 같은 네트워크 자원을 쓰려는 상황임을 이해한다.
  • 파일 경로, 권한, 환경변수 문제가 서버 실행 실패로 이어질 수 있음을 안다.
  • 앱 코드가 파일, 네트워크, 메모리 같은 자원에 접근할 때 커널을 거친다는 그림을 받아들일 수 있다.
  • OOMKilled, Permission denied, Too many open files 같은 에러를 보면 어느 L4 문서로 돌아갈지 고를 수 있다.
  • Docker 컨테이너가 별도 OS가 아니라 Linux 커널의 격리 기능 위에서 실행된다는 말을 낯설지만 받아들일 수 있다.

선택 심화: 이 도입부 안에는 선택 심화 절이 없다. 5절에서 안내한 각 토픽의 스케줄러 내부 정책, 메모리 튜닝, 동기화 구현, 컨테이너 런타임 세부는 해당 문서가 표시한 선택 심화 절로 미룬다.

1.5. 선행 단계의 한계 - OS 자원·경계 모델이 필요한 이유

섹션 제목: “1.5. 선행 단계의 한계 - OS 자원·경계 모델이 필요한 이유”

앞선 레이어에서 이벤트 루프, 요청 경로, 클라우드 실행 단위를 배웠다면 서버가 어떤 일을 하는지는 설명할 수 있다. 하지만 앱과 런타임의 관찰만으로는 두 프로세스가 왜 서로의 메모리를 덮어쓰지 못하는지, CPU 시간이 어떤 실행 흐름에 돌아가는지, 파일 접근이 왜 거부되는지, 한 컨테이너의 과사용을 어디에서 막는지까지 설명하기 어렵다. 자원을 사용하는 코드는 보이지만 자원을 배분하고 경계를 강제하는 주체가 모델에 빠져 있기 때문이다.

L4는 이 선행 단계의 한계를 OS 메커니즘으로 채운다. 스케줄러는 제한된 CPU 시간을 실행 흐름 사이에 배분하고, 프로세스별 가상 주소 공간은 메모리 접근 범위를 나누며, 사용자·그룹 권한과 시스템 콜 경계는 파일·네트워크 접근을 검사한다. cgroup은 CPU·메모리 사용량을 제한하고 namespace는 프로세스가 볼 수 있는 PID·네트워크·파일 시스템 범위를 분리한다.

따라서 L4의 해결 방식은 장애 이름을 더 외우는 것이 아니라, OOMKilled, Permission denied, CPU 지연 같은 현상을 어느 OS 자원 또는 경계가 배분·검사·제한한 결과인지로 바꾸어 설명하는 것이다.

2. 이미 알고 있는 것에서 출발하기

섹션 제목: “2. 이미 알고 있는 것에서 출발하기”

프론트엔드나 Node.js에서 본 dev server, 포트 충돌, 파일 경로 오류는 출발점일 뿐이다. 여기서는 앱 내부의 생명주기나 이벤트 흐름이 아니라 커널이 실행 단위와 자원 경계를 어떻게 만들고 강제하는가로 즉시 관찰 대상을 바꾼다.

OS는 실행 파일을 프로세스로 만들고, 각 프로세스에 주소 공간과 파일 디스크립터를 붙이며, 사용자·그룹 권한으로 접근을 검사한다. CPU 시간이 부족하면 runnable task 사이에서 순서를 정하고, RAM이나 cgroup 한도를 넘으면 회수·지연·종료 중 하나를 선택한다. 컨테이너도 별도 OS가 아니라 이 프로세스의 시야(namespace)와 사용량(cgroup)을 제한한 결과다.

따라서 같은 “서버가 안 뜬다”도 서로 다른 문제다. 포트를 이미 점유한 프로세스가 있는지, 실행 파일을 읽을 권한이 없는지, 메모리 한도를 넘었는지, 필요한 파일이 다른 mount에 있는지에 따라 확인할 OS 경계가 달라진다.

이 레이어를 읽을 때는 명령어 목록보다 아래 렌즈를 먼저 잡는 편이 좋다.

렌즈핵심 질문실무에서 보이는 모습
프로세스지금 무엇이 실행 중인가node dist/main.js, PM2 worker, ECS task
파일데이터와 설정은 어디에 놓였는가로그, .env, 업로드 파일, /proc
권한누가 읽고 쓰고 실행할 수 있는가Permission denied, root 실행, SSH 접근
커널/유저 공간앱이 직접 못 하는 일은 어디로 요청하는가fs.readFile, HTTP socket, Too many open files
메모리프로세스는 어디까지 메모리를 쓸 수 있는가Node heap 증가, Docker OOMKilled, Redis 메모리 정책
스케줄링제한된 CPU를 누가 언제 쓰는가이벤트 루프 지연, Worker 수, context switching
격리한 프로세스나 컨테이너의 문제가 어디까지 퍼지는가컨테이너 limit, namespace, cgroups

처음부터 task_struct, MMU, TLB, Ring 0 같은 용어를 완벽히 이해하려고 하면 진입이 무거워진다. 먼저 “OS는 실행 단위와 자원 경계를 관리한다”는 큰 그림을 잡고, 각 토픽에서 필요한 내부 구조를 하나씩 붙이면 된다.

  • 터미널에서 현재 위치와 파일 경로를 읽을 수 있으면 충분하다. 절대경로와 상대경로가 헷갈리면 content/topics/L4/linux-basics.mdx의 파일 시스템과 경로 부분으로 돌아간다.
  • Node.js 서버가 하나의 실행 중인 프로세스라는 감각이 있으면 좋다. 이벤트 루프와 비동기 I/O가 낯설면 content/topics/L0/nodejs-event-loop.mdx를 먼저 본다.
  • HTTP 요청이 네트워크를 통해 서버 프로세스에 도착한다는 그림이 필요하다. TCP/UDP나 포트가 막히면 content/topics/L2/tcp-udp-internals.mdx를 참고한다.
  • 컨테이너나 ECS가 익숙하지 않다면 깊게 파고들기보다 “격리된 실행 환경” 정도로만 잡고 시작한다. 필요할 때 content/topics/L5/docker-basics.mdxcontent/topics/L3/ecs-vs-ec2.mdx를 참고하면 된다.

L4 추천 학습 순서

  1. 1. linux-basics.mdx

    서버를 만질 때 보이는 파일, 로그, 권한, 프로세스, 환경변수의 표면을 잡는다.

  2. 2. process-thread.mdx

    Node 프로세스, worker, ECS task처럼 실행 단위가 어떻게 격리되고 병렬화되는지 본다.

  3. 3. system-call-interrupt.mdx

    앱이 파일과 네트워크를 직접 만지는 것이 아니라 커널에 요청한다는 경계를 이해한다.

  4. 4. memory-management.mdx

    프로세스 메모리, 가상 메모리, OOM, 캐시 정책을 연결한다.

  5. 5. cpu-scheduling.mdx

    CPU가 여러 작업 사이에서 어떻게 시간을 나누는지 보고 이벤트 루프 지연과 Worker 수 판단으로 연결한다.

  6. 6. concurrency-sync.mdx

    여러 실행 흐름이 같은 자원을 건드릴 때 왜 race condition과 lock이 필요한지 본다.

  7. 7. cgroups-namespace.mdx

    Docker와 Kubernetes의 컨테이너 격리가 Linux 커널 기능 위에 있다는 사실을 정리한다.

처음 네 문서는 L4의 뼈대다. 뒤의 세 문서는 그 뼈대를 성능, 동시성, 컨테이너 운영으로 확장한다.

뒤쪽 문서는 이름이 조금 어려운 개념을 더 자주 만난다. THP, EEVDF, futex, Redis distributed lock, gVisor, Kata 같은 단어는 첫 회독에서 구현 세부를 외우지 않아도 된다. 처음에는 “어떤 문제에서 등장했는가”, “실패하면 어떤 신호가 보이는가”, “언제 선택 심화로 미뤄도 되는가”만 잡는다. 튜닝 값, 커널 내부 자료구조, 특정 런타임 명령은 본문 이해가 끝난 뒤 선택 부록이나 후속 레이어에서 다시 보면 된다.

6. 어렵게 느껴지는 지점과 돌아갈 곳

섹션 제목: “6. 어렵게 느껴지는 지점과 돌아갈 곳”
막히는 느낌보통 부족한 전제돌아갈 문서
ps, chmod, /var/log 같은 말이 한꺼번에 나온다파일 경로, 권한, CLI 표면content/topics/L4/linux-basics.mdx
Node.js가 싱글 스레드라는데 worker와 cluster가 헷갈린다이벤트 루프와 실행 단위 구분content/topics/L0/nodejs-event-loop.mdx, content/topics/L4/process-thread.mdx
시스템 콜이 왜 필요한지 감이 안 온다앱과 커널의 권한 경계content/topics/L4/system-call-interrupt.mdx
OOM, heap, RSS, swap이 섞여 보인다OS 메모리와 V8 힙의 층위 구분content/topics/L4/memory-management.mdx
CPU 사용률은 낮은데 응답이 느린 상황이 이해되지 않는다대기, 스케줄링, I/O 지연 구분content/topics/L4/cpu-scheduling.mdx, content/topics/L6/logs-metrics-traces.mdx
컨테이너가 왜 host와 다르게 보이는지 모르겠다Linux 격리와 자원 제한content/topics/L4/cgroups-namespace.mdx, content/topics/L5/docker-basics.mdx
포트, 연결, 패킷 이야기가 OS 문서 안에서 튀어나온다TCP 연결과 소켓 감각content/topics/L2/tcp-udp-internals.mdx

막히는 것은 정상이다. L4는 여러 레이어의 바닥을 받치는 영역이라 한 번에 매끈하게 지나가기 어렵다. 대신 막힐 때마다 “나는 지금 파일을 모르는가, 프로세스를 모르는가, 권한 경계를 모르는가, 메모리를 모르는가”처럼 부족한 전제를 좁히면 된다.

L4에 들어갈 준비

  • 로컬 dev server도 OS 입장에서는 하나의 프로세스라고 설명할 수 있다.
  • 포트 충돌이 두 프로세스가 같은 네트워크 자원을 쓰려는 상황임을 이해한다.
  • 파일 경로, 권한, 환경변수 문제가 서버 실행 실패로 이어질 수 있음을 안다.
  • 앱 코드가 파일, 네트워크, 메모리 같은 자원에 접근할 때 커널을 거친다는 그림을 받아들일 수 있다.
  • `OOMKilled`, `Permission denied`, `Too many open files` 같은 에러를 보면 어느 L4 문서로 돌아갈지 고를 수 있다.
  • Docker 컨테이너가 별도 OS가 아니라 Linux 커널의 격리 기능 위에서 실행된다는 말을 낯설지만 받아들일 수 있다.

OS/Linux는 서버 코드 아래에서 프로세스, 파일, 권한, 메모리, CPU, 격리 경계를 제공하는 실행 기반이다.

L4를 지나고 나면 “서버가 죽었다”는 말을 더 작게 쪼갤 수 있다. 프로세스가 종료된 것인지, 포트나 파일 디스크립터가 부족한 것인지, 권한이 막힌 것인지, 메모리 한도를 넘은 것인지, CPU 스케줄링이나 동시성 문제가 생긴 것인지 구분하는 힘이 생긴다.