Skip to content

필사 모드: WebAssembly의 다음 10년 심화 가이드 — WASM, WASI, Component Model, Fermyon, Cloudflare Workers, Envoy 플러그인, Docker 통합까지 (2025)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

> **TL;DR** — WebAssembly(WASM)는 2017년 브라우저 4대 벤더 합의로 W3C 표준이 되며 출발했다. 2024-2025년 WASM은 브라우저를 넘어 **서버(Fastly, Fermyon)**, **엣지(Cloudflare Workers, Deno Deploy)**, **플러그인(Envoy, Istio, Redpanda, Kong)**, **블록체인(Substrate, NEAR)**, **AI(ONNX Runtime Web, WebLLM)**까지 확장됐다. 핵심 이점: **5ms 콜드 스타트**(V8 isolate 대비 빠름), **모든 언어 지원**(Rust/Go/C++/Python/Ruby), **강력한 샌드박싱**(deny-by-default). 이 글은 WASM이 '왜 설계됐나'는 역사부터 **스택 머신 바이트코드**, **WASI 시스템 인터페이스**, **Component Model**(WASM의 패키지 시스템), **Fermyon Spin + SpinKube**, **Cloudflare Workers와 V8 Isolate 대비**, **Envoy WASM 플러그인**, **Docker + WASM 통합**(2023)까지 — 현대 분산 시스템의 새 기반 기술을 전 지형도로 정리한다.

WebAssembly는 왜 설계됐는가

asm.js — 2013년의 시작

Mozilla가 2013년 **asm.js**를 제안. JavaScript의 제한된 부분집합을 ahead-of-time 컴파일 가능한 형태로 정의:

function add(x, y) {

x = x | 0 // 정수 강제

y = y | 0

return (x + y) | 0

}

이걸로 **Unreal Engine 3, Unity 3D**를 브라우저에서 실행 가능해졌다. 하지만 JavaScript 문법을 강제로 재해석하는 트릭이라 한계 분명 — 파싱 비용, 숫자 타입 한정.

WebAssembly MVP — 2017년 표준화

Google, Mozilla, Microsoft, Apple이 2015년 합의, 2017년 MVP 릴리스. 브라우저 4사가 **처음으로** 4번째 공식 웹 언어(HTML/CSS/JS에 이어) 합의.

**목표**:

- 네이티브에 가까운 속도

- 안전한 샌드박스

- 기존 웹에 통합

- 언어 중립

**비목표**:

- JavaScript 대체 (보완)

- DOM 직접 조작 (JS 통해 간접)

스택 머신 바이트코드

WASM은 **스택 기반 가상 머신**. JVM과 비슷하지만 훨씬 단순.

예시 — add 함수

(module

(func $add (param $a i32) (param $b i32) (result i32)

local.get $a

local.get $b

i32.add)

(export "add" (func $add)))

**실행 흐름**:

1. `local.get $a` — 스택에 a 푸시 `[a]`

2. `local.get $b` — `[a, b]`

3. `i32.add` — 팝 팝 → 덧셈 → 푸시 `[a+b]`

4. 함수 끝 → 스택 맨 위가 반환값

타입 시스템

- `i32`, `i64` — 32/64비트 정수

- `f32`, `f64` — 부동소수점

- `v128` — SIMD (2019)

- `funcref`, `externref` — 참조 타입

Linear Memory

WASM은 단일 연속 바이트 배열만 가짐. malloc 없음, GC 없음(MVP). 메모리 안전성은 **out-of-bounds check**로만 보장.

(memory (export "memory") 1) ;; 1 page = 64KB

(data (i32.const 0) "Hello")

언어 런타임(Rust alloc, Go runtime)이 linear memory 위에서 자체 allocator 구현.

파싱/검증/실행 속도 — V8 Isolate 대비

| 런타임 | 콜드 스타트 | 메모리 | 격리 수준 |

|---|---|---|---|

| Linux Container | 100-500ms | MB | Process (namespace) |

| **V8 Isolate** (Cloudflare Workers) | 5-10ms | ~3MB | JS context |

| **WASM (Wasmtime)** | **1-5ms** | 1-10MB | Linear memory |

| **WASM (WAMR, micro)** | **< 1ms** | KB | Linear memory |

WASM은 V8 Isolate보다도 빠른 콜드 스타트, 메모리 효율, **언어 무관** 추가 이점.

WASI — POSIX 없는 시스템 호출

브라우저 WASM은 DOM 통해 JS API를 호출. 서버 WASM은? → **WASI (WebAssembly System Interface)**.

WASI 0.1 (Preview 1, 2019)

POSIX 유사한 시스템 호출:

- `fd_read`, `fd_write` — 파일 디스크립터

- `path_open` — 파일 열기

- `clock_time_get` — 시간

- `random_get` — 난수

- `environ_get` — 환경변수

Capability-based Security

WASI의 혁신: **deny-by-default**. 기본적으로 모든 파일/네트워크 접근 차단. 명시적 capability 부여만 접근 가능.

이 명령은 /tmp만 접근 가능

wasmtime run \

--dir=/tmp \

--env API_KEY=xyz \

app.wasm

호스트가 준 capability 외엔 어떤 파일도 못 읽음. Linux의 "일단 다 접근 가능, 거부는 샌드박스"와 반대 철학.

WASI 0.2 (Preview 2, 2024)

Component Model 기반으로 재설계. 인터페이스를 **WIT (WebAssembly Interface Type)**로 정의:

package wasi:http

interface types {

record request {

method: method,

headers: headers,

body: body,

}

}

interface incoming-handler {

handle: func(request: request) -> response

}

이제 각 기능(HTTP, filesystem, keyvalue store)이 독립 인터페이스. 호스트가 원하는 것만 제공.

WASIX — Wasmer의 확장

2023년 Wasmer가 WASI가 너무 제한적이라 주장하며 **WASIX** 포크: threads, sockets, fork/exec, signals 추가. 호환성 논쟁 중.

Component Model — WASM의 패키지 시스템

2024년 WASM 커뮤니티의 가장 큰 주제. "**WASM 모듈 간 타입 안전 상호운용**".

문제

기존 WASM은 `i32`, `i64`만 전달 가능. 문자열도 `(pointer, length)` 쌍. 호출자/피호출자가 메모리 레이아웃을 직접 조율해야.

// JS에서 Rust WASM 호출 — 메모리 수동 관리 지옥

const { memory, alloc, free, greet } = wasmModule.exports

const ptr = alloc(name.length)

new Uint8Array(memory.buffer).set(new TextEncoder().encode(name), ptr)

const resultPtr = greet(ptr, name.length)

// ... 결과 디코딩도 복잡

Component Model 해결

**WIT (Interface Types)**로 고수준 타입 선언:

package example:greeting

world greeter {

export greet: func(name: string) -> string

}

Rust에서:

wit_bindgen::generate!({ path: "wit" });

impl Guest for MyComponent {

fn greet(name: String) -> String {

format!("Hello, {}!", name)

}

}

컴파일하면 `.wasm` + `.wit` metadata. 어느 언어에서든 **타입 안전 호출**:

console.log(greet('World')) // "Hello, World!"

wasmCloud — Component Model을 분산 앱으로

2024년 CNCF Incubating. Erlang/OTP 영향 받은 액터 모델 + Component Model. 각 component가 원격 호출될 수 있고, 재시작/리로드가 투명.

Fermyon Spin — WASM-native 서버리스

2022년 창업(Matt Butcher, Helm/Brigade 창시자). "**Docker는 무겁다, Lambda는 lock-in이다 → Spin**".

Spin 앱 구조

spin.toml

spin_manifest_version = 2

[application]

name = "my-app"

version = "0.1.0"

[[trigger.http]]

route = "/"

component = "hello"

[component.hello]

source = "hello.wasm"

allowed_outbound_hosts = ["https://api.example.com"]

컴포넌트 구현 (Rust):

use spin_sdk::http::{IntoResponse, Request};

use spin_sdk::http_component;

#[http_component]

fn handle_request(req: Request) -> impl IntoResponse {

http::Response::builder()

.status(200)

.body("Hello, WASM!")

.build()

}

spin build

spin up

- **콜드 스타트**: 1-5ms

- **언어**: Rust, Go, JavaScript, Python, Ruby, C#, TinyGo

- **Outbound HTTP, Key-value, SQL, LLM** 내장

SpinKube — 2024년 CNCF Sandbox

K8s에 WASM을 1급 시민으로. kubelet에 `runtimeClass: wasmtime`을 달면 Pod가 WASM으로 실행.

apiVersion: apps/v1

kind: Deployment

metadata: { name: hello-wasm }

spec:

template:

spec:

runtimeClassName: wasmtime-spin-v2

containers:

- name: hello

image: ghcr.io/fermyon/hello:latest

**이득**:

- Pod 수천 개가 한 노드에 (메모리 효율)

- 콜드 스타트 사실상 없음

- Docker 이미지 대신 100KB WASM 바이너리

Cloudflare Workers — V8 Isolate + WASM

2017년 출시. 실제로는 **V8 Isolate** 기반(WASM 아님). 하지만 **WASM을 실행할 수 있다**.

// Cloudflare Worker

export default {

async fetch(request) {

const instance = await WebAssembly.instantiate(wasmModule)

const { resize } = instance.exports

const imageBytes = await request.arrayBuffer()

const resized = resize(imageBytes)

return new Response(resized, { headers: { 'Content-Type': 'image/webp' } })

}

}

**V8 Isolate vs WASM 비교**:

| 특성 | V8 Isolate | WASM |

|---|---|---|

| 언어 | JavaScript만 | 거의 모든 언어 |

| 콜드 스타트 | 5-10ms | 1-5ms |

| 메모리 | 128MB 기본 | 설정 가능 |

| CPU 시간 제한 | 10ms (Free), 50ms (Paid) | 유사 |

| 생태계 | npm | 각 언어 |

Cloudflare는 2024년 **Workers AI**, **Workers for Platforms** 출시, WASM 지원 대폭 확대.

다른 엣지 런타임들

- **Deno Deploy** — V8 isolate + WASM

- **Vercel Edge Functions** — Cloudflare Workers 위에

- **Fastly Compute@Edge** — Wasmtime 기반, **100% WASM 네이티브**

- **AWS Lambda@Edge** — 컨테이너 기반 (WASM 아직 미지원)

- **Netlify Edge Functions** — Deno 기반

**Fastly Compute@Edge**는 WASM-first 최대 사례. Rust/AssemblyScript/Go/JavaScript 지원.

Envoy WASM 플러그인 — Service Mesh 확장

Envoy Proxy(Istio, Consul, Gloo, AWS App Mesh의 데이터 플레인)가 **WASM filter**를 지원. 서비스 메시에 **커스텀 로직**을 코드 레벨로 삽입.

use proxy_wasm::traits::*;

struct MyFilter;

impl HttpContext for MyFilter {

fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {

if self.get_http_request_header(":path").unwrap_or_default().contains("/admin") {

self.send_http_response(403, vec![], Some(b"Forbidden"));

return Action::Pause

}

Action::Continue

}

}

이걸 Envoy에 플러그인으로 주입:

http_filters:

- name: envoy.filters.http.wasm

typed_config:

config:

vm_config:

runtime: "envoy.wasm.runtime.v8"

code: { local: { filename: "my_filter.wasm" } }

**효과**: Envoy 재컴파일 없이, 런타임에 로드. 언어 무관.

Proxy-Wasm 표준

2020년 Envoy/Istio/Apache APISIX/Kong이 합의한 인터페이스. 한 번 쓴 WASM filter가 여러 프록시에서 동작.

다른 WASM 플러그인 생태계

- **Redpanda** (Kafka 대체) — WASM Data Transforms로 토픽 간 처리

- **Kong Gateway** — WASM plugin

- **Dapr** — WASM middleware

- **Shopify Functions** — 2022년 출시, 체크아웃 로직 WASM으로

런타임 비교 — Wasmtime vs Wasmer vs WasmEdge

| 런타임 | 제조사 | 특징 | 용도 |

|---|---|---|---|

| **Wasmtime** | Bytecode Alliance (CNCF) | 가장 표준에 충실, Cranelift JIT | 범용, de facto |

| **Wasmer** | Wasmer Inc. | 다중 컴파일러(LLVM, Cranelift, Singlepass) | 범용, WASIX |

| **WasmEdge** | CNCF | 클라우드 네이티브 최적화, AI | 엣지, AI |

| **WAMR** (Intel) | Intel | 마이크로 런타임 (KB급) | 임베디드, IoT |

| **Wazero** | Tetrate | **Go로 쓰인 zero-dep runtime** | Go 생태계 통합 |

| **V8** | Google | 브라우저 + Node.js + Workers | 브라우저, JS+WASM |

| **JavaScriptCore** | Apple | Safari, Bun | 브라우저 |

Docker + WASM — 2023년 통합

Docker Desktop 4.15(2023.10)이 **WASM 런타임 지원**을 실험적 발표. containerd shim으로 wasmtime/wasmedge/wasmtime 통합.

docker run --runtime=io.containerd.wasmedge.v1 \

--platform=wasi/wasm32 \

myapp:wasm

**Docker + WASM 통합의 의미**:

- 개발자 친숙한 `docker build`/`docker run` 사용 가능

- K8s containerd/CRI-O가 WASM 런타임 지원

- **Docker 대체가 아니라 보완** — 무거운 컨테이너 + 가벼운 WASM 혼용

언어별 WASM 지원

Rust

- **1급 시민**. `rustup target add wasm32-wasi` 만 하면 됨

- `wasm-bindgen` — JS 상호작용

- `wit-bindgen` — Component Model

- 가장 작은 WASM 바이너리 (100KB)

Go

- 1.11부터 지원, 1.21에서 WASI 추가

- **TinyGo** — 작은 바이너리, 마이크로컨트롤러도 가능

- 가비지 컬렉터 때문에 바이너리 큼 (MB 단위)

JavaScript

- 2023년 **Andromeda**, **StarlingMonkey** 런타임 등장

- `componentize-js`, `shopify-wasm-js` 등 도구

- SpinderMonkey 기반

Python

- **py2wasm** (Wasmer)

- **Pyodide** — CPython + NumPy + Pandas를 브라우저에서

- **CPython WASI 빌드** — 3.13부터 실험적 공식 지원

Ruby

- `ruby.wasm` (Matsumoto, 2022)

- MRI(CRuby) WASM 빌드

C# / .NET

- **Blazor WebAssembly** — Microsoft 공식, .NET 런타임을 WASM으로

- AOT 컴파일 가능

Swift

- 2024년 Swift 6.0에서 WASM 공식 타겟 진입

Zig

- 네이티브 지원, LLVM 활용

- 작은 바이너리

SIMD, Threads, Exception Handling

WASM MVP(2017)은 최소한만. 이후 확장:

SIMD (2019, Chrome 91+)

- 128비트 벡터 연산

- AVX 없이도 4x 성능 (이미지, 오디오 처리)

- FFmpeg, OpenCV 포팅 가능

Threads (2019, Chrome 70+)

- `SharedArrayBuffer` 기반

- `pthread` 유사 API

- 브라우저에서 COOP/COEP 헤더 필요

Exception Handling (2023)

- try/catch 직접 지원

- C++ exception, Rust panic 깔끔 처리

Garbage Collection (2023, 일부 구현)

- Java/C#/Kotlin/Dart 효율 지원을 위함

- `anyref`, `eqref`, struct/array ref

Tail Call (2023)

- 함수형 언어의 꼬리 재귀 최적화

브라우저 WASM의 부활

2020년대 초 "브라우저 WASM은 죽었다" 분위기. 2024년 반전:

WebGPU + WASM

- GPU 병렬 연산 + WASM = 브라우저에서 AI 모델 로컬 실행

- **WebLLM** — Llama 2를 브라우저에서 실행

- **Transformers.js** (HuggingFace) — BERT, GPT, Whisper 브라우저

Figma의 WASM

- Figma는 C++ 코어를 WASM으로 포팅 (2016). 지금도 가장 유명한 WASM 성공 사례

- Photoshop Web (Adobe, 2023) 도 WASM 기반

AutoCAD Web, Google Earth, Zoom WebRTC

- 모두 C++ → WASM 포팅

블록체인과 WASM

Substrate (Polkadot)

- Runtime이 WASM으로 저장

- on-chain 업그레이드 = 새 WASM 블록

NEAR Protocol

- Smart contract = WASM

- Rust/AssemblyScript 지원

CosmWasm, Solana (BPF 아님), ICP

- 여러 체인이 WASM을 Smart Contract VM으로 선택

EVM + WASM

- Ethereum의 차세대 eWASM 제안 (실제 롤업)

- Stylus (Arbitrum) — EVM + WASM 병행

AI 시대와 WASM

ONNX Runtime Web

- 브라우저에서 ML 모델 추론

- WASM + WebGL/WebGPU 백엔드

WasmEdge Tensor Extension

- 엣지에서 AI 추론

- LLaMA, Mistral 포터블 실행

llamafile

- 단일 실행파일로 LLM 모델 + WASM 런타임 + llama.cpp

- Mozilla Ocho 프로젝트

실전 채택 시나리오

1. 서버리스 엣지 컴퓨팅

- Cloudflare Workers, Fastly, Spin

- 요청당 수 ms, 글로벌 배포

2. 플러그인 시스템

- Envoy/Istio 트래픽 로직

- Redpanda 데이터 변환

- Figma/Photoshop 이펙트

3. 멀티 언어 라이브러리 공유

- Rust로 쓴 암호화 라이브러리 → JS/Go/Python에서 동일 WASM 사용

- 보안 감사 1회로 다 언어 커버

4. 브라우저 무거운 앱

- AutoCAD, Figma, Photoshop, Zoom

- 네이티브에 근접한 속도

5. 임베디드/IoT

- WAMR 같은 마이크로 런타임

- 디바이스 펌웨어 업데이트를 WASM으로

6. AI 로컬 실행

- 브라우저/엣지에서 모델 추론

- 프라이버시 보장, 서버 비용 0

WASM vs Container — 대체가 아닌 보완

| 축 | Container (Docker) | WASM |

|---|---|---|

| 격리 | OS namespace | Linear memory |

| 이식성 | 플랫폼/CPU별 이미지 | **단일 바이너리** |

| 크기 | 10MB-GB | KB-수십MB |

| 콜드 스타트 | 100ms-수초 | **1-5ms** |

| 시스템 접근 | 전체 (권한 필요) | **deny-by-default** |

| 성능 | 거의 네이티브 | 네이티브의 80-95% |

| 언어 | 무관 | 컴파일 타겟 필요 |

| 레거시 지원 | 모든 Linux 앱 | 포팅 필요 |

현실: **Container + WASM 하이브리드**. Docker Compose에 Spin component 혼용. K8s Pod에 WASM runtimeClass.

10가지 흔한 안티패턴

1. **WASM = JavaScript 대체** — 아님. 보완.

2. **모든 것을 WASM으로** — I/O 무거운 앱은 네이티브가 낫기도

3. **브라우저에서 DOM 직접 조작 기대** — 아직 JS 통해

4. **큰 바이너리 (10MB+) 다운로드** — 컴포넌트 분리 필요

5. **WASI 없이 서버에 시스템 호출** — 실패

6. **SharedArrayBuffer 없이 멀티스레드 기대** — COOP/COEP 헤더 필요

7. **Go WASM 작다고 착각** — TinyGo 써야 작음

8. **Wasmer/Wasmtime 혼용 설치** — 버전 지옥

9. **Component Model 없이 언어 간 호출** — pointer/length 지옥

10. **Docker 대체라고 말하기** — 보완 관계

실전 도입 체크리스트 (2025)

1. **유스케이스 명확화** — 엣지 / 플러그인 / AI / 멀티언어

2. **런타임 선택** — Wasmtime(표준), Wasmer(다목적), WasmEdge(엣지)

3. **언어 선택** — Rust(최소 바이너리), Go/TinyGo, JS, Python

4. **WASI 버전** — Preview 1(주류) vs Preview 2(Component Model)

5. **바이너리 크기 최적화** — `wasm-opt`, strip, LTO

6. **호스트 인터페이스 설계** — 최소 권한, WIT 정의

7. **보안** — capability 명시, 네트워크/파일시스템 제한

8. **Observability** — 로그/메트릭 수집 방법

9. **성능 벤치마크** — 네이티브 대비 80% 이상인지

10. **배포 플랫폼** — Spin/SpinKube / Cloudflare / Fastly / 직접

11. **테스트 전략** — WASI shim 환경

12. **업그레이드 경로** — Component Model 전환 준비

다음 글 예고 — "Edge Computing의 새 시대" — Cloudflare Workers, Vercel, Deno Deploy, Fastly, 그리고 지리적 분산 아키텍처

WebAssembly가 '어디서나 돌아가는 코드'였다면, **Edge Computing**은 '사용자 가까이에서 코드를 돌리는 아키텍처'다. 2017년 Cloudflare Workers로 시작한 엣지 컴퓨팅은 2024-2025년 대부분 SaaS의 기본 인프라가 됐다. 5ms 응답을 당연히 기대하는 시대의 뒷받침이다.

다음 글에서는:

- **CDN에서 Edge Compute로** — 캐시를 넘어 코드 실행

- **Cloudflare Workers, Durable Objects, D1** — 엣지 데이터베이스

- **Vercel Edge Functions + Middleware** — Next.js 통합

- **Deno Deploy** — V8 + TypeScript 네이티브

- **Fastly Compute@Edge** — WASM 네이티브

- **AWS Lambda@Edge, CloudFront Functions** — AWS 답안

- **Fly.io** — 지역 VM 오케스트레이션

- **엣지 데이터베이스** — Turso(libSQL), PlanetScale, Neon

- **Region-aware 아키텍처** — read replica, write region

- **엣지 AI** — Cloudflare Workers AI, Vercel AI SDK

- **Cold start 경쟁** — V8 Isolate vs Container vs Firecracker vs WASM

- **Edge 보안** — DDoS, Zero Trust, mTLS

을 다룬다. '**지구 반대편에서 50ms**'라는 현대 웹 UX 표준이 어떻게 현실이 됐는지, 엣지 아키텍처의 설계 트레이드오프를 추적한다.

현재 단락 (1/315)

Mozilla가 2013년 **asm.js**를 제안. JavaScript의 제한된 부분집합을 ahead-of-time 컴파일 가능한 형태로 정의:

작성 글자: 0원문 글자: 11,100작성 단락: 0/315