使用wasm扩展envoy

Rust开发技术学习路线

导言    Rust是Mozilla公司推出的一门全新的编程语言,1.0版本于2015年5月15日正式对外发布。Rust的设计目标是要做一门系统编程语言,运行性能高、避免几乎所有的段错误(Segmentation Fault)和保证线程安全。这意味着Rust可…

envoy wasm 介绍

WebAssembly是一种沙盒技术,可用于扩展Istio代理(Envoy)。Proxy-Wasm沙箱API取代了Mixer作为Istio中的主要扩展机制。

WebAssembly沙箱目标:

  • 效率 -扩展增加了低延迟,CPU和内存开销。

  • 功能 -扩展可以执行策略,收集遥测和执行有效载荷突变。

  • 隔离 -一个插件中的编程错误或崩溃确实会影响其他插件。

  • 配置 -使用与其他Istio API一致的API配置插件。扩展名可以动态配置。

  • Operator -可以扩展扩展并将其部署为仅日志,失败打开或失败关闭。

  • 扩展开发人员 -该插件可以用几种编程语言编写。

istio社区基于官方envoy的基础上fork 了 https://github.com/istio/envoy,在wasm分支以实现istio wasm支持,当前官方envoy暂未支持wasm

架构

  • 筛选器服务提供程序接口(SPI),用于为筛选器构建Proxy-Wasm插件。

  • Envoy中嵌入了Sandbox V8 Wasm Runtime。

  • headers, trailers 和 metadata的host api。

  • 调出用于gRPC和HTTP调用的API。

  • Stats和Logging API,用于度量和监视

使用wasm扩展envoy

通过js生成wasm实现envoy header的修改

代码实现

使用 solo.io提供的proxy-runtime通过js来实现wasm逻辑

  1. git clone https://github.com/solo-io/proxy-runtime

  2. mkdir wasm-addheader

  3. npm install --save-dev assemblyscript

  4. npx asinit .

修改package.json

  1. "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --validate --use abort=abort_proc_exit --sourceMap --debug",

  2. "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --validate --use abort=abort_proc_exit --sourceMap --optimize",

修改依赖为 proxy-runtime的本地路径

  1. "@solo-io/proxy-runtime": "file:/root/proxy-runtime"

该示例判断配置的header value是否存在,不存在设置则添加 hello:worldheader,
设置则为 hello:configvalue通过逻辑实现:

  1. export * from "@solo-io/proxy-runtime/proxy"; // this exports the required functions for the proxy to interact with us.

  2. import { RootContext, Context, RootContextHelper, ContextHelper, registerRootContext, FilterHeadersStatusValues, stream_context } from "@solo-io/proxy-runtime";


  3. class AddHeaderRoot extends RootContext {

  4. configuration : string;


  5. createContext(context_id: u32): Context {

  6. return ContextHelper.wrap(new AddHeader(context_id, this));

  7. }

  8. }


  9. class AddHeader extends Context {

  10. root_context : AddHeaderRoot;

  11. constructor(context_id: u32, root_context:AddHeaderRoot){

  12. super(context_id, root_context);

  13. this.root_context = root_context;

  14. }

  15. onResponseHeaders(a: u32): FilterHeadersStatusValues {

  16. const root_context = this.root_context;

  17. if (root_context.getConfiguration() == "") {

  18. stream_context.headers.response.add("hello", "world!");

  19. } else {

  20. stream_context.headers.response.add("hello", root_context.getConfiguration());

  21. }

  22. return FilterHeadersStatusValues.Continue;

  23. }

  24. }


  25. registerRootContext((context_id: u32) => { return RootContextHelper.wrap(new AddHeaderRoot(context_id)); }, "add_header");

编译

  1. npm run asbuild

配置envoy

我们配置了一个返回admin接口的listener,在filter中添加了我们的 add_header wasm plugin

  1. admin:

  2. access_log_path: /tmp/admin_access.log

  3. address:

  4. socket_address: { address: 127.0.0.1, port_value: 9901 }


  5. static_resources:

  6. listeners:

  7. - name: listener_0

  8. address:

  9. socket_address: { address: 0.0.0.0, port_value: 10000 }

  10. filter_chains:

  11. - filters:

  12. - name: envoy.http_connection_manager

  13. typed_config:

  14. "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager

  15. stat_prefix: ingress_http

  16. use_remote_address: true

  17. codec_type: AUTO

  18. route_config:

  19. name: local_route

  20. virtual_hosts:

  21. - name: local_service

  22. domains: ["*"]

  23. routes:

  24. - match: { prefix: "/" }

  25. route: { cluster: some_service }

  26. http_filters:

  27. - name: envoy.filters.http.wasm

  28. config:

  29. config:

  30. name: "add_header"

  31. root_id: "add_header"

  32. configuration: "what ever you want"

  33. vm_config:

  34. vm_id: "my_vm_id"

  35. runtime: "envoy.wasm.runtime.v8"

  36. code:

  37. local:

  38. filename: /media/optimized.wasm

  39. allow_precompiled: false

  40. - name: envoy.router

  41. clusters:

  42. - name: some_service

  43. connect_timeout: 0.25s

  44. type: STATIC

  45. lb_policy: ROUND_ROBIN

  46. load_assignment:

  47. cluster_name: some_service

  48. endpoints:

  49. - lb_endpoints:

  50. - endpoint:

  51. address:

  52. socket_address:

  53. address: 127.0.0.1

  54. port_value: 9901

测试访问

我们将编译好的文件通过volume挂在进容器

  1. docker run -it --net=host --entrypoint=bash -v /media:/media istio/proxyv2:latest

  2. envoy -c /media/t.yaml

通过curl测试访问:

  1. curl http://172.16.233.129:10000/ -I

  2. HTTP/1.1 200 OK

  3. content-type: text/html; charset=UTF-8

  4. cache-control: no-cache, max-age=0

  5. x-content-type-options: nosniff

  6. date: Fri, 05 Jun 2020 16:00:57 GMT

  7. server: envoy

  8. x-envoy-upstream-service-time: 0

  9. hello: what ever you want

  10. transfer-encoding: chunked

可以看到返回的header已经包含 hello:what ever you want

Dfinity上“领英”distrikt注册用户超过2万|Dfinity周报第3期

原力区原作 本篇是原力区第3期Dfinity周报啦,内容会从数据角度展示了项目一周内在代币经济和网络状态方面的变化,从一个较长的周期来观察Dfinity的发展。 随后,我们会同步社区一周的动态,会包括但不限于有关Dfinity项目进展、生态、合作、技术解读等。…

Click to rate this post!
[Total: 0 Average: 0]

人已赞赏
Rust开发每日优选

WASM智能合约优势分析

2021-8-13 15:25:34

Rust开发小白百科每日优选

Rust 和 Wasm 的融合,使用 yew 构建 web 前端(4)- 获取 GraphQL 数据并解析

2021-8-13 15:26:12

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索