Ssoon

[7주차] 요청 경로에서 Istio 확장 : WebAssembly로 Istio의 Data Plane 확장 본문

Istio Hands-on Study [1기]

[7주차] 요청 경로에서 Istio 확장 : WebAssembly로 Istio의 Data Plane 확장

구구달스 2025. 4. 23. 16:57

🚀 WebAssembly로 Istio 데이터 플레인 확장하기

  • Istio의 데이터 플레인을 확장하는 가장 강력한 방법 중 하나는 WebAssembly(WASM) 를 사용해 커스텀 Envoy 필터를 만드는 것입니다.
  • WASM의 기본 개념과 Envoy에서 WASM을 활용해 동적으로 필터를 추가하는 방법을 설명합니다. 기존 필터 설정이나 Lua 스크립트와 달리, WASM은 다양한 언어로 작성된 커스텀 필터런타임에 배포할 수 있는 유연성을 제공합니다.
WebAssembly를 사용하면 커스텀 Envoy 필터를 동적으로 배포해
Istio 데이터 플레인을 확장할 수 있습니다.

🛠️ WebAssembly란?

WASM의 기본 개념

  • WebAssembly(WASM)는 다양한 프로그래밍 언어로 작성된 코드를 이식 가능한 바이너리 형식으로 컴파일가상 머신(VM)에서 실행하는 기술입니다. WASM은 원래 웹 브라우저에서 CPU 집약적인 작업을 고속으로 실행하기 위해 개발되었으며, 2019년 W3C 권고안으로 채택되었습니다. 현재 모든 주요 브라우저에서 지원됩니다.

  • 컴팩트한 크기: 모듈 크기와 로드 시간이 작음.
  • 고성능: 네이티브 코드에 가까운 실행 속도.
  • 안전성: 메모리 안전과 샌드박스 실행 환경으로 호스트 시스템 보호.
  • 제한된 접근: 호스트가 허용한 메모리와 기능에만 접근 가능.
WASM은 이식 가능하고 안전한 바이너리 형식으로,
브라우저와 같은 환경에서 고성능으로 실행됩니다.

🔧 Envoy에서 WebAssembly 사용 이유

기존 Envoy 필터의 한계

  • 기존 방식으로 Envoy 필터를 작성하는 데는 두 가지 주요 단점이 있습니다:
    • C++ 사용: 필터를 C++로 작성해야 하며, 이는 복잡하고 전문 지식이 필요.
    • 정적 빌드: 커스텀 필터를 Envoy 바이너리에 정적으로 빌드해야 하므로, 커스텀 Envoy 빌드를 유지보수해야 함.

  • WASM은 이러한 단점을 해결합니다:
    • 다양한 언어 지원: C++, Rust, Go 등 WASM으로 컴파일 가능한 언어로 필터 작성 가능.
    • 동적 로드: Envoy의 WASM 실행 엔진을 통해 런타임에 필터를 동적으로 로드, 별도의 바이너리 빌드 불필요.
    • Istio 호환성: Istio의 기본 Envoy 프록시를 유지하면서 커스텀 필터 추가 가능.
WASM은 C++ 없이 다양한 언어로 커스텀 필터를 작성하고,
런타임에 동적으로 로드해 Envoy를 확장할 수 있게 합니다.

📌 핵심 요약

  • WebAssembly란?: WASM은 이식 가능하고 고성능인 바이너리 형식으로, 샌드박스 VM에서 안전하게 실행됩니다.
  • Envoy와 WASM: WASM을 사용하면 C++ 없이 다양한 언어로 커스텀 Envoy 필터를 작성하고, 런타임에 동적으로 로드할 수 있습니다.
  • 장점: 정적 빌드의 복잡성을 없애고, Istio의 기본 Envoy 프록시를 유지하면서 유연한 확장이 가능합니다.
  • 활용 사례: WASM HTTP 필터를 통해 요청 경로에서 커스텀 로직을 실행하며, 데이터 플레인을 확장할 수 있습니다.

🚀 WebAssembly로 Envoy 필터 개발하기


🛠️ WASM 필터 개발 준비

개발 환경 설정

  • WASM으로 Envoy 필터를 개발하려면 다음 사항을 고려해야 합니다:
    • 언어 선택: WASM으로 컴파일 가능한 언어(C++, Rust, AssemblyScript, TinyGo).
    • Envoy 버전: 사용 중인 Envoy 버전과 호환되는 Abstract Binary Interface(ABI) 확인.
    • 빌드 도구: 언어별 SDK와 빌드 체인 설정.
  • AssemblyScript(TypeScript 기반 언어)를 사용하며, wasme 도구(Solo.io 제공)를 활용해 설정을 간소화합니다.
    wasmeWASM 필터 프로젝트를 빠르게 초기화하고 빌드 과정을 자동화합니다.
WASM 필터 개발은 언어, Envoy 버전, 빌드 도구를 고려하며,
wasme로 설정을 간소화할 수 있습니다.

 


🔧 meshctl로 WASM 필터 생성

meshctl 설치 및 프로젝트 초기화

  • meshctl은 WASM 모듈을 생성, 빌드, 배포하기 위한 도구로, Docker와 유사한 사용자 경험을 제공합니다.
    먼저 meshctl을 설치합니다:
$ docker exec -it myk8s-control-plane bash
root@myk8s-control-plane:/# cd && pwd
/root
root@myk8s-control-plane:~# curl -sL https://run.solo.io/meshctl/install | GLOO_MESH_VERSION=v2.5.0 sh
Attempting to download meshctl version v2.5.0
Downloading meshctl-linux-amd64...
Download complete!, validating checksum...
Checksum valid.
meshctl was successfully installed 🎉

Add the Gloo Mesh CLI to your path with:
  export PATH=$HOME/.gloo-mesh/bin:$PATH

Now run:
  meshctl install     # install Gloo Mesh management plane
Please see visit the Gloo Mesh website for more info:  https://www.solo.io/products/gloo-mesh/
root@myk8s-control-plane:~# tree .gloo-mesh/
.gloo-mesh/
`-- bin
    `-- meshctl

2 directories, 1 file


root@myk8s-control-plane:/# meshctl install
 INFO  💻 Installing Gloo Platform components in the management cluster
 SUCCESS  Finished downloading chart.
 SUCCESS  Finished installing chart 'gloo-platform-crds' as release gloo-mesh:gloo-platform-crds
 SUCCESS  Finished downloading chart.
 ...
   ERROR   installing gloo-platform: installing helm chart: execution error at (gloo-platform/templates/licenses.yaml:30:10): A Gloo Mesh Enterprise license key is required
  • Gloo Mesh Enterprise의 설치 오류 A Gloo Mesh Enterprise license key is required를 해결하기 위해 라이선스 키 없이 Gloo Mesh를 사용하는 방법은 Gloo Mesh 오픈 소스 버전을 설치하는 것입니다
root@myk8s-control-plane:/# helm repo add gloo-platform https://storage.googleapis.com/gloo-platform/helm-charts
"gloo-platform" has been added to your repositories

root@myk8s-control-plane:/# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "gloo-platform" chart repository
Update Complete. ⎈Happy Helming!⎈

root@myk8s-control-plane:/# kubectl create namespace gloo-system
namespace/gloo-system created

root@myk8s-control-plane:/# helm install gloo-mesh gloo-platform/gloo-platform \
  --namespace gloo-mesh \
  --set global.glooMesh.licenseKey="" \
  --set gloo-mesh-enterprise.enabled=false \
  --set common.cluster="my-cluster"
NAME: gloo-mesh
LAST DEPLOYED: Tue May 20 04:26:01 2025
NAMESPACE: gloo-mesh
STATUS: deployed
REVISION: 1
TEST SUITE: None
  • Gloo Mesh 오픈 소스 vs. Enterprise:
    Gloo Mesh 오픈 소스 버전은 WebAssembly(WASM) 확장 기능을 기본적으로 지원하지 않습니다. WASM 지원은 주로 Gloo Mesh Enterprise 버전에서 제공되는 기능입니다.
    meshctl wasm 명령어는 Gloo Mesh Enterprise에서 WASM 필터를 초기화하거나 관리하는 데 사용됩니다. 오픈 소스 버전에서는 이 명령어가 지원되지 않을 수 있습니다. => 실패!
meshctl wasm init ./hello-wasm --language=assemblyscript
  ERROR   unknown command "wasm" for "meshctl"
  • 이 명령어는 hello-wasm 폴더를 생성하고, AssemblyScript 프로젝트의 기본 파일(index.ts)과 의존성을 설정합니다. index.ts에는 HTTP 응답에 헤더를 추가하는 기본 구현이 포함되어 있습니다.
meshctl은 WASM 필터 프로젝트를 초기화하고,
AssemblyScript로 기본 구현을 제공합니다.

🛠️ WASM 필터 코드 살펴보기

AssemblyScript 구현

  • hello-wasm/assembly/index.ts 파일에는 두 개의 주요 클래스가 정의되어 있습니다:
    • AddHeaderRoot: WASM 모듈의 커스텀 설정을 관리.
    • AddHeader: 요청/응답 처리 콜백 함수를 구현.
  • 아래는 응답에 hello 헤더를 추가하는 onResponseHeaders 함수의 예입니다:
class AddHeader extends Context {
  root_context: AddHeaderRoot;
  constructor(root_context: AddHeaderRoot) {
    super();
    this.root_context = root_context;
  }
  onResponseHeaders(a: u32): FilterHeadersStatusValues {
    const root_context = this.root_context;
    if (root_context.configuration == "") {
      stream_context.headers.response.add("hello", "world!");
    } else {
      stream_context.headers.response.add("hello", root_context.configuration);
    }
    return FilterHeadersStatusValues.Continue;
  }
}
  • 주요 콜백 함수는 다음과 같습니다:
    • onRequestHeaders: 요청 헤더 처리
    • onRequestBody: 요청 본문 처리
    • onResponseHeaders: 응답 헤더 처리
    • onResponseBody: 응답 본문 처리
AssemblyScript로 작성된 WASM 필터는 요청/응답의 헤더나 본문을 조작하며,
다양한 콜백 함수를 제공합니다.

🔍 WASM 모듈 빌드 및 배포

모듈 빌드

  • hello-wasm 폴더에서 WASM 모듈을 빌드합니다:
meshctl wasm build assemblyscript ./hello-wasm/ -t webassemblyhub.io/ceposta/istioinaction-demo:0.1
  • 이 명령어는 AssemblyScript 코드를 WASM 모듈로 컴파일하고, OCI(Open Container Initiative) 이미지로 패키징합니다. 출력물은 .wasm 파일과 메타데이터를 포함합니다.
  • 로컬에 저장된 모듈을 확인합니다:
meshctl wasm list
  • 출력 예시:
NAME                                       TAG  SIZE     SHA
webassemblyhub.io/ceposta/cache-example    1.0  12.6 kB  10addc6d
webassemblyhub.io/ceposta/demo-filter      1.0  12.6 kB  a515a5d2
webassemblyhub.io/ceposta/istioinaction-demo 0.1  12.6 kB  a515a5d2

모듈 배포

  • 빌드된 모듈을 WebAssembly Hub(webassemblyhub.io) 같은 OCI 레지스트리에 업로드합니다:
meshctl wasm push webassemblyhub.io/ceposta/istioinaction-demo:1.0
  • 빌드된 OCI 이미지를 확인하려면 로컬 저장소를 살펴봅니다:
ls -l ~/.gloo-mesh/wasm/store/bc234119a3962de1907a394c186bc486/
  • 출력 예시:
total 28
-rw-r--r-- 1 solo solo  224 Jul 2 19:04 descriptor.json
-rw-rw-r-- 1 solo solo 12553 Jul 2 19:04 filter.wasm
-rw-r--r-- 1 solo solo   43 Jul 2 19:04 image_ref
-rw-r--r-- 1 solo solo  221 Jul 2 19:04 runtime-config.json
  • filter.wasm은 WASM 바이너리이며, 메타데이터 파일은 Envoy 버전 및 ABI 호환성을 나타냅니다.
meshctl로 WASM 모듈을 빌드하고 OCI 이미지로 패키징해
WebAssembly Hub에 배포할 수 있습니다.

📌 핵심 요약

  • WASM 필터 개발: AssemblyScript 같은 언어로 WASM 필터를 작성하며, meshctl로 프로젝트 초기화와 빌드를 간소화합니다.
  • 코드 구조: AddHeader 클래스는 요청/응답의 헤더나 본문을 조작하는 콜백 함수를 구현합니다.
  • 빌드 및 배포: meshctl로 WASM 모듈을 OCI 이미지로 빌드하고, WebAssembly Hub 같은 레지스트리에 업로드합니다.
  • 주의사항: Envoy의 WASM 지원은 실험적이며, 프로덕션 배포 전 철저한 테스트가 필요합니다.
  • 장점: C++ 없이 다양한 언어로 필터를 작성하고, 런타임에 동적으로 로드해 Istio의 데이터 플레인을 확장할 수 있습니다.

🚀 WebAssembly Envoy 필터 배포하기.


🛠️ 배포 준비

환경 초기화 및 서비스 배포

  • 배포를 시작하기 전에 이전 설정을 초기화합니다:
kubectl delete envoyfilter,wasmplugin -n istioinaction --all
  • 테스트를 위해 httpbin 서비스를 배포합니다. 이 서비스는 요청 헤더를 에코하여 필터의 동작을 확인하는 데 유용합니다:
kubectl apply -f ch14/httpbin.yaml
이전 설정을 초기화하고 httpbin 서비스를 배포해 WASM 필터 테스트 환경을 준비합니다.

🔧 WasmPlugin으로 WASM 필터 배포

WasmPlugin 리소스 설정

  • Istio의 WasmPlugin 리소스는 WASM 모듈을 특정 워크로드에 적용하는 선언적 방법을 제공합니다. 아래는 httpbin 워크로드에 WASM 필터를 적용하는 WasmPlugin 설정입니다:
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: httpbin-wasm-filter
  namespace: istioinaction
spec:
  selector:
    matchLabels:
      app: httpbin
  pluginName: add_header
  url: oci://webassemblyhub.io/ceposta/istioinaction-demo:1.0
  • selector: app: httpbin 레이블이 있는 워크로드에 필터 적용.
  • pluginName: 필터의 이름을 add_header로 지정.
  • url: WASM 모듈이 저장된 OCI 레지스트리 URL(이전 섹션에서 업로드한 webassemblyhub.io).
  • 이 설정은 WebAssembly Hub에서 WASM 모듈을 다운로드해 httpbin 워크로드의 Envoy 프록시에 로드합니다.
  • WasmPlugin을 적용합니다:
kubectl apply -f ch14/wasm/httpbin-wasm-filter.yaml
WasmPlugin은 WASM 모듈을 특정 워크로드에 동적으로 로드하며,
OCI 레지스트리에서 모듈을 가져옵니다.

🛠️ WASM 필터 테스트

필터 동작 확인

  • WASM 필터가 제대로 적용되었는지 확인하기 위해 httpbin 서비스에 요청을 보냅니다. 이 필터는 응답에 hello: world! 헤더를 추가하도록 설계되었습니다:
kubectl exec -it deploy/sleep -c sleep -- curl -v httpbin:8000/status/200
  • 응답 예시:
* Trying 10.102.125.217:8000...
* Connected to httpbin (10.102.125.217) port 8000 (#0)
> GET /status/200 HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: envoy
< date: Mon, 06 Dec 2021 16:02:37 GMT
< content-type: text/html; charset=utf-8
< access-control-allow-origin: *
< access-control-allow-credentials: true
< content-length: 0
< x-envoy-upstream-service-time: 3
< hello: world!
<
* Connection #0 to host httpbin left intact
  • 응답에 hello: world! 헤더가 포함되어 있다면 WASM 필터가 정상적으로 동작하는 것입니다.
curl 요청으로 httpbin 서비스를 호출해
WASM 필터가 응답 헤더를 추가하는지 확인할 수 있습니다.

🔍 WASM 필터의 확장 가능성

복잡한 로직 구현

  • 이 예제는 간단한 헤더 추가 기능만 다루었지만, WASM 필터는 더 복잡한 로직을 구현할 수 있습니다. 예를 들어:
    • 요청/응답 본문 수정
    • 외부 서비스 호출
    • 조건부 라우팅 로직
  • WASM의 장점은 다양한 언어(AssemblyScript, Rust, C++ 등)로 필터를 작성하고, 런타임에 동적으로 로드할 수 있다는 점입니다. Istio의 WasmPlugin은 이를 선언적으로 관리해 배포를 간소화합니다.
WASM 필터는 복잡한 로직을 구현할 수 있으며,
다양한 언어와 동적 로드로 유연성을 제공합니다.

📌 핵심 요약

  • 환경 준비: 이전 설정을 초기화하고 httpbin 서비스를 배포해 테스트 환경을 구성합니다.
  • WasmPlugin: Istio의 WasmPlugin 리소스를 사용해 WASM 모듈을 httpbin 워크로드에 적용하며, OCI 레지스트리에서 모듈을 로드합니다.
  • 테스트: curl로 httpbin에 요청을 보내 hello: world! 헤더가 추가되는지 확인해 WASM 필터의 동작을 검증합니다.
  • 확장 가능성: WASM은 복잡한 로직을 다양한 언어로 구현할 수 있으며, 런타임 로드로 커스텀 필터를 유연하게 배포할 수 있습니다.

 

Comments