乐趣区

关于envoy:MoE-系列二|Golang-扩展从-Envoy-接收配置

文|朱德江(GitHub ID:doujiang24)

MOSN 我的项目外围开发者蚂蚁团体技术专家

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

本文 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:

https://github.com/doujiang24/envoy-go-filter-example/tree/master/example-basic-auth

理解更多…

MOSN Star 一下✨:
https://github.com/mosn/mosn

退出移动版