유니커널(unikernel)은 애플리케이션 자체가 곧 운영체제가 되는 구조다. 별도의 유저랜드가 없고, 웹 서버·DNS·메일 발송처럼 흔히 OS에 기대던 기능을 따로 fork하거나 spawn할 수 없다. 필요하면 그 기능을 애플리케이션 안에 라이브러리로 직접 작성해 넣어야 한다. 바로 이 지점이 지난 10년간 유니커널을 '어려운 기술'로 남겨둔 마찰이었다. 2010년대 중반 OCaml 기반 MirageOS를 다뤘던 이들은 TCP와 HTTPS 스택은 있어도 스토리지 지원이 거의 없어 NetBSD의 드라이버를 유저스페이스로 끌어다 썼다고 회고한다. 그만큼 생태계의 빈칸을 손으로 메워야 했다.
MirageOS와 Unikernel Systems에 몸담았던 저스틴 코맥(Justin Cormack)이 다시 이 주제를 꺼낸 배경에는 변화한 전제가 있다. 그는 뉴스레터 연재를 위해 여러 대화를 진행 중이며, 이 글의 필자가 첫 상대였다. 핵심 주장은 단순하다. 유니커널을 어렵게 만들던 마찰이 사라졌다는 것이다.
운영체제는 설계 부채다
필자의 관점은 도발적이다. 유니커널이 아닌 모든 애플리케이션은 '앱이 있고 그 아래 OS가 있다'는 가정 위에 지어졌는데, 애초에 왜 OS가 필요했는가를 되묻는다. 답은 40년 전 사람인 운영자(operator)가 단말 앞에 앉아 있었기 때문이다. 다중 사용자 운영체제는 그 인간 운영자를 위해 존재했고, 그 위에 애플리케이션을 얹었을 뿐이다. 사람이 더 이상 그 자리에 앉지 않는 시대에 이 구조는 설계 부채로 남는다.
이 부채가 보안에서 문제를 일으킨다. 애플리케이션이 뚫리면(popped) 공격자는 셸을 얻고, 그 셸은 데이터 유출을 돕는 집사 노릇을 한다. 반면 유니커널은 공격 표면이 훨씬 작다. 셸도, 다음 단계로 넘어갈 발판도 없다면 공격자가 할 수 있는 일이 사라진다. 특히 필자는 셸이나 인터프리터가 없으면 'LLM의 가중치 안에 다음에 뭘 해야 할지 아는 지식이 없다'는 점을 강조한다. 프레임워크의 흔한 원격코드실행 취약점으로 손쉽게 셸을 얻어 모델이 자동으로 다음 수를 두던 공격이, 소스코드를 알아야만 가능한 표적 공격으로 바뀐다는 것이다.
코맥은 여기에 공정한 반론을 제기했다. 공격 표면 축소는 사람들이 모호하게 말하는 개념이다. 리눅스 컨테이너에서 셸을 제거해도 거의 모든 환경에는 사실상 인터프리터 역할을 하는 무언가가 남고, 쓰기 가능한 파일시스템이 없어도 새 프로그램을 실행할 수 있으며, 메모리 안전성과 가젯 문제도 여전하다. 다만 필자는 지난 26년간 업계가 '프로덕션에 컴파일러를 두지 말라'에서 빌드/프로덕션 컨테이너 분리, 그리고 Chainguard로 공격 표면을 깎아왔다면, 반대 방향으로 아예 공격 표면이 없도록 가는 편이 낫다고 본다.
마찰을 걷어낸 것은 에이전트
과거 유니커널의 발목을 잡던 '라이브러리 부재'는 이제 다르게 풀린다. OCaml에 Stripe 라이브러리가 없다면, 예전엔 한숨 쉬며 직접 짰다. 지금은 Go 라이브러리를 OCaml로 이식하는 루프를 돌리면 된다. 코맥도 비슷한 사례를 들었다. 어플라이언스용 최소 리눅스 이미지를 만들며 XFS 파일시스템이 필요했을 때, xfsprogs 전체를 끌어오는 대신 에이전트와 함께 mkfs.xfs를 Rust로 다시 작성해 모든 플래그를 해석하고 바이트 단위로 동일한 출력을 내게 했다. 몇 시간이 걸렸다. 원본 도구가 '골든 오라클' 역할을 하기에, 양쪽 구현으로 파일시스템을 생성해 diff하고 테스트를 이식하는 검증 자동화가 가능했던 덕이다.
스토리지라는 또 다른 공백은 클라우드형 아키텍처로 메운다. S3를 무한 확장 가능한 1차 저장소로 두고, 로컬 NVMe 블록 캐시와 LRU로 핫 데이터를 다루는 turbopuffer식 접근이다. 지연시간이 제약이 아니라면 다중 사용자 접근이 가능한 사실상 무한 스토리지를 얻는다. 또한 NixOS의 머신 테스트는 여러 대의 가상 머신을 띄워 네트워크 규칙과 애플리케이션의 상호작용을 검증하게 해주는, 잘 알려지지 않은 강점으로 꼽혔다.
실무자가 가늠해야 할 지점
필자는 7개월 전 자신의 멘탈 모델을 점검하며 마이크로소프트 Orleans를 OCaml로 이식해 유니커널로 돌리는 'Spaceleans'를 일주일 만에 만들었다고 말한다. Orleans는 트랜잭션을 지원하는 분산 액터 시스템으로, 여러 물리 머신을 하나의 주소 공간으로 합친다. 코맥은 이를 '얼랭(Erlang)스럽다'고 평했다. 다만 필자 본인도 공개할 계획은 없다고 밝혔듯, 이는 '유니커널이 어렵다'는 통념을 반증하는 실험일 뿐 곧바로 제품화 가능한 성과는 아니다.
에이전트 친화성 측면에서 OCaml은 매력적으로 거론된다. 모듈 간 펑터, 모듈의 동작을 설명하는 타입드 헤더인 .mli 파일이 에이전트에게 효율적인 컨텍스트가 되고 컴파일도 빠르다는 것이다. 반대로 Rust는 백프레셔는 좋지만 느린 컴파일이 세금처럼 작용한다. LLM의 환각은 컴파일이 느릴수록 분당 시도 횟수가 줄어 비용이 커지고, 100만 줄 규모 프로젝트를 네 에이전트가 동시에 컴파일하면 디스크·CPU 경합으로 토큰보다 빠른 머신에 더 많은 돈을 쓰게 된다.
결국 이 이야기의 설득력은 '보안을 깊이 신경 쓴다면'이라는 전제에 묶여 있다. 단일 특권 레벨에서 OS와 앱을 함께 돌리던 초기 설계의 한계, 커널을 주 단위로 패치하도록 요구받는 현실, 녹화 주간에 Firecracker의 핵심인 KVM이 뚫려 5만 달러 포상이 걸린 사건 같은 맥락이 그 전제를 받친다. 유니커널은 만능이 아니며 메모리 안전성 같은 숙제는 남는다. 그러나 '공격 표면을 계속 깎을 것인가, 아예 없앨 것인가'라는 선택지를 다시 테이블에 올려놓았다는 점만으로도, 두 세대에 걸쳐 그 존재조차 모르고 자란 개발자들이 한 번쯤 들여다볼 가치가 있다.