Wasm C++ 篩選器
此沙箱示範了一個基本的 C++ 編寫的 Envoy Wasm 篩選器,該篩選器將內容注入到 HTTP
回應的主體中,並新增和更新一些標頭。
它還將引導您完成建置自己的 C++ Wasm 篩選器,並使用 Envoy 執行它的步驟。
步驟 1:啟動所有容器
首先,讓我們啟動容器 - 一個使用 Wasm 篩選器的 Envoy 代理,以及一個回顯我們請求的後端。Envoy 組態公開了兩個監聽器,第一個監聽器在 8000 埠中,其中包含監聽器篩選器鏈中的 wasm 篩選器。第二個監聽器在 8001 埠中,路由到包含叢集篩選器鏈中 wasm 篩選器的叢集。
變更到 Envoy 儲存庫中的 examples/wasm-cc
資料夾,然後啟動組合
$ pwd
envoy/examples/wasm-cc
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------
wasm_proxy_1 /docker-entrypoint.sh /usr ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp
wasm_web_service_1 node ./index.js Up
步驟 2:檢查 Web 回應
當您向代理發出請求時,Wasm 篩選器應將「Hello, world」插入回應主體的末尾。
$ curl -s https://127.0.0.1:8000 | grep "Hello, world"
}Hello, world
篩選器也會將 content-type
標頭設定為 text/plain
,並新增自訂 x-wasm-custom
標頭。
$ curl -v https://127.0.0.1:8000 | grep "content-type: "
content-type: text/plain; charset=utf-8
$ curl -v https://127.0.0.1:8000 | grep "x-wasm-custom: "
x-wasm-custom: FOO
在第二個監聽器中,也可以獲得類似的輸出,該監聽器會路由到具有上游 wasm 篩選器的叢集。
$ curl -s https://127.0.0.1:8001 | grep "Hello, world"
}Hello, world
$ curl -v https://127.0.0.1:8001 | grep "content-type: "
content-type: text/plain; charset=utf-8
$ curl -v https://127.0.0.1:8001 | grep "x-wasm-custom: "
x-wasm-custom: FOO
步驟 3:編譯更新後的篩選器
為 Wasm 篩選器提供了兩個原始碼檔案。
envoy_filter_http_wasm_example.cc
提供內含預先建置二進位檔案的原始碼。
envoy_filter_http_wasm_updated_example.cc
對原始檔案進行了一些變更。
以下差異顯示了已進行的變更
--- /tmp/tmpiw2hzbvp/generated/rst/start/sandboxes/_include/wasm-cc/envoy_filter_http_wasm_example.cc
+++ /tmp/tmpiw2hzbvp/generated/rst/start/sandboxes/_include/wasm-cc/envoy_filter_http_wasm_updated_example.cc
@@ -65,8 +65,8 @@
for (auto& p : pairs) {
LOG_INFO(std::string(p.first) + std::string(" -> ") + std::string(p.second));
}
- addResponseHeader("X-Wasm-custom", "FOO");
- replaceResponseHeader("content-type", "text/plain; charset=utf-8");
+ addResponseHeader("X-Wasm-custom", "BAR");
+ replaceResponseHeader("content-type", "text/html; charset=utf-8");
removeResponseHeader("content-length");
return FilterHeadersStatus::Continue;
}
@@ -78,9 +78,9 @@
return FilterDataStatus::Continue;
}
-FilterDataStatus ExampleContext::onResponseBody(size_t body_buffer_length,
+FilterDataStatus ExampleContext::onResponseBody(size_t /* body_buffer_length */,
bool /* end_of_stream */) {
- setBuffer(WasmBufferType::HttpResponseBody, 0, body_buffer_length, "Hello, world\n");
+ setBuffer(WasmBufferType::HttpResponseBody, 0, 17, "Hello, Wasm world");
return FilterDataStatus::Continue;
}
警告
這些編譯更新後 Wasm 二進位檔案的說明使用 envoyproxy/envoy-build-ubuntu 映像檔。您將需要 4-5 GB 的磁碟空間來容納此映像檔。
從您的主機系統匯出 UID
。這將確保在建置容器內建立的二進位檔案與您的主機使用者具有相同的權限
$ export UID
注意
建置組合的設計方式與 Envoy 儲存庫中的 ./ci/run_envoy_docker.sh
命令類似。
Bazel 暫時性成品是在 /tmp/envoy-docker-build
中使用從 UID
環境變數取得的 uid 建立的。
停止代理伺服器,然後使用更新後的程式碼編譯 Wasm 二進位檔案
$ docker compose stop proxy
$ docker compose -f docker-compose-wasm.yaml up --remove-orphans wasm_compile_update
編譯後的二進位檔案現在應該在 lib
資料夾中。
$ ls -l lib
total 120
-r-xr-xr-x 1 root root 59641 Oct 20 00:00 envoy_filter_http_wasm_example.wasm
-r-xr-xr-x 1 root root 59653 Oct 20 10:16 envoy_filter_http_wasm_updated_example.wasm
步驟 4:編輯 Dockerfile 並重新啟動代理
編輯範例中提供的 Dockerfile-proxy
配方,以使用您在步驟 3 中建立的更新後二進位檔案。
找到將 Wasm 二進位檔案新增到映像檔的 COPY
行
1FROM envoyproxy/envoy:dev
2COPY ./envoy.yaml /etc/envoy.yaml
3COPY ./lib/envoy_filter_http_wasm_example.wasm /lib/envoy_filter_http_wasm_example.wasm
4RUN chmod go+r /etc/envoy.yaml /lib/envoy_filter_http_wasm_example.wasm
5CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "--service-cluster", "proxy"]
將此行替換為以下內容
COPY ./lib/envoy_filter_http_wasm_updated_example.wasm /lib/envoy_filter_http_wasm_example.wasm
現在,重建並啟動代理容器。
$ docker compose up --build -d proxy
步驟 5:檢查代理是否已更新
Wasm 篩選器應改為將「Hello, Wasm world」插入回應主體的末尾。
$ curl -s https://127.0.0.1:8000 | grep "Hello, Wasm world"
}Hello, Wasm world
content-type
和 x-wasm-custom
標頭也應已變更
$ curl -v https://127.0.0.1:8000 | grep "content-type: "
content-type: text/html; charset=utf-8
$ curl -v https://127.0.0.1:8000 | grep "x-wasm-custom: "
x-wasm-custom: BAR
另請參閱
- Envoy Wasm 篩選器
關於 Envoy Wasm 篩選器的更多資訊。
- Envoy Wasm API (V3)
Envoy Wasm API - 第 3 版。
- Proxy Wasm C++ SDK
代理的 WebAssembly (C++ SDK)