共计 8069 个字符,预计需要花费 21 分钟才能阅读完成。
简介: 本文将介绍如何应用 ORAS 客户端将具备容许的媒体类型的 Wasm 模块推送到 ACR 注册库(一个 OCI 兼容的注册库)中,而后通过 ASM 控制器将 Wasm Filter 部署到指定工作负载对应的 Pod 中。Wasm Filter 部署中的所有步骤都应用申明形式,也就是说能够创立一个自定义资源 CRD 来形容 Wasm Filter 的部署。一旦该 CRD 创立之后,ASM 控制器能够将 Wasm 模块加载到数据立体层中的相应 Envoy 代理中,同时在管制立体层中也会创立相应的 Istio EnvoyFilter 自定义资源。
Envoy Filter 介绍
首先回顾一下 EnvoyProxy 的实现机制。Envoy 的外围是一个 L3/L4 网络代理,并反对 L7 代理,通过提供可插入 filter chain 机制容许开发人员编写 filter 来执行不同的工作,譬如咱们罕用到的 HTTP connection manager,将原始字节转换为 HTTP 级别的音讯和事件,还解决所有 HTTP 连贯和申请共有的性能包含拜访日志、tracing 等。
上图能够看到:Downstream 作为连贯到 Envoy 并发送申请以及接管响应的客户端局部,监听器 Listener 组件用于绑定到 IP 地址 / 端口并接管来自 Downstream 上游的连贯。通过配置 Listener,用户能够启用通过代理的流量治理能力,而后应用多个 Filter 加强数据流,多个 Filter 形成了一个 Filter Chain。能够看到通过这些 Filter chain 解决之后,会把申请映射到相应的 Cluster(此处的 Cluster 集群是指 Envoy 连贯到的逻辑上雷同的一组上游主机,与下文中提交的 Kubernetes 集群没有关系),而 Cluster 的作用是负责连贯到一组上游节点服务, 并应用关联的负载平衡策略转发这些申请。
依据解决工作的不同,Envoy Filter 分为三类:
- Listener Filter:用于操作解决 L4 连贯中的元数据。
- Network Filter:用于操作解决 L4 连贯中的原始数据。
- HTTP Filter:用于操作解决 L7 连贯中的 HTTP 申请与响应。
除了这些 built-in Filter 之外,还能够开发自定义的 Filter,可应用 native c++ 编译形式,或是通过 wasm 技术构建 Filter。
此外,Envoy 提供了一组 API,也就是咱们常说的 xDS API。通过这些 API,管制立体能够动静地配置 Envoy 代理。
如上图所示,与进站流量相似,对于出站流量来说,监听器在配置的地址或者端口进行监听网络流量的申请。每个监听器同样会定义一组位于数据门路中的 Filter,并造成一组过滤器链 Filter Chain。通过这样的一组过滤器,用户能够配置 Envoy 来针对出站流量做特定的工作,包含数据协定解决、生成调用的统计信息、执行 RBAC 权限等。
为了更好地了解这些 Envoy Filter 以及 Filter Chain,上面来看一个理论的例子。这个就是 Istio 官网示例 bookinfo 中的第一个服务 productpage。首先, productpage pod 中 Envoy Proxy 配置了一个监听 9080 端口的监听器,进入这个 pod 的端口 9080 上的流量申请都会被拦挡到这个 proxy 中,而后申请就会通过这些 Filter Chain 进行解决。具体如下:
- 第一个 filter 是 envoy.filters.network.metadata_exchange,它的次要作用顾名思义,用来在 filter 之间替换元数据。
- 第二个 filter: envoy.http_connection_manager,它上面通常会有以下几个跟 http 特定的 filter,包含:envoy.filters.http.wasm/envoy.wasm.metadata_exchange(用于元数据交互)Istio_authn filter(用于受权认证)envoy.filters.http.cors(解决跨域资源共享的 filter)envoy.filters.http.fault(故障注入过滤器,能够用来测试微服务架构中容错能力,用户能够自定义错误代码来实现延时注入或者终止申请,在不同的失败场景下提供错误处理的能力,例如服务失败、服务过载、服务高延时等状况,这个也是较为罕用的 filter)envoy.filters.http.wasm/envoy.wasm.stats、envoy.filters.http.wasm/xxx-wasmfilter(用户自定义的 wasm 实现的 filter)envoy.filters.http.router(实现 HTTP 转发,简直所有 HTTP 场景下都会应用到这一过滤器)
备注:能够通过申请这个 URL 地址获取配置信息:kubectl exec -it [productpage-xxx] -c istio-proxy curl
localhost:15000/config_dump
增加新的 Filter
Envoy 社区曾经提供了若干个 Built-in Filters,具体参见:
https://www.envoyproxy.io/doc…。
在服务网格中,能够通过 API 启用这些 Built-in Filter 能力。
如果这些 Built-in Filter 无奈满足需要,还能够通过自定义 Filter 实现,有以下两种形式:
- 动态预编译 :将其余过滤器集成到 Envoy 的源代码中,并编译新的 Envoy 版本。这种办法的毛病是您须要保护 Envoy 版本,并一直使其与官网发行版放弃同步。因为 Envoy 是用 C++ 实现的,因而新开发的过滤器也必须用 C++ 实现。
- 动静运行时加载 :在运行时将新的过滤器动静加载到 Envoy 代理中。为了简化扩大 Envoy 的过程, 通过引入 WebAssembly 技术 – 它是一种无效的可移植二进制指令格局,提供了可嵌入和隔离的执行环境。
应用 Wasm 扩大 Envoy Proxy 的优缺点
在理论利用中,会依据以下优缺点来决定是否应用 Wasm 这种形式扩大 Envoy Filter。
Pros
- 敏捷性:过滤器能够动静加载到正在运行的 Envoy 过程中,而无需进行或从新编译。
- 可维护性:不用更改 Envoy 本身根底代码库即可扩大其性能。
- 多样性:能够将风行的编程语言(例如 C/C++ 和 Rust)编译为 WASM,因而开发人员能够抉择实现过滤器的编程语言。
- 可靠性和隔离性:过滤器会被部署到 VM 沙箱中,因而与 Envoy 过程自身是隔离的;即便当 WASM Filter 呈现问题导致解体时,它也不会影响 Envoy 过程。
- 安全性:过滤器通过预约义 API 与 Envoy 代理进行通信,因而它们能够拜访并只能批改无限数量的连贯或申请属性。
Cons
- 性能约为 C++ 编写的原生动态编译的 Filter 的 70%。
- 因为须要启动一个或多个 WASM 虚拟机,因而会耗费肯定的内存使用量。
- The WebAssembly ecosystem is still young。
envoy-wasm 运行机制
如下图所示,envoy-wasm 运行机制包含以下几个步骤:
- Wasm 二进制代码须要可能被动静加载进来,无论是通过 local file 形式还是 xds 近程获取形式。
- 一个 Wasm filter 是否被容许加载,须要一致性校验:https://github.com/proxy-wasm…。
- 一旦被加载之后,Wasm filter 就成为 filter chain 的一部分,当新的申请进来之后,还是先进入到原生的 filter,之后进入到 Proxy-Wasm 扩大控制器。
- Proxy-Wasm 扩大控制器会依据在 filter chain 中定义的 configuration 信息,调用并执行注册的校验过的这些 Wasm filter。
- 内置的 Wasm runtime 反对:LLVM-based WAVM ~20MB, and V8 ~10MB。
- 事件驱动模型。
- 兼容 native filter 调用形式。
如下所示,是下发到 Envoy Proxy 侧的一个 Wasm Filter 的配置内容。
以上讲述了 Envoy Filter 以及通过 Wasm 扩大的形式,引出了 Wasm filter 机制,这将是将来的支流形式。
在一个服务网格体系中,如何以无效并且简略的形式来治理 Wasm filter 的部署运行,将是云产品须要解决的一个问题。
OPAS 及 Wasm filter 注册库
在 Cloud Native 生态系统中,如何治理一个 Artifact 文件,置信绝大多数人会想到 oci 标准规范,是否能够像治理 Docker 镜像那样去治理这些 Wasm filter。
ORAS 我的项目就是用来解决这个问题的,它的全称为 OCI Registry As Storage。ORAS 是 OCI Artifacts 我的项目的参考实现,能够显著地简化 OCI 注册库中任意内容的存储。
应用 ORAS API/SDK Library 能够构建自定义工具,实现以下性能:
- 将 WebAssembly 模块推入到 OCI 注册库中。
- 从 OCI 注册库中拉取 WebAssembly 模块。
oras cli 的应用相似于 docker cli,如下所示:
以阿里云容器镜像服务企业版 ACR EE 为例,作为企业级云原生利用制品治理平台,曾经提供了容器镜像、Helm Chart 以及合乎 OCI 标准的制品的生命周期治理。开明之后,创立一个镜像仓库,会调配一个地址,提供了 vpc 和公网两种形式。
应用 oras login 命令行登录, 执行以下命令:
oras login –username=< 登录账号 >
acree-1-registry.cn-hangzhou.cr.aliyuncs.com
通过 oras push 命令推送, 执行以下命令:
oras push acree-1-registry.cn-hangzhou.cr.aliyuncs.com//asm-test:v0.1 –manifest-config runtime-config.json:application/vnd.module.wasm.config.v1+json example-filter.wasm:application/vnd.module.wasm.content.layer.v1+wasm
留神参数 –manifest-config,能够参考 Wasm Artifact 镜像标准。
Wasm filter 被推送到 ACR EE 注册库中之后,能够查看相干信息,如下:
阿里云服务网格 ASM 架构
在阿里云服务网格 ASM 产品中是如何应用 Wasm 技术呢?首先咱们理解一下 ASM 产品的技术架构,如下图所示。作为业内首个全托管 Istio 兼容的服务网格产品,ASM 的定位是专一打造全托管、平安、稳固、易用的服务网格,以及反对跨地区多集群、多云混合云服务的对立治理。管制立体的组件托管在阿里云侧,与数据面侧的用户集群解耦独立,升高用户应用的复杂度,用户只须要专一于业务利用的开发部署。在托管模式下,放弃与 Istio 的兼容,反对申明式的形式定义灵便的路由规定,反对多个 Kubernetes 集群的对立流量治理。
服务网格 ASM 作为连贯下层利用和上层计算基础设施的重要环节,能够分为 3 个角度来了解:
- 从向下与基础设施交融的角度
- 服务网格本身的能力建设的角度
- 向上反对应用层以及被集成能力的角度
其中, 从服务网格本身的能力建设来看,ASM 作为一个托管的服务网格产品,提供了柔性架构,能够反对不同版本的、定制的 Istio 管制面与数据面 Proxy 代理。
- 在托管侧,将管制面外围组件进行革新托管,并负责整个管制面和数据面组件的生命周期治理。在产品能力方面,ASM 在 Mesh CA、平安审计方面做了加强晋升网格实例的平安度;把客户场景的常见问题造成了诊断规定,用户能够自行运行诊断剖析。
- 在做外围托管侧的建设之外,ASM 优化整合了阿里云的多个产品服务,如:在可观测性方面,整合了 xtrace、arms、日志服务等;在跨 vpc 网络买通方面整合了 cen,实现多集群的互联互通;在限流方面集成了 AHAS 的限流服务。
- ASM 还集成扩大了社区开源的组件能力,包含在平安方面的 OPA 平安引擎的反对、spiffe/spire 的反对、envoyfilter 的扩大反对等。所以这一部分须要提供一种简略无效的形式帮忙用户轻松扩大这些能力。
在阿里云 ASM 中应用 Wasm
随着新架构的优化,WebAssembly 技术被引入服务网格中,解决代理扩大的问题。这样一来,ASM 架构就变成了“托管的高可用弹性控制立体 + 可扩大的插件式的数据立体“的模式。
阿里云服务网格 ASM 产品中提供了对 WebAssembly(WASM)技术的反对,服务网格应用人员能够把扩大的 WASM Filter 通过 ASM 部署到数据面集群中相应的 Envoy 代理中。通过 ASMFilterDeployment Controller 组件, 能够反对动静加载插件、简略易用、以及反对热更新等能力。
通过这种过滤器扩大机制,能够轻松扩大 Envoy 的性能并将其在服务网格中的利用推向了新的高度。
上面咱们具体来看在 ASM 实例中是怎么启用这个能力的?
部署一个 ASM 实例之后,默认该性能是没有开启的,用户须要被动去开启。例如通过如下 aliyun cli 形式:
aliyun servicemesh UpdateMeshFeature --ServiceMeshId=xxxxxx --WebAssemblyFilterEnabled=true
开启该性能之后,ASM 实例会部署相干组件并执行如下工作:
- 部署一个 DaemonSet(asmwasm-controller) 到 K8s 集群中。
- asmwasm-controller 监听一个 configmap,该 configmap 寄存要拉取的 wasm filter 的地址,例如:acree-1-registry.cn-hangzhou.cr.aliyuncs.com/_*_/sample:v0.1。
- 如果须要受权认证,该 asmwasm-controller 会依据定义的 pullSecret 值取得相应的 secret 值。
- 而后,调用 oras API 从注册库中动静拉取 Wasm filter。
- 该 asmwasm-controller 应用 HostPath 形式挂载 volume,所以拉取的 Wasm filter 会落盘到对应的节点上。
启用了该性能之后,如何开始部署一个 Wasm filter 并挂载到对应 workload 的 Envoy Proxy 中呢?
阿里云服务网格 ASM 产品提供了一个新的 CRD ASMFilterDeployment 以及相干的 controller 组件。这个 controller 组件会监听 ASMFilterDeployment 资源对象的状况,会做 2 个方面的事件:
- 创立出用于管制面的 Istio EnvoyFilter Custom Resource,并推送到对应的 asm 管制面 istiod 中。
- 从 OCI 注册库中拉取对应的 wasm filter 镜像,并挂载到对应的 workload pod 中。
以下是一个 ASMFilterDeployment CR 示例:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMFilterDeployment
metadata:
name: details-v1-wasmfiltersample
spec:
workload:
kind: Deployment
labels:
app: details
version: v1
filter:
parameters: '{"name":"hello","value":"hello details"}'
image: 'acree-1-registry.cn-hangzhou.cr.aliyuncs.com/asm/asm-test:v0.1'
imagePullOptions:
pullSecret: 'asmwasm-cache'
rootID: 'my_root_id'
id: 'details-v1-wasmfiltersample.default'
生成的 Istio Envoy Filter 资源如下所示:
其中,match 片段中定义了 envoy.router 这个 filter、patch 片段中定义了 INSERT_BEFORE 操作,插入一个 Wasm filter,如下:
挂载了 Wasm filter 的工作负载定义更新后如下,其中以 hostpath 形式挂载 Wasm filter 文件到 Proxy 容器中:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
.…
spec:
….
template:
metadata:
annotations:
sidecar.istio.io/userVolume: '[{"name":"wasmfilters-dir","hostPath":{"path":"/var/local/lib/wasm-filters"}}]’sidecar.istio.io/userVolumeMount: '[{"mountPath":"/var/local/lib/wasm-filters","name":"wasmfilters-dir"}]'
确认 Wasm filter 是否失效。登录到 productpage Pod 的 istio-proxy 容器中,执行以下命令,将一些流量发送到 details 服务上。在响应中,能够看到过滤器的头增加到响应头中。
kubectl exec -ti deploy/productpage-v1 -c istio-proxy -- curl -v http://details:9080/details/123
* Trying 172.21.9.191...
* TCP_NODELAY set
* Connected to details (172.21.9.191) port 9080 (#0)
> GET /details/123 HTTP/1.1
> Host: details:9080
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
xxxxxxx
< resp-header-demo: added by our filter
xxxxx
* Connection #0 to host details left intact
xxxxx
总结
在开发阶段:
依照如下流程,应用适当的 wasm sdk/ 编程语言,创立编译出一个 wasm 二进制文件,通过应用 oras cli 上传到 oci 镜像仓库中。
在部署运行阶段:
首先确认曾经在 ASM 中开启 Wasm 反对能力,而后创立一个 ASMFilterDeployment 自定义资源,留神这个 CR 是在服务网格 ASM 实例对应的 apiserver 中创立。一旦创立,相应的 crd controller 会监听同步相应的资源,一方面生成一个 Istio EnvoyFilter CR 并发送到 ASM 实例的管制面 apiserver 中,用户能够查看生成的这个 Istio Envoyfilter CR 是否满足冀望。
另一方面,确认 Workload 部署变更失效,包含:
- 能够登录到 proxy container 进行查看 Wasm filter 是否挂载胜利。
- 通过调整 wasm log level 来打印相干信息。
作为业内首个全托管 Istio 兼容的服务网格产品,阿里云服务网格(简称 ASM)是一个对立治理微服务利用流量、兼容 Istio 的托管式平台,专一打造全托管、平安、稳固、易用的服务网格,反对跨地区多集群、多云混合云服务的对立治理。通过流量管制、网格观测以及服务间通信安全等性能,服务网格 ASM 能够全方位地简化您的服务治理,并为运行在异构计算基础设施上的服务提供对立的治理能力,实用于 Kubernetes 集群、Serverless Kubernetes 集群、ECS 虚拟机以及自建集群。
作者:王夕宁 阿里云高级技术专家,阿里云服务网格 ASM 技术负责人,专一于 Kubernetes、服务网格以及其余云原生畛域。
原文链接
本文为阿里云原创内容,未经容许不得转载