운영체제 설계에서 모듈화와 커널 확장성을 확보하는 방법
운영체제 설계의 모듈화, 컨테이너 연계, 커널 확장성과 NUMA·I/O 최적화 원칙을 실무 관점에서 정리합니다.
2026-08-14 · 최초 발행 2026-01-16
기능을 나누고 경계를 고정하는 커널 설계
운영체제는 프로세스, 메모리, 파일 시스템, 네트워크, 장치를 한 구조 안에서 다뤄야 한다. 기능을 한 덩어리로 묶으면 변경과 검증의 범위가 커진다. 모듈화는 관련 기능을 모듈 내부에 모으고, 모듈 사이의 의존성을 줄이는 데서 출발한다.
이때 내부 구현은 감추고 인터페이스만 노출해야 한다. 각 모듈에는 단일 책임을 부여하며, 모듈 간 상호작용은 명확한 규약으로 고정한다.
계층화는 이 경계를 구조적으로 드러내는 방식이다. 상위 계층은 아래 계층의 서비스만 사용하고, 하위 구현의 세부사항에 의존하지 않는다. 계층 간 인터페이스가 표준화되면 계층별 개발과 테스트도 분리할 수 있다.
커널 구조는 기능을 어느 주소 공간에 둘지에 따라 달라진다. 모놀리식 커널은 모든 기능을 단일 주소 공간에서 실행한다. 마이크로커널은 최소 기능만 커널에 남기고 나머지를 사용자 공간으로 보낸다. 하이브리드 커널은 두 방식의 장점을 결합하며, 엑소커널은 하드웨어 추상화를 최소화해 애플리케이션에 직접 제어권을 부여한다.
동적 커널 모듈은 기능을 실행 중에 추가하거나 제거하는 확장 경로다. 커널을 다시 컴파일하지 않고 확장할 수 있으며, 모듈 의존성도 자동으로 해결한다.
플러그인 구조 역시 같은 원칙을 따른다. 표준 인터페이스를 정의하고, 런타임에 플러그인을 검색·로딩하며, 플러그인 간 독립성을 보장한다. 실행 중 추가와 제거가 가능한 핫플러그도 이 구조에 포함된다.
컨테이너 워크로드와 만나는 운영체제
마이크로서비스는 컨테이너 기술을 통해 격리된다. 운영체제는 커널 네임스페이스로 리소스를 분리하고, cgroup으로 자원 할당량을 제어하며, 경량 가상화 기술을 활용한다.
컨테이너 런타임은 커널 기능 위에서 동작한다. PID, Network, Mount 네임스페이스는 컨테이너 격리를 담당하고, CPU·메모리·I/O cgroup은 자원 제한을 담당한다. 파일시스템에는 OverlayFS와 AUFS를 사용할 수 있으며, 보안에는 seccomp, AppArmor, SELinux가 연결된다.
서비스 메시 환경에서는 사이드카 프록시를 통한 서비스 통신이 이뤄진다. eBPF 기반 네트워크 가속, DPDK와 XDP 같은 커널 바이패스 기술, 서비스 디스커버리 지원도 함께 고려 대상이 된다.
오케스트레이션 플랫폼과의 접점도 있다. Kubernetes CRI(Container Runtime Interface) 구현, 노드 리소스 모니터링과 보고, CNI 기반 네트워크 플러그인, CSI 기반 스토리지 플러그인을 지원한다.
커널 수준의 관찰성은 메트릭 노출, eBPF 기반 성능 모니터링, 시스템 콜 추적, 네트워크 트래픽 분석으로 이어진다.
코어와 노드가 늘어날 때의 커널 병목
수직 확장에서는 코어 수 증가에 따른 성능 향상, NUMA 메모리 접근의 지역성, 락 스케일링, 퍼-CPU 자료구조가 핵심이 된다. 세분화된 락과 RCU를 사용하고 퍼-CPU 자료구조로 캐시 경합을 줄이는 방식이 여기에 속한다.
워크로드 증가에 대한 대응은 더 큰 서버를 쓰는 수직 확장과 더 많은 서버를 두는 수평 확장으로 나뉜다.
수평 확장에서는 Ceph, GlusterFS 같은 클러스터 파일시스템, 분산 스토리지, 확장 가능한 네트워크 스택, 로드 밸런싱 지원이 필요하다.
락 경합을 줄이기 위해서는 세분화된 락을 적용하고, RCU(Read-Copy-Update)로 읽기 락을 제거하며, 원자적 연산을 활용하는 락 프리 자료구조를 사용할 수 있다. 퍼-CPU 변수도 락 경합 감소에 사용된다.
NUMA 환경에서는 로컬 메모리를 우선 할당하고, NUMA 노드별 메모리 풀을 운용한다. 프로세스 이동에 따른 메모리 마이그레이션과 인터리빙 정책 설정도 메모리 관리 범위에 포함된다.
I/O 확장성은 멀티큐 블록 레이어(blk-mq), 비동기 I/O(io_uring), 다중 I/O 경로(Multipath I/O), I/O 스케줄러 최적화로 다룬다.
인터페이스 선택을 바꾸기 위한 패턴
하드웨어 추상화 계층(HAL)을 두고 드라이버와 커널 코어를 분리하면, 아키텍처 의존 코드를 격리하고 플랫폼 독립적 코드를 작성할 수 있다.
콜백과 이벤트 기반 설계는 인터럽트 핸들러, 파일 시스템 연산, 네트워크 프로토콜 스택 훅, 디바이스 드라이버에 적용된다.
팩토리 패턴은 객체 생성 로직을 감춘다. 파일 시스템 마운트 시 적절한 구현을 선택하거나, 디바이스 드라이버 인스턴스와 프로토콜 핸들러를 생성하는 데 사용된다.
전략 패턴은 교체 가능한 정책을 다룬다. 스케줄링 정책, 메모리 할당 전략, I/O 스케줄러, 파일 시스템 선택이 그 대상이다.
측정 결과로 병목을 다시 확인한다
확장성 평가는 코어 수 증가에 따른 성능, 동시 연결 수 증가, 대량 파일 처리, 네트워크 처리량을 측정하는 방식으로 수행한다.
병목 분석에서는 락 경합, 캐시 미스율, 컨텍스트 스위칭 빈도, I/O 대기 시간을 확인한다. perf 프로파일링 결과를 바탕으로 최적화 지점을 찾고, 코드를 개선한 뒤 다시 측정한다.
벤치마킹에는 LMBench의 마이크로 벤치마크, Phoronix Test Suite의 종합 벤치마크, CPU·메모리·I/O를 다루는 sysbench, 스토리지 I/O를 다루는 fio를 사용할 수 있다.
커널 확장의 최근 접근
Unikernel은 애플리케이션과 커널을 통합하고 불필요한 기능을 제거하는 방식이다. 극도로 작은 이미지 크기와 빠른 부팅 시간을 지향하며 클라우드 환경에 맞춘다.
eBPF는 커널 모듈 없이 커널 기능을 확장하는 방법이다. 커널 검증과 JIT 컴파일을 거쳐 안전하게 실행되며, 네트워크 필터링, 보안 정책, 성능 모니터링에 사용할 수 있다.
Rust 커널 개발은 메모리 안전성, 동시성 안전성, 타입 안전성을 지향한다. Linux 커널 일부에 도입이 시작됐다.