MoE 系列(二)|Golang 扩展从 Envoy 接收配置

文|朱德江(GitHub ID:doujiang24)

MOSN 项目核心开发者蚂蚁集团技术专家

MoE 系列(二)|Golang 扩展从 Envoy 接收配置

专心于云原生网关研发的相关工作

本文 1445 字 阅览5 分钟

上一篇咱们用一个简略的示例,体会了用 Golang 扩展 Envoy 的极速上手。

这次咱们再经过一个示例,来体会 Golang 扩展的一个强壮的特性:

从 Envoy 接纳装备

Basic Auth

咱们还是从一个小示例来体会,这次咱们完结规范的 Basic Auth 的认证,与上一次示例不同的是,这次认证的用户暗码信息,需要从 Envoy 传给 Go,不能在 Go 代码中写死了。

完好的代码能够看example-basic-auth[1],下面咱们展开介绍一番。

获取装备

为了更加灵活,在规划上,Envoy 传给 Go 的装备是 Protobuf 的 Any 类型,也就是说,装备内容对于 Envoy 是透明的,咱们在 Go 侧注册一个解析器,来完结这个 Any 装备的解析。

如下示例:

func init() {
	// 注册 parser
	http.RegisterHttpFilterConfigParser(&parser{})
}
func (p *parser) Parse(any *anypb.Any) interface{} {
	configStruct := &xds.TypedStruct{}
	if err := any.UnmarshalTo(configStruct); err != nil {
		panic(err)
	}
	v := configStruct.Value
	conf := &config{}
	if username, ok := v.AsMap()["username"].(string); ok {
		conf.username = username
	}
	if password, ok := v.AsMap()["password"].(string); ok {
		conf.password = password
	}
	return conf
}

这儿为了便利,Any 中的类型是 Envoy 界说的 TypedStruct 类型,这样咱们能够直接运用现成的 Go pb 库。

值得一提的是,这个装备解析,只要在首次加载的时分需要执行,后续在 Go 运用的是解析后的装备,所以,咱们解析到一个 Go map 能够具有更好的运转时功能。

一起,因为 Envoy 的装备,也是有层级联系的,比如 http-filter, virtual host, router, virtual clusters 这四级,咱们也支持这四个层级一起有装备,在 Go 侧来安排 merge。

当然,这个只要在 Go 侧有杂乱的 filter 安排逻辑的时分用得上,后面咱们在 MOSN 的上层封装的时分,能够看到这种用法,这儿暂时不做展开介绍。

认证

详细的 Basic Auth 认证逻辑,咱们能够参考 Go 规范 net/http 库中的 Basic Auth 完结。

func (f *filter) verify(header api.RequestHeaderMap) (bool, string) {
	auth, ok := header.Get("authorization")
	if !ok {
		return false, "no Authorization"
	}
	username, password, ok := parseBasicAuth(auth)
	if !ok {
		return false, "invalid Authorization format"
	}
	if f.config.username == username && f.config.password == password {
		return true, ""
	}
	return false, "invalid username or password"
}

这儿面的parseBasicAuth就是从 net/http 库中的完结,是不是很便利呢。

装备

简略起见,这次咱们运用本地文件的装备方式。如下是要害的装备:

http_filters:
  - name: envoy.filters.http.golang
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
      library_id: example
      library_path: /etc/envoy/libgolang.so
      plugin_name: basic-auth
      plugin_config:
        "@type": type.googleapis.com/xds.type.v3.TypedStruct
        value:
          username: "foo"
          password: "bar"

这儿咱们装备了用户名暗码:foo:bar

预告一下,下一篇咱们会体会经过 Istio 来推送装备,体会一番动态更新装备的全流程。

测验

编译,运转,跟上篇一样,咱们还是运用 Envoy 官方供给的镜像即可。

跑起来之后,咱们测验一下:

$ curl -s -I 'http://localhost:10000/'
HTTP/1.1 401 Unauthorized
# invalid username:password
$ curl -s -I 'http://localhost:10000/' -H 'Authorization: basic invalid'
HTTP/1.1 401 Unauthorized
# valid foo:bar
$ curl -s -I 'http://localhost:10000/' -H 'Authorization: basic Zm9vOmJhcg=='
HTTP/1.1 200 OK

是不是很简略呢,一个规范的 Basic Auth 扩展就完结了。

总结

Envoy 是面向云原生的架构规划,供给了装备动态改变的机制,Go 扩展能够从 Envoy 承受装备,也就意味着 Go 扩展也能够很好的使用这套机制。

Go 扩展的开发者,不需要关心装备的动态更新,只需要解析装备即可,十分的便利~

下一篇咱们会介绍,合作 Istio 来动态更新用户名暗码,体会一番云原生的装备改变体会。

后续还有更多 Golang 扩展的特性介绍,原理解析,以及,更上层的 MOSN 集成体会,欢迎持续关注。

[1]example-basic-auth:

github.com/doujiang24/…

了解更多…

MOSNStar 一下✨:
github.com/mosn/mosn