한컴테크를 통해 한컴의 기술을 공유합니다. 한컴의 프로그래밍, 프레임워크, 라이브러리 및 도구 등 다양한 기술을 만나보세요. 한컴 개발자들의 다양한 지식을 회사라는 울타리를 넘어 여러분과 공유합니다. 한컴이 제공하는 기술블로그에서 새로운 아이디어와 도전을 마주하고, 개발자가 꿈꾸는 미래를 실현하세요.

한컴테크

WASI 표준화로 가능하게 되는 것들


들어서며


WebAssembly(이하 Wasm) 기술이 소개된 지 10년이 되어가면서 최근 웹 개발의 성능을 개선하기 위해서 활발하게 사용되고 있습니다.

Wasm 모듈을 브라우저 외부에서 활용하기 위한 WASI 표준화에 대해 알아보겠습니다. WASI는 2019년 발표된 기술로 Wasm 하위 그룹 WASI.dev(https://wasi.dev/)에서 표준화 작업을 진행하고 있습니다.

그림 출처 : https://wasi.dev/

WASI 소개


WebAssembly System Interface(WASI)는 W3C WebAssembly(Wasm)로 컴파일된 소프트웨어를 위한 시스템 인터페이스 표준 스펙입니다. WASI가 제공하는 인터페이스로 Wasm 애플리케이션은 브라우저 외부에서 클라우드, 임베디드 장치까지 모든 환경에서 실행될 수 있습니다.

WASI는 Wasm 모듈이 File System, Networking, Time, Random 등의 시스템 리소스에 접근할 수 있도록 하는 표준화된 API를 제공합니다.

Wasm과 WASI로 할 수 있는 것

크로스플랫폼 애플리케이션

  • 단일 릴리즈 파일을 Wasm 런타임이 있는 모든 플랫폼에서 실행할 수 있습니다. 모든 프로젝트를 동일한 대상으로 컴파일하고 단일 런타임에서 실행할 수 있습니다.

플랫폼 간의 코드 재사용

  • 클라이언트와 서버, 모바일과 데스크톱의 다양한 플랫폼 간의 애플리케이션 아키텍처에서 코드를 재사용할 수 있습니다. WASI Shell 구현으로 크로스플랫폼 래퍼를 작성하여 라이브러리를 작성할 수도 있습니다.

단일 환경으로 컨테이너화

  • 모든 애플리케이션 간의 종속성을 Wasm 파일로 단일하게 컴파일할 수 있습니다. 다른 종속성을 위한 컨테이너가 필요하지 않기 때문에 사용성이 개선되고, 컨테이너 간의 오버헤드가 줄어들거나 없어지게 됩니다.

WASI 표준화는 진행 중이기 때문에 현재 버전의 WASI로 모든 사례가 가능한 것은 아닙니다.

Wasm 모듈이 WASI를 사용하는 방법

Wasm 모듈은 import 구문으로 표준화된 WASI API 바인딩을 사용할 수 있습니다.

Hosts

  • 호스트는 Wasm 모듈을 실행하는 Wasm 런타임입니다. Google Chrome의 V8과 같은 웹 브라우저의 모듈도 Wasm 런타임입니다.
  • 브라우저 외부에서 Wasm 모듈을 실행할 때는 HTML, CSS, JavaScript 등을 지원하는 전체 브라우저 엔진이 필요하지 않습니다. 호스트로 많이 사용하는 다양한 독립형 Wasm 런타임 / 인터프리터가 있습니다.
    • Wasmtime
    • Lucet
    • Wasmer
    • Wasm3

대부분의 Wasm 런타임 / 인터프리터는 CLI로 사용되거나, 라이브러리 API로 애플리케이션에 연동됩니다.

Guests

  • 게스트는 호스트가 실행하는 Wasm 모듈입니다. Wasm 모듈을 작성하려는 경우 호스트 애플리케이션 내부에서 실행되는 게스트 애플리케이션을 작성하게 됩니다.
  • 호스트는 게스트의 작업을 수행하여 게스트에게 추가 기능을 제공합니다. 이 기능은 importObject에 함수를 전달하여 제공됩니다.

WASI는 호스트가 게스트 Wasm 모듈에 대한 시스템 수준의 작업을 수행하기 위한 표준화된 API 집합입니다. 이러한 방식으로 개발자는 시스템 리소스에 접근할 수 있는 Wasm 모듈을 작성할 수 있습니다.

WASI는 기능 기반의 보안 모델을 사용합니다. 호스트가 게스트 모듈에 기능을 명시적으로 승인해야 게스트 모듈이 작업을 수행할 수 있습니다. 예를 들어 Wasmtime에서 게스트 모듈은 기본적으로 호스트 파일 시스템의 어떤 부분도 접근할 수 없습니다. Wasmtime을 호출하는 사용자는 –mapdir 또는 –dir fla를 설정하여 모듈에 호스트 파일 시스템의 디렉터리에 접근할 수 있는 기능을 부여해야 합니다.

현재 시점에도 WASI의 많은 부분이 아직 제안 상태로 표준화 과제로 남아 있습니다. networking과 같은 시스템 리소스는 아직은 WASI 표준에 포함되지 않았습니다. WASI가 제공하고자 하는 기능 중 filesystem 접근과 같은 일부 기능만 구현이 완료되어 표준화되었습니다.

WASI API


Wasm 바이너리는 Wasm 스펙에 따라 빌드된 모듈이 될 수도 있고, 컴포넌트 모델에 따라 빌드된 컴포넌트가 될 수도 있습니다.

WASI API를 사용하여 Wasm 애플리케이션을 작성하려면 먼저 바이너리 유형을 선정해야 합니다. 사용하려는 Wasm 런타임이 지원하는 WASI 릴리스 버전을 참고합니다.

WASI 0.1

모듈은 초기 버전인 WASI 0.1의 API를 사용할 수 있습니다.

WASI P1 API는 WITX Interface Description Language(IDL)로 정의되었습니다. WASI 0.1 및 WITX에 대한 설명서는 WASI GitHub 저장소의 legacy 디렉터리에서 확인할 수 있습니다.

WASI 0.2

컴포넌트는 2024년 2월에 출시된 WASI 0.2와 컴포넌트 모델을 사용합니다. 어떤 언어(예를 들어 Rust)에서 컴파일된 Wasm 컴포넌트는 다른 언어(예를 들어 Go)에서 컴파일된 컴포넌트와 연동될 수 있습니다. WASI 0.2는 WASI의 미래 기술을 제공합니다.

WASI 0.2는 가장 최신의 WASI 릴리스입니다. WASI 0.2 및 컴포넌트 모델로 설계된 API는 WebAssembly Interface Type(WIT) Interface Description Language(IDL)로 정의됩니다. WIT API의 정의는 Wasm 컴포넌트 바이너리로 구성된 .wit 파일에 작성됩니다. WASI P2에는 다음 인터페이스가 포함되어 있습니다.

APIRepositoryVersion
I/Ohttps://github.com/WebAssembly/wasi-io0.2.0
Clockshttps://github.com/WebAssembly/wasi-clocks0.2.0
Randomhttps://github.com/WebAssembly/wasi-random0.2.0
Filesystemhttps://github.com/WebAssembly/wasi-filesystem0.2.0
Socketshttps://github.com/WebAssembly/wasi-sockets0.2.0
CLIhttps://github.com/WebAssembly/wasi-cli0.2.0
HTTPhttps://github.com/WebAssembly/wasi-http0.2.0

WASI 0.2 API를 사용하면 WIT 정의와 Wasm으로 컴파일할 언어 간의 바인딩을 생성합니다. WIT에 대한 자세한 내용은 컴포넌트 모델 설명서의 WIT 섹션을 참고할 수 있습니다.

Hello WASI


WASI 애플리케이션을 작성하는 예제 프로그램을 작성해 보겠습니다.

우선 호스트로 사용할 Wasm 런타임으로 Wasmtime을 설치합니다. Linux 및 macOS 사용자는 다음 스크립트로 설치할 수 있습니다.

$ curl https://wasmtime.dev/install.sh -sSf | bash

Windows 사용자는 https://github.com/bytecodealliance/wasmtime/releases 페이지에서 MSI 설치 프로그램을 다운로드하여 설치할 수 있습니다.

이제 rustup 도구를 사용하여 Rust가 설치되어 있는지 확인합니다.

$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

Windows 사용자는 https://www.rust-lang.org/tools/install 페이지의 안내에 따라 설치할 수 있습니다.

구현

먼저, cargo를 사용하여 새로운 실행 파일을 생성합니다.

$ cargo new --bin hello_wasi
$ cd hello_wasi

터미널과 특정 디렉토리의 파일에 “Hello world!”를 출력하는 프로그램을 작성하겠습니다.

src/main.rs 파일을 열고 다음과 같이 작성합니다.

rust

use std::io::prelude::*;
use std::fs;
fn main() {
  // `Hello world!` 텍스트를 출력합니다.
  println!("Hello world!");
  // `/helloworld` 디렉토리에 `helloworld.txt` 파일을 생성합니다.
  let mut file = fs::File::create("/helloworld/helloworld.txt").unwrap();
  // 파일에 `Hello world!` 텍스트를 작성합니다.
  write!(file, "Hello world!\n").unwrap();
}

이 코드에서 WASI API를 직접 사용하지 않았지만, 프로그램을 WASI로 컴파일하면 Rust API가 WASI API를 내부적으로 사용하게 됩니다.

이제 WASI를 컴파일할 수 있는 대상으로 추가합니다. rustup 도구에 WASI를 설치하도록 요청하고 프로그램을 WASI로 컴파일합니다.

$ rustup target add wasm32-wasi
$ cargo build --target wasm32-wasi

wasm 파일은 target/wasm32-wasi/debug/hello_wasi.wasm 파일로 컴파일됩니다.

그리고 프로그램이 호스트에서 파일을 생성할 수 있는 접근 권한을 명시적으로 부여해야 합니다. 프로그램이 새로운 파일을 생성하기 때문에 기능 권한을 부여하지 않으면 게스트는 해당 기능을 사용할 수 없습니다.

디렉터리에 쓸 수 있는 기능을 부여하려면 Wasmtime CLI의 –mapdir 플래그를 사용합니다. 

wasmtime --mapdir GUEST_DIRECTORY::HOST_DIRECTORY my-wasi-program.wasm

다음 구문으로 게스트의 가상 파일 시스템에 있는 /helloworld 디렉터리를 호스트 파일 시스템의 현재 디렉터리에 매핑하고, WASI 프로그램을 실행할 수 있습니다.

wasmtime --mapdir /helloworld::. target/wasm32-wasi/debug/hello_wasi.wasm

드디어 터미널에 “Hello World!”가 출력되고, 현재 디렉터리에 “Hello World!” 내용이 저장된 helloworld.txt 파일이 생성되었습니다.

WASI 방향성


WASI 인터페이스의 표준화 작업은 장기적으로 애플리케이션 개발자를 위한 것이 아닙니다. 근본적으로 라이브러리 개발자를 위한 더 낮은 수준의 추상화 작업입니다.

WASI 0.2의 목표는 애플리케이션 개발자에게 Wasm 모듈로 작성할 수 있는 인터페이스를 제공하는 것이 아니라, 프로그래밍 언어의 표준 라이브러리 개발자가 그 환경에서 빌드할 수 있는 안정적인 공통 인터페이스를 제공하는 것입니다.

그림 출처 : WebAssembly Interface Types: Interoperate with All the Things! By Lin Clark / CC BY-SA 3.0 or any later version

Hello WASI 애플리케이션을 다시 작성해 보겠습니다. Rust 웹 프레임워크 Rocket을 사용해서 간단하게 웹 서버를 구축한 예제입니다.

rust

#[macro_use] extern crate rocket;
#[get("/hello/")]
fn hello(name: &str) -> String {
    format!("Hello, {name}!")
}
#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![hello])
}

이 코드에는 Wasm 인터페이스가 전혀 없습니다. 장기적으로 개발자는 표준 라이브러리를 사용하여 코드를 작성한 다음 Wasm 바이너리로 간단하게 컴파일할 수 있을 것입니다.

WASI 0.2는 라이브러리 개발자가 빌드할 수 있는 공통 표준 인터페이스 집합을 제공하기 때문에 이러한 방향으로 나아가는 첫 번째 단계가 될 것입니다.

마치며


Wasm 기술로 웹 환경에서도 최상의 성능으로 애플리케이션을 개발할 수 있습니다. 그리고 WASI를 통해서 이러한 Wasm의 장점을 더 많은 사용자에게, 더 많은 플랫폼에서, 더 많은 경험으로 제공할 수 있게 되었습니다.

WASI 표준화가 가고자 하는 방향은 소프트웨어 개발이 시작된 이후로 항상 존재해 왔던 운영 체제와 프로그래밍 언어의 장벽이 없는 생태계를 구축하는 미래를 향하고 있습니다.

많은 분이 함께하는 기회가 있었으면 합니다!

출처 및 참고


Scroll to Top