본문으로 건너뛰기
Previous
Next
Linux 커널 심화 시리즈 전체 목차 | 프로덕션 튜닝과 트러블슈팅

Linux 커널 심화 시리즈 전체 목차 | 프로덕션 튜닝과 트러블슈팅

Linux 커널 심화 시리즈 전체 목차 | 프로덕션 튜닝과 트러블슈팅

이 글의 핵심

Linux 커널 심화 시리즈 전체 목차: 파일시스템, 프로세스, 메모리, 디스크 관리 4개 고급 주제로 프로덕션 전문가 되기.

시리즈 소개: 내가 읽는 Linux

Linux 커널 심화 시리즈는 운영체제 안쪽을 파고드는 글들이다. 아래 정리는 교과서 식 커리큘럼이 아니라, 내가 “나중에 다시 찾기 쉬우라고” 써 둔 개인용 안내에 가깝다. 파일시스템, 프로세스 스케줄링, 가상 메모리, 블록·디스크 I/O 네 가지로 줄을 세웠고, 프로덕션에서 자꾸 나오는 “디스크는 남는데 쓰기가 막힌다”, “CPU는 한가한데 응답이 느리다”, “갑자기 OOM으로 죽는다” 같은 이야기를 커널 쪽 눈으로 읽는 데 쓰면 된다.

“한 번에 다 이해”하려 하지 말고, 스토리지 → CPU 스케줄 → 메모리 → I/O 순으로 층을 쌓는 편이 낫다. 나머지(네트워크, 보안, 자동화)는 그다음에 같은 사고 틀에 끼워 넣으면 된다.

SRE·DevOps, 백엔드/인프라 쪽이면 perf, bpftrace, sysctl, cgroup으로 가설을 좁히는 연습이 본문과 맞물린다.

이 시리즈가 잘 맞는 편

  • 프로덕션 Linux에서 장애·성능이 바로 실적으로 이어지는 역할
  • 응용은 쓰는데 VFS·메모리 회수 쪽이 빈 느낌일 때
  • cgroup·NUMA·페이지 폴트 이름은 아는데 문장으로 묶기 어려울 때

덜 맞는 편

  • grep·ssh·systemctl이 아직 어색하면—먼저 셸·권한·패키지 쪽에 손을 익히는 게 낫다.
  • LKM·드라이버 작성이 목표면 이 시리즈는 동작 이해·운영 쪽이고, 개발 루트는 따로 잡는 게 맞다.

처음 서버 터트렸을 때

초보 때였다. 테스트 서버였지만, “백업은 당연히 있겠지” 수준이었고, 디스크가 빡빡한 상태에서 find로 잡다가 rm 파이프를 한 방에 쏴 버렸다. 권한·경로·대상 디렉터리를 끝까지 확인 안 한 채 말이다. 잠시 뒤 서비스가 조용해졌고, 그때서야 journalctl이 아니라 빈 셸부터 봤다. 복구는 남의 백업 덕에 티 안 나게 끝났다. “운 좋은 사고”였지, 실력이 아니었다.

그때 남은 건 튜닝 팁이 아니라 습관이었다. 가정 → 한 번 읽기 → 느리게라도 되돌릴 수 있는가. 대량 I/O·대량 삭제·대역폭·inode는 캐주얼하게 만지지 말 것. 그 뒤로 systemctl·cgroup·df -i를 읽는 이유는 “멋”이 아니라 다시는 그때 같은 헛발질을 덜 하려는 쪽에 가깝다.

이 시리즈를 읽는 사람에게도, 딱 맞는 도구보다 “왜 터지는지”를 커널·블록·메모리 쪽 말로 붙잡는 연습이 더 오래 남는다고 본다.


이 글에 대한 솔직한 쪽지

systemd 논쟁은 이제 그만 보고 싶다. 2020년대에 들어서도 “init 철학”만 밤새 싸울 바에는, systemctl·유닛·journalctl·Restart 정책운영에서 끝까지 쓰는 쪽이 낫다. sysvinit이 그리울 땐 그 환경에서 돌리면 되고, 싫으면 정책으로 “표준은 systemd”밖에 없는 조직이 많다는 것도 사실이다. “진영”이 아니라 장애 때 로그·타임스탬프·depend가 실제로 도움 되느냐로 보는 게 이 인덱스의 기준이다.


시리즈 본문(내가 쓰는 목차)

파일시스템(고급)

#03 파일·inode 내부

읽는 데 대략 30분 안팎(본문 기준), 고급이다. ext4·XFS 온디스크 inode, extent, VFS, 하드 링크, 블록 주소 쪽.

훑을 때: ext4/XFS의 inode가 실제로 어떻게 데이터와 이어지는지, extent가 예전 직접/간접 블록과 뭐가 다른지, dfdf -i용량 full vs inode full을 나누는 법. “디스크는 남는데 파일이 안 만들어진다”를 inode·디렉터리·extent로 설명할 수 있으면 이 편의 목적은 달성이다. 사전으로는 POSIX 모델, stat, ls -i, 링크 차이 정도를 두면 읽기 편하다.


프로세스(고급)

#05 프로세스·스케줄러

30분 대, 고급. task_struct, CFS, vruntime, 런큐, NUMA, cgroup CPU.

훑을 때: 커널이 프로세스/스레드를 어떤 구조로 잡는지, CFS vruntime이 “공정”과 지연 사이에서 어떤 트레이드오프를 만드는지, NUMA·친화성, cgroup으로 CPU 쿼터 둘 때 throttling이 지표에 어떻게 찍히는지. top의 load average가 I/O wait인지 CPU 병목인지 cgroup 제한인지 말로 갈라낼 수 있으면 충분하다. ps, nice, chrt, taskset 개략, K8s requests/limits가 cgroup에 붙는다는 만 있어도 된다.


메모리(고급)

#06 메모리·가상 메모리

30분 대, 고급. MMU, 다단계 페이지 테이블, TLB, Page Fault, ZONE, SLUB, kswapd, OOM, THP, swappiness.

훑을 때: MMU·페이지 테이블·TLB가 성능·격리 둘 다에 왜 쓰이는지, minor/major page fault, COW가 fork·컨테이너·공유에 어떤 의미인지, ZONE·버디·SLUB, kswapd·direct reclaim·OOM, THP·vm.swappiness호불호. free -h·/proc/meminfo캐시·anon·file을 나눌 수 있으면 OK. 가상/물리 주소, mmap 틀, 컨테이너 memory 제한 측정 정도.


디스크·블록(고급)

#09 디스크·블록 계층

30분 대, 고급. ext4/XFS journal, blk-mq, I/O scheduler, iostat, blktrace.

훑을 때: 저널·트랜잭션 복구(정전 뒤 일관성), 할당기·단편화, blk-mq·I/O 스케줄러(none, mq-deadline 등)가 지연/처리량에 끼치는 힘, iostat·blktrace큐·지연 읽기. iostat -x%util·await 등을 “디스크가 나빠서” 한 줄로 못 끊는다는 것까지 이해하면 된다. lsblk, ROTA, NVMe vs SATA의 뉘앙스 정도.


주제를 어디에 꽂을지(개인 색인)

시리즈 본문은 네 편(파일·inode, 프로세스, 메모리, 디스크)에 못 박았다. 아래는 같은 맵에서 IPC·TCP·systemd·SELinux를 어느 축에 붙이는지, 내가 메모로 쓰는 수준의 분류다.

기초: 파일·프로세스

  • VFS·inode·경로#03 + OS 개론의 dentry
  • 스케줄·스레드#05 + 사용자 공간 clone/pthread(라이브러리 따라 다름)
  • 셸·스크립트는 별도 축—자동화는 아래 도구 가이드

시스템 프로그래밍: 메모리·IPC·시그널

  • 가상 메모리·COW#06
  • 파이프·소켓·공유 메모리 → fd·복사 비용·블로킹(본문은 압박·mmap 쪽이 두껍다)
  • 시그널 → #05 맥락과 겹쳐 읽기

네트워크

  • TCP는 블록 I/O와 지연의 문법이 다르다. ss·tcpdump·conntrack·bpftrace 쪽이 자주 붙는다. “언제 sleep 하느냐”는 #05·#06교차가 잘 먹힌다.

성능

  • CPUperf, flame, CFS/throttling·#05
  • 메모리vmstat, OOM, cgroup memory, THP·#06
  • 디스크iostat, pidstat -d·#09
  • eBPFbpftrace—고정 지표가 모자를 때

보안

  • DAC·capabilities·ns = “뭘 열 수 있나”
  • SELinux/AppArmor = “어떤 라벨이 어떤 타입에 닿나”—로그는 audit
  • KASLR·SMEP 같은 이야기는 #06이 있으면 경계가 중요한지 말이 쉬워진다(보안 전문 시리즈는 아님).

운영

  • 배포·systemd·이미지 레이어 → 결국 I/O·inode·cgroup
  • “지연”은 CPU / 메모리 / 디스크 / 네트워크 / 락으로 먼저 쪼갠 뒤, 해당 본문을 연다

내가 돌릴 때 쓰는 순서(참고만)

초·중·고를 따로 표로 나누지 않는다. 대신 첫 바퀴는 보통 #03 → #05 → #06 → #09다. “저장이 어떻게 짜이는가”(#03)에서 “실행/스케줄”(#05), “주소/회수”(#06), “블록 경로”(#09)로 간다. 둘째 바퀴는 장애 유형으로 섞는다: OOM → #06 + cgroup, I/O wait 잦음 → #09, load 높은데 CPU 낮음 → I/O/락/throttling(#05) 쪽.

시스템 프로그래밍으로 깊이 파고 싶으면 C의 open/mmap/epollerrno·부분 쓰기까지, Go·Rust는 시스콜·뮤텍 비용이 #05랑 이야기가 통한다. strace로 시스콜을 보며 #06의 “언제 read가 막히나”를 확인해 보는 식.

동일 주제는 관련 시리즈의 C/Go/Rust 인덱스랑 병행해도 좋다.


시리즈에서 반복하는 톤

  • 자료구조·경로(task_struct, mm_struct 틀)가 /proc 같은 데 어떻게 번역돼 찍히는지
  • 장애 티켓에서 자주 돌아오는 질문(inode, %util 해석, OOM, throttling)에 맥락을 붙이는 쪽
  • sysctl·cgroup·THP·스케줄·큐—효과는 워크로드 따라 다르다는 말을 반복해도 싫지 않다
  • x86/ARM·컨테이너 오버헤드는 같은 말이 다른 H/W에선 다르게 보인다는 전제

실전에서 떠올리는 갈래(고정 루틴 아님)

“디스크 30%인데 작은 파일이 안 붙는다”

inode·dentry 쪽, 할당기/마운트 옵션/쿼터, 컨테이너 overlay의 다른 df 해석. df -h·df -i·(환경 따라) tune2fs·xfs_info, fd 폭주는 lsof#03 쪽.

“API가 튀는데 CPU는 낮다”

디스크 I/O(iostat·pidstat·#09), 메모리 압박(vmstat·dmesg·#06), cgroup throttling(#05), 락·스케일은 사용자 공간+perf off-cpu.

“빌드/배치 후 OOM”

dmesgkilled process, OOM score, cgroup, THP/스왑. drop_caches튜닝이 아니라 잠깐 실험용—운영에 상시 쓰지 말자는 쪽.

“DB 디스크 latency가 기준을 넘는다”

스케줄러/큐(NVMe+mq에서 none vs mq-deadline 등), 저널 모드와 내구성-성능 트레이드(리스크 감수 수준), 가상화 stall·IOPS cap—iostat만으론 “디스크 나쁨”으로 못 끊는다.


각 글에서 다시 찾는 명령(압축)

옵션은 배포·권한에 따라 다르다. 본문이 본다.

#03 파일·inode

df -hT
df -i
stat /path/to/file
ls -li
# tune2fs -l /dev/sdXN
# xfs_info /mount/point

#05 프로세스·스케줄러

ps auxf
ps -L -o pid,tid,psr,comm
taskset -pc <pid>
mpstat -P ALL 1
# find /sys/fs/cgroup -maxdepth 2 -type f -name cpu.stat

#06 메모리

free -h
vmstat 1
dmesg -T | egrep -i "oom|oom-kill|out of memory|reclaim" || true
head -n 40 /proc/meminfo
sysctl vm.swappiness

#09 디스크·블록

lsblk -o NAME,ROTA,TYPE,SIZE,FSTYPE,MOUNTPOINT
iostat -xz 1
pidstat -d 1 -p <pid>
# blktrace — 테스트·정책 맞을 때만

도구 가이드(bash, vim, systemd, docker)

bash(또는 POSIX 셸)

파이프·리다이렉트·set -euo pipefail—운영 사고 꽤 많이 실패를 삼킨 스크립트에서 온다. find·xargs-print0·이스케이프 익힌 다음 대량 rm 자동화. set -x·PS4재현 남기기.

vim(또는 표준 편집기)

서버엔 GUI가 없는 경우가 많다. sudoedit로 권한 실수를 줄이는 쪽.

systemd

systemctl·journalctl·Restart=·LimitNOFILE—유닛 경계에서 fd·리소스. 장애 때 status의 Tasks, coredump, OOM—유닛과 커널을 같이 본다. (위 쪽지 참고: 논쟁보다 로그가 도움 되는가.)

docker(OCI)

이미지·overlay2·빌드 캐시 → inode·용량·#03·#09. memory/cpu limit은 같은 cgroup 말투—값 의미는 v1/v2·런타임에 좌우.


실무 쪽 눈높이(한 줄씩)

DevOps/SRE — SLO의 지연이 CPU·메모리·디스크·네트워크·락 중 어디서 오느냐가 1호. 릴리스가 시스콜·힙·스레드를 바꾸면 같은 H/W에서 병목이 바뀐다. 메트릭 + (필요 시) eBPF로 한 번 잡는 지연.

시스템 관리자 — RAID·LVM·스냅·백업이 #03·#09와 맞닿는다. sudo·audit·SELinux—거절은 앱이 아니라 정책·라벨·로그로 끝날 때가 많다. 커널 채널·재부팅·livepatch는 조직 정책 플러그.


“4주·8주” 대신: 내 캘린더에 쓰는 수준

표로 주차·과제를 박아 두지는 않는다. 시간 있을 때 한 편을 읽고, 한 가지만이라도 df -idmesg로 손에 익힌다. 여유 있으면 8주에 가깝게 늘려서 #03+셸, #05+C·Go, #06+perf, #09+bpftrace처럼 가로로 한 번씩 겹쳐 본다. 목표는 “다 읽기”가 아니라, 한 번 재현한 병목에 가설→완화를 메모에 남기는 것.


FAQ

Q. 이 시리즈 누가 봄?

A. SRE, DevOps, 백엔드/인프라, 시스템 쪽 관심 있으면 와도 됨. 프로덕션에서 장애·성능이 진짜 KPI일 때 맞음.

Q. 선수 필요해?

A. C는 포인터·구조체 정도, Linux 명령이랑 OS 개론 있으면 덜 헤맴. 이랑 /proc 읽기 먼저 익혀도 체감 큼.

Q. 실무에서 바로 씀?

A. ㅇ. df -i, vmstat, iostat 같은 현장 도구랑 sysctl/cgroup 맥락 같이 감. 다만 “한 방 튜닝”은 워크로드 따라 박살 나기 쉬워서 쟁여 보라는 쪽.

Q. 커널 소스 봐야 돼?

A. 필수는 아님. 구조·함수 집어주는 건 이해용. 직접 패치는 빌드·테스트 별도 루트.

Q. 번호가 03·05·06·09만 있어?

A. 이 블로그에 올라온 본문이 그 네 개로 정리돼 있어서 그럼. 번호 비연속일 수 있음—주제로 인덱스 쓰면 됨.

Q. 네트워크·쿠버·보안은?

A. 직접 깊이 파는 축은 커널·스토리지·스케줄·메모리 쪽. 쿠베는 cgroup·ns·네트워크·CSI로 투영됨. 네트워크는 I/O랑 지연 말투가 달라서 위 색인 쪽 “네트워크”만 보조로 쓰면 됨.

Q. ARM(Graviton 같은 거) 같냐?

A. 큰 틀(MMU, TLB, 스케줄, blk-mq)은 비슷. perf 이벤트·캐시·드라이버는 다름 머신에서 perf list·문서로 확인 ㄱ.

Q. 습관 하나만 고르라면?

A. 튜닝·지우기·대량 I/O가정→재고→(가능하면) 롤백 같이. “안 커밋한 시도”가 사고 원인인 경우 많음.


관련 시리즈

  • C 언어 시리즈 — 시스템 프로그래밍·POSIX API
  • Rust 시리즈 — 메모리·FFI 대비
  • Go 시리즈 — 고루틴·사용자 공간 스케줄 vs 커널

추천 자료(참고)

온라인

도구


시작파일·inode (#03)에서 메타데이터·저장 축을 잡고, #05·#06·#09깊이를 더하면 된다. 이 페이지는 교과서가 아니라, 다시 열기 쉬운 개인용 북마크다.


부록: 자주 쓰는 짧은 도구

df -hT, df -i, du --max-depth=1, (환경) tune2fs·xfs_info / uptime, mpstat, pidstat·ps -L / free -h, vmstat 1, dmesg -T / iostat -xz 1, pidstat -d, (고급) blktrace / strace -f -c -p <pid>, (허가 시) perf.

짧은 나열만으로도 “어느 축”으로 갈지 첫 10분은 잡는다. 원인-근거-완화는 위 본문·갈래를 차례로 연다.


품질·갱신

  • updatedDate — frontmatter updatedDate는 편집 흐름에 따라 수동 갱신.
  • readingMinutes — frontmatter 기존 값 유지. 실제로는 실습·되돌아 읽기까지 합치면 걸릴 수 있음.
  • 링크/blog/...빌드 기준. 로컬에선 라우트 확인.

배포 전에는 팀 루틴(git addcommitpushnpm run deploy 등)에 맞추면 됨.