runwasi 심은 containerd 런타임 계층에서 어떤 역할을 맡나?
runwasi는 containerd의 shim API를 구현해 Wasmtime·WasmEdge·Wasmer·WAMR 같은 Wasm 런타임을 containerd가 관리하는 프로세스로 편입시키는 라이브러리다. 즉 Wasm 모듈을 OCI 이미지와 같은 경로로 pull·run·stop시켜, Kubernetes 입장에서는 runc 컨테이너와 구분 없이 스케줄링 대상이 되게 만든다.containerd/runwasi 2026년 기준 이 구조는 Azure Kubernetes Service, Civo, SpinKube에서 production으로 쓰이고 있다는 점이 2025 KubeCon EU 발표에서 확인된다.
- runwasi는 새 런타임이 아니라 shim 계층이다 — 실행 자체는 Wasmtime 등 하위 런타임이 맡는다.
- Wasm 워크로드는
RuntimeClass로 runc 워크로드와 노드 풀 단위로 분리해 스케줄링하는 것이 실제 운영 방식이다. - 메모리 footprint 우위는 여러 실험에서 재현되지만, startup time 우위는 스케일에 따라 흔들린다.
- 판단 기준: 지연은 cold start에서, 격리는 런타임·RuntimeClass 선택에서, 비용은 메모리 footprint에서 갈린다.
이번 글에서는 runwasi shim이 containerd shim API를 구현해 Wasm 모듈을 실행 상태로 올리는 경로만 뜯는다. Wasm 런타임 내부의 컴파일 최적화나 WASI 스펙 세부 구현은 범위 밖이다.
shim 프로세스는 containerd와 어떻게 통신하나?
containerd는 각 태스크마다 shim 프로세스를 띄우고 gRPC로 생명주기(create/start/kill/delete)를 위임한다. runwasi는 이 shim API를 Rust로 구현해, 컨테이너 런타임 대신 Wasm 런타임을 호출하도록 바꿔 끼운 것이다. containerd 쪽에서 보면 프로세스 관리 방식은 runc 컨테이너와 동일하고, 차이는 shim 내부에서 무엇을 exec하느냐뿐이다. 이 설계 덕분에 containerd의 이미지 관리·네임스페이스·CRI 인터페이스를 그대로 재사용할 수 있다는 점이 runwasi 프로젝트 설명의 핵심 주장이다.
OCI 이미지 경로에 Wasm 모듈이 어떻게 들어가나?
Wasm 모듈은 일반 OCI 레이어처럼 레지스트리에 push/pull된다. runwasi 공식 벤치마크는 ghcr.io/containerd/runwasi/wasi-demo-app:latest와 wasi-demo-oci:latest를 baseline 이미지로 써서 이 경로를 직접 검증한다.runwasi.dev benchmark containerd는 이 이미지를 일반 컨테이너 이미지와 동일하게 캐시·검증하고, 실행 시점에만 shim이 분기해 Wasm 런타임으로 넘긴다. 즉 이미지 배포 파이프라인은 바뀌지 않고 실행기만 교체되는 구조다.
Kubernetes에서 이 경로를 스케줄링에 연결하려면 무엇이 필요한가?
containerd 설정에 runtime_type = "io.containerd.wasmedge.v1"을 추가하고 containerd를 재시작한 뒤, RuntimeClass를 handler: wasmedge로 등록하면 파드가 이 경로를 탄다. WasmEdge 공식 문서는 이 절차를 containerd config default 기반으로 안내한다.WasmEdge Kubernetes 가이드 여기서 RuntimeClass는 nodeSelector: runtime=wasm과 짝을 이뤄, Wasm 워크로드를 별도 노드 풀로 보내는 스케줄링 분리를 실제로 구현한다. 이 지점이 지연·격리·비용 세 축 중 격리에 가장 직접 연결되는 설계 지점이다.
실측 수치는 어느 조건에서, 무엇을 보여주나?
2025년 6월 공개된 Intel4EC WASM 연구는 메모리 사용량 평가에서 containerd 기반 runwasi가 저수준 런타임 대안보다 40.0% 이상 적은 메모리를, 다른 비교 조건에서는 최소 10.9% 적은 메모리를 기록했다고 제시한다. 반면 startup time 평가에서는 10개 컨테이너 동시 실행 기준 9개 대상 중 3위, 400개 컨테이너 기준 4위로 내려앉았고, 상대 수치로 −11.5%, +2.7%, −6.9%, +18.8%가 함께 제시된다. 저자들은 이를 “가장 낮은 메모리 footprint를 갖는 새 WASM 통합”이자 “대안들과 비슷한 수준의 startup time”이라고 정리한다. 요약하면 재현 조건은 containerd + runwasi 조합에서 컨테이너 수를 10개에서 400개로 늘리는 부하 시나리오이며, 메모리는 일관되게 우세, startup time은 규모가 커질수록 순위가 밀린다.
이 통합으로 무엇을 얻고 무엇을 잃나?
얻는 것은 배포 경로의 단일화다. Wasm 모듈이 OCI 이미지·CRI·RuntimeClass 경로에 그대로 올라가므로, 별도의 오케스트레이션 레이어 없이 기존 Kubernetes 클러스터 안에서 Wasm 워크로드를 관리할 수 있다. 메모리 footprint도 위 실측처럼 낮은 편이다. 잃는 것은 확장성 구간에서의 예측 가능성이다. 컨테이너 수가 늘어날수록 startup time 순위가 하위권으로 밀리는 결과가 나오는 만큼, 대규모 동시 스케일 아웃이 잦은 워크로드에서는 다른 런타임과의 벤치마크 재확인이 필요하다. 또한 runwasi 자체는 shim일 뿐이므로, 실제 격리 강도는 선택한 하위 Wasm 런타임(Wasmtime·WasmEdge 등)의 샌드박스 구현에 좌우된다는 의존성도 남는다.
이 조합은 언제 쓰고 언제 피해야 하나?
edge·플러그인·AI 추론같이 콜드 스타트가 1~10ms 단위로 짧아야 하고 메모리 예산이 빡빡한 워크로드에는 WasmEdge/Wasmtime + runwasi 조합이 적합한 후보로 제시된다. 반대로 수백 대 이상 동시 스케줄링이 반복되는 대규모 배치성 워크로드, 혹은 기존 OCI 컨테이너와 성능 특성이 완전히 동일해야 하는 워크로드에는 startup time 순위 하락 구간을 먼저 자체 환경에서 재현해 보는 편이 안전하다. gVisor·Kata·Firecracker처럼 VM 수준 격리가 필요한 경우는 이 비교 축 자체가 다르므로 runwasi 선택 기준에 포함되지 않는다.
핵심 정리
- runwasi는 새 런타임이 아니라 containerd shim API를 구현한 계층으로, Wasm 모듈을 OCI 이미지·CRI 경로에 그대로 태운다.
- Kubernetes 연결은
runtime_type설정과RuntimeClass+nodeSelector조합으로 이뤄지며, 이는 스케줄링 단위의 격리 분리로 직결된다. - 2025년 실측 기준 메모리 footprint는 저수준 대안보다 10.9~40.0% 낮게 나오지만, startup time은 10~400 컨테이너 스케일에서 3~4위(9개 대상 중)로 밀린다.
- 트레이드오프는 배포 경로 단일화·메모리 효율 대 대규모 스케일 구간의 startup time 예측 불확실성이다.
- 적용 경계: 짧은 cold start·낮은 메모리 예산이 중요한 edge/AI 워크로드에는 적합, 대규모 동시 스케줄링이 반복되는 환경에서는 자체 재현 벤치마크가 우선이다.
더 알아보기
컨테이너 오케스트레이션·런타임: 스케줄링부터 네트워킹까지 — 이 주제의 종합 가이드