L4 OS/Linux 입구
L4 OS/Linux 입구
섹션 제목: “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 경계가 달라진다.
3. 새로 배워야 하는 사고 모델
섹션 제목: “3. 새로 배워야 하는 사고 모델”이 레이어를 읽을 때는 명령어 목록보다 아래 렌즈를 먼저 잡는 편이 좋다.
| 렌즈 | 핵심 질문 | 실무에서 보이는 모습 |
|---|---|---|
| 프로세스 | 지금 무엇이 실행 중인가 | 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는 실행 단위와 자원 경계를 관리한다”는 큰 그림을 잡고, 각 토픽에서 필요한 내부 구조를 하나씩 붙이면 된다.
4. 들어가기 전 최소 선수지식
섹션 제목: “4. 들어가기 전 최소 선수지식”- 터미널에서 현재 위치와 파일 경로를 읽을 수 있으면 충분하다. 절대경로와 상대경로가 헷갈리면
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.mdx와content/topics/L3/ecs-vs-ec2.mdx를 참고하면 된다.
5. 이 레이어를 듣는 순서
섹션 제목: “5. 이 레이어를 듣는 순서”L4 추천 학습 순서
- 1. linux-basics.mdx
서버를 만질 때 보이는 파일, 로그, 권한, 프로세스, 환경변수의 표면을 잡는다.
- 2. process-thread.mdx
Node 프로세스, worker, ECS task처럼 실행 단위가 어떻게 격리되고 병렬화되는지 본다.
- 3. system-call-interrupt.mdx
앱이 파일과 네트워크를 직접 만지는 것이 아니라 커널에 요청한다는 경계를 이해한다.
- 4. memory-management.mdx
프로세스 메모리, 가상 메모리, OOM, 캐시 정책을 연결한다.
- 5. cpu-scheduling.mdx
CPU가 여러 작업 사이에서 어떻게 시간을 나누는지 보고 이벤트 루프 지연과 Worker 수 판단으로 연결한다.
- 6. concurrency-sync.mdx
여러 실행 흐름이 같은 자원을 건드릴 때 왜 race condition과 lock이 필요한지 본다.
- 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는 여러 레이어의 바닥을 받치는 영역이라 한 번에 매끈하게 지나가기 어렵다. 대신 막힐 때마다 “나는 지금 파일을 모르는가, 프로세스를 모르는가, 권한 경계를 모르는가, 메모리를 모르는가”처럼 부족한 전제를 좁히면 된다.
7. 들을 준비가 된 상태
섹션 제목: “7. 들을 준비가 된 상태”L4에 들어갈 준비
- 로컬 dev server도 OS 입장에서는 하나의 프로세스라고 설명할 수 있다.
- 포트 충돌이 두 프로세스가 같은 네트워크 자원을 쓰려는 상황임을 이해한다.
- 파일 경로, 권한, 환경변수 문제가 서버 실행 실패로 이어질 수 있음을 안다.
- 앱 코드가 파일, 네트워크, 메모리 같은 자원에 접근할 때 커널을 거친다는 그림을 받아들일 수 있다.
- `OOMKilled`, `Permission denied`, `Too many open files` 같은 에러를 보면 어느 L4 문서로 돌아갈지 고를 수 있다.
- Docker 컨테이너가 별도 OS가 아니라 Linux 커널의 격리 기능 위에서 실행된다는 말을 낯설지만 받아들일 수 있다.
8. 이 레이어의 핵심 한 문장
섹션 제목: “8. 이 레이어의 핵심 한 문장”OS/Linux는 서버 코드 아래에서 프로세스, 파일, 권한, 메모리, CPU, 격리 경계를 제공하는 실행 기반이다.
L4를 지나고 나면 “서버가 죽었다”는 말을 더 작게 쪼갤 수 있다. 프로세스가 종료된 것인지, 포트나 파일 디스크립터가 부족한 것인지, 권한이 막힌 것인지, 메모리 한도를 넘은 것인지, CPU 스케줄링이나 동시성 문제가 생긴 것인지 구분하는 힘이 생긴다.