Istio 实战:WasmPlugin(Proxy-Wasm 插件)开发(实现限流和修改请求和响应的 header)

news2024/9/29 7:33:10

更多 istio 文章:Istio 专栏目录

WasmPlugin 的典型应用

  1. 限流:当前 envoy 提供的限流能力虽然比较强大,但主要提供了一些 api,在使用上对用户不够友好,且全局限流对每个请求都调用一次限流服务,性能损耗较大。因此,可以通过开发限流过滤器,提高易用性和时延
  2. 应用层协议解析:主要是能实现对 http 协议中 request 和 response 的 header 和 trailer 进行自定义开发

环境准备

proxy-wasm sdk 有支持多语言开发(点击前往),本实例以 go 语言为例(github 地址)

kubernetes

kubernetes 安装省略
示例使用的 kubernetes 版本为 1.23.4

istio

istio 安装省略
示例使用的 istio 版本为 1.16.3

docker

docker 安装省略
打包镜像使用

go

go 安装省略

tinygo

此 SDK 由 TinyGo 提供支持,不支持官方的 Go 编译器。因此需要安装 tinygo(tinygo 安装指南)
以 windows 安装为例,官网提供了四种安装方式
在这里插入图片描述
如下所示,下载压缩包后解压到指定位置
在这里插入图片描述
将 bin 路径添加到环境变量 Path 中
在这里插入图片描述
此时运行 tinygo version 应该输出版本信息
在这里插入图片描述

镜像仓库

推荐使用阿里云镜像仓库,主要是免费!(点击前往)

示例一:修改请求和响应的 header

示例代码 github 地址(点击前往)
如果对您有帮助,请点个免费的 star,谢谢!

创建 go 项目

创建好文件夹后执行 go mod init go-wasm 生成依赖管理工具

添加 main.go

// 读取 wasmplugin crd 中的 pluginConfig 内容
var customData string

func (p *pluginContext) OnPluginStart(pluginConfigurationSize int) types.OnPluginStartStatus {
	proxywasm.LogDebug("loading plugin config")
	data, err := proxywasm.GetPluginConfiguration()
	if data == nil {
		return types.OnPluginStartStatusOK
	}

	if err != nil {
		proxywasm.LogCriticalf("error reading plugin configuration: %v", err)
		return types.OnPluginStartStatusFailed
	}

	// 插件启动的时候读取配置
	customData = string(data)

	return types.OnPluginStartStatusOK
}

// Additional headers supposed to be injected to response headers.
var additionalResponseHeaders = map[string]string{
	"who-am-i":      "go-wasm-extension",
	"injected-by":   "istio-api!",
	"devloper-name": "mm",
	"which-header":  "response",
	// 定义自定义的header,每个返回中都添加以上header
}

// 修改 respense headers
func (ctx *httpHeaders) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action {
	//添加 headr
	for key, value := range additionalResponseHeaders {
		proxywasm.AddHttpResponseHeader(key, value)
	}

	//为了便于演示观察,将配置信息也加到返回头里
	proxywasm.AddHttpResponseHeader("customData", customData)
	return types.ActionContinue
}

// Additional headers supposed to be injected to request headers.
var additionalRequestHeaders = map[string]string{
	"devloper-name": "mm",
	"which-header":  "request",
}

// 修改 request headers
func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
	//添加 headr
	for key, value := range additionalRequestHeaders {
		proxywasm.ReplaceHttpRequestHeader(key, value)
	}
	return types.ActionContinue
}

添加 dockerfile

FROM scratch

COPY main.wasm ./plugin.wasm

go 代码生成 wasm 文件

tinygo build -o main.wasm -scheduler=none -target=wasi main.go

生成镜像,推送阿里仓库

# 注意最后面的点号 .
docker build -t registry.cn-hangzhou.aliyuncs.com/ydkmm/wasm:4 .

docker push registry.cn-hangzhou.aliyuncs.com/ydkmm/wasm:4 

部署 demo 程序

参考 httpbin 程序(点击前往)

部署 wasmplugin

执行 kubectl apply -f go-wasm.yaml 创建资源

注意和之前的 httpbin 程序在同一命名空间

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: my-wasm
  namespace: mm-wasm
spec:
  selector:
    matchLabels:
      app: httpbin
  ## 编译好的镜像
  url: oci://registry.cn-hangzhou.aliyuncs.com/ydkmm/wasm:3
  #插件的配置信息,在代码中可以获取到json string
  pluginConfig:
    testConfig: abcddeeeee
    listconfig:
     - abc
     - def

查看效果

浏览器访问 httpbin 服务
在这里插入图片描述
f12 查看具体的 header
在这里插入图片描述
在这里插入图片描述

示例二:限流

示例代码 github 地址(点击前往)
如果对您有帮助,请点个免费的 star,谢谢!

核心代码

主要是通过当前请求的时间戳和记录的令牌桶填充时间 lastRefillNanoSec 对比,超过 1s 则重新填充令牌桶并刷新 lastRefillNanoSec,否则令牌数量减一

// 令牌桶限流
current := time.Now().UnixNano()
// We use nanoseconds() rather than time.Second() because the proxy-wasm has the known limitation.
// TODO(incfly): change to time.Second() once https://github.com/proxy-wasm/proxy-wasm-cpp-host/issues/199
// is resolved and released.
if current > ctx.pluginContext.lastRefillNanoSec+1e9 {
	ctx.pluginContext.remainToken = 5
	ctx.pluginContext.lastRefillNanoSec = current
}
proxywasm.LogCriticalf("Current time %v, last refill time %v, the remain token %v",
	current, ctx.pluginContext.lastRefillNanoSec, ctx.pluginContext.remainToken)
if ctx.pluginContext.remainToken == 0 {
	if err := proxywasm.SendHttpResponse(403, [][2]string{
		{"powered-by", "proxy-wasm-go-sdk!!"},
	}, []byte("rate limited, wait and retry."), -1); err != nil {
		proxywasm.LogErrorf("failed to send local response: %v", err)
		proxywasm.ResumeHttpRequest()
	}
	return types.ActionPause
}
ctx.pluginContext.remainToken -= 1

查看效果

在浏览器上每次点击刷新会使令牌桶减一,快速刷新,在 1s 内超过5次,则页面显示被限速
在这里插入图片描述
查看日志可以看到具体的操作流程
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1379190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM-SpringMVC+Spring+Mybatis

创建项目 创建好 项目后, 项目目录分析 数据库设计 我们采用员工表 Employee 与 部门表 Department 部门表 表设计--- 员工表 --表设计 因为有文件上传操作,因此 建立 info表 (其中 员工只能隶属一个部门,因此 两张表之间 有外键关系) java 代码 设计 数据库建立完毕后,需要…

自定义数据实现SA3D

SA3D:Segment Anything in 3D with NeRFs 实现了3D目标分割 原理是利用SAM(segment anything) 模型和Nerf分割渲染3D目标, SAM只能分块,是没有语义标签的,如何做到语义连续? SA3D中用了self-prompt, 根据前一帧的mask…

C#编程-了解线程的优先级

了解线程的优先级 控制线程行为的一个属性是它的优先级。.NET运行时环境基于它们的优先级执行线程。CPU一次仅执行一个线程。因此,处于执行的可运行状态的线程,排队等待轮到被处理器执行。线程是固定优先级调度的。带有优先级的每个线程在处理器的线程队列中有自己的位置。 …

Java面试之虚拟机

1、前言 本篇的面试题基于网络整理,和自己编辑。在不断的完善补充哦。 2、什么是虚拟机? Java 虚拟机,是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟机执行的字节码文件( .class )。 Java 被设计成允许应用程…

老胡的周刊(第124期)

老胡的信息周刊[1],记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 QAnything[2] 开源的企业级本地知识库问答解…

Java入门IDEA基础语法

1:Java入门 1.1 Java简介 Java是什么: Java是一门非常优秀的计算机语言 语言:人与人交流沟通的表达方式 计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言 Java之父:詹姆斯高斯林(James Gosli…

深入理解计算机系统(2):信息的表示和处理

信息存储 大多数计算机使用 8 位的块,或者字节(byte),作为最小的可寻址的内存单位,而不是访问内存中单独的位。机器级程序将内存视为一个非常大的字节数组,称为虚拟内存(virtual memory)。内存的每个字节都由一个唯一的数字来标识…

Elasticsearch:是时候离开了! - 在 Elasticsearch 文档上使用 TTL

作者:来自 Elastic David Pilato 想象一下,圣诞老人必须向世界上所有的孩子们分发礼物。 他有很多工作要做,他需要保持高效。 他有一份所有孩子的名单,并且知道他们住在哪里。 他很可能会将礼物按区域分组,然后再交付。…

2024上半年教资笔试报名详细教程1月12日开始报名啦

重点提醒: 1、注册开放时间:2024年1月10日开始。 (参加过笔试的考生,需要重新注册, 不影响已获得的笔试成绩。名额少的考点建议提前注册抢名额) 2、网上报名时间:2024年1月12日至15日。 千万不…

【IDEA--dubug相关】-- 1. 取消debug的所有断点 2. debug侧边栏消失问题

下面是一些经常在日常debug时用到的场景,方便查看、与君共勉! 文章目录 1. 如何取消所有断点2. debug底部左边侧边栏消失 1. 如何取消所有断点 如图我们可能在项目中给很多代码行添加了断点,一个一个点取消麻烦 在debug运行中点击选中底部…

《C语言学习》---郝斌版---笔记

简介 学习计算机,离不开C语言的学习,而C语言学习过程中的视频课教程,目前来说,如果郝斌老师的C语言排第二,没有人敢排第一 郝斌老师的C语言教程,通俗易懂,引人发思,特别适合新手入门…

深度探析卷积神经网络(CNN)在图像视觉与自然语言处理领域的应用与优势

目录 前言1 CNN网络结构与工作原理1.1 输入层1.2 卷积层1.3 最大池化层1.4 全连接层 2 应用领域2.1 图像视觉领域中CNN的应用2.2 NLP领域中CNN的应用 3 CNN的限制与未来展望3.1 CNN的挑战3.2 CNN的展望 结语 前言 卷积神经网络(CNN)作为一种强大的深度学…

2023一带一路暨金砖国家技能发展与技术创新大赛“网络安全”赛项省选拔赛样题卷①

2023金砖国家职业技能竞赛"网络安全" 赛项省赛选拔赛样题 2023金砖国家职业技能竞赛 省赛选拔赛样题第一阶段:职业素养与理论技能项目1. 职业素养项目2. 网络安全项目3. 安全运营 第二阶段:安全运营项目1. 操作系统安全配置与加固任务一Linux …

DNS解析和主从复制

一、DNS名称解析协议 二、DNS正向解析 三、DNS主从复制 主服务器 从服务器

2024年湖北职称评审对论文的要求

1.期刊发表版面的时间节点2024年12月及之前 2.期刊是正规的期刊,有国内刊号 3.期刊能在国家出版社总署检索到 4.文章内容查重符合知网查重标准 5.论文方向和申报专业方向一致 6.必须要是第一作者或者独著 7.评正高的人才们要准备中文核心论文两篇或出版专业学术论著…

人工智能的现状及今后发展趋势展望

人工智能(Artificial Intelligence, AI)作为当今科学技术领域的一个热门话题,已经逐渐影响到了人们的生活方方面面。在过去的几十年里,人工智能领域取得了巨大的发展,并且展现出了巨大的潜力。然而,随着时间…

【Python】新鲜出炉的海洋捕食者算法Python版本

2020年发表的海洋捕食者算法《Marine Predators Algorithm: A nature-inspired metaheuristic》。 作者只在原论文中给出了MATLAB代码,网上也没有Python版本,我自己用Python重写了MATLAB代码。 """2020海洋捕食者算法 """…

Python元组(tuple)

目录 元组元组的创建和删除访问元组元素修改元组元组方法 元组 元组是有序且不可更改的集合。在 Python 中,元组是用圆括号编写的。 元组的创建和删除 实例 创建元组: thistuple ("a", "b", "c") print(thistuple)删除…

微软等开源评估ChatGPT、Phi、Llma等,统一测试平台

微软亚洲研究院、中国科学院自动化研究所、中国科学技术大学和卡内基梅隆大学联合开源了,用于评估、分析大语言模型的统一测试平台——PromptBench。 Prompt Bench支持目前主流的开源、闭源大语言模型,例如,ChatGPT、GPT-4、Phi、Llma1/2、G…

Ps:操控变形

Ps菜单:编辑/操控变形 Edit/Puppet Warp 操控变形 Puppet Warp命令能够借助网格随意扭曲特定图像区域,同时可保持其他区域不变。 其应用范围小至精细的图像修饰(如发型设计),大至总体的变换(如重新定位手臂…