Istio中如何处理thrift等协议(istio 协议)

createh52个月前 (02-01)技术教程9

对于Istio来说,分为控制面和数据面。控制面负责下发Envoy 的配置。数据面接受控制面下发的配置,按照配置工作。

所以本质上只有envoy支持的协议,控制面才能够支持。实际情况,istio支持的协议类型,远远少于Envoy支持的类型。

Istio对于HTTP,gRPC协议之外的协议,支持并不是特别好。而实际的应用中,其实很多单位都在使用诸如thrift,dubbo或其他私有协议。随着Istio用户越来越多,增加对其他协议的支持是一个强需求。

Istio如何确定各种协议

Istio支持代理任何TCP通信。这包括HTTP,HTTPS,gRPC以及原始TCP协议。为了提供其他功能,例如路由和丰富的metrics,我们必须确定具体协议。确定的方式有:

  • 自动检测
  • 手动指定

自动检测

Istio可以自动检测HTTP和HTTP/2通信。其他协议类型,如果没有手动指定,则将流量视为纯TCP流量。

手动指定

如何指定?

我们知道对于Istio来说,支持k8s中的 Service 和 非k8s环境ServiceEntry两种资源对象转换为内部的统一服务模型。

对于k8s中的Service:

  • 通过端口名: name: [-]
  • Kubernetes 1.18+, 可以通过 appProtocol 字段: appProtocol:

通过appProtocol字段指定,具体示例如下:

kind: Service
metadata:
  name: myservice
spec:
  ports:
  - number: 3306
    name: database
    appProtocol: mysql
  - number: 80
    name: http-web

对于ServiceEntry,通过ports列表中protocol属性自定,具体示例如下:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-mongocluster
spec:
  hosts:
  - mymongodb.somedomain # not used
  addresses:
  - 192.192.192.192/24 # VIPs
  ports:
  - number: 27018
    name: mongodb
    protocol: MONGO
  location: MESH_INTERNAL
  resolution: STATIC
  endpoints:
  - address: 2.2.2.2
  - address: 3.3.3.3

截止到目前,支持以下值:

http
http2
https
tcp
tls
grpc
grpc-web
mongo
mysql
redis
thrift

其中*标注的协议,默认是不支持,需要在特性开关中启用。对于thrift来说,我们需要给pilot设置环境变量:
PILOT_ENABLE_THRIFT_FILTER

可以看出,Istio逐步在增加对其他协议的支持,比如mongo,redis,mysql,thrift。

Istio 如何支持其他协议

那么我们目前有以下几种方式支持thrift等协议。

1)EnvoyFilter

EnvoyFilter是Istio中自定义的一种网络资源对象,用来更新配置Envoy中的filter,为服务网格控制面提供了更强大的扩展能力,使Envoy中filter chain具备自定义配置的能力。

我们以thrift举例说明。

Istio默认把Thrift协议当做普通的TCP协议来处理。我们需要通过EnvoyFilter移除默认的TCP Filter,并增加Thrift proxy Filter。

具体的EnvoyFilter如下:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: thrift-demo
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      # will match outbound listeners in all sidecars
      context: SIDECAR_OUTBOUND 
      listener:
        # The port dedicated to thirft
        portNumber: 10005
        filterChain:
          filter:
            name: envoy.tcp_proxy
    patch:
      # Remove envoy.tcp_proxy filter
      operation: REMOVE
  - applyTo: NETWORK_FILTER
    match:
      # will match outbound listeners in all sidecars
      context: SIDECAR_OUTBOUND
      listener:
        # The port dedicated to thirft
        portNumber: 10005
    patch:
      operation: INSERT_FIRST
      value:
        name: envoy.filters.network.thrift_proxy
        config:
          stat_prefix: "outbound|10005||thrift-demo-server.thrift-demo.svc.cluster.local"
          transport: AUTO_TRANSPORT
          protocol: AUTO_PROTOCOL
          thrift_filters:
          - name: envoy.filters.thrift.router
          route_config:
            routes:
            - match:
                # empty string matches any request method name
                method_name: ""
              route:
                cluster: "outbound|10005||thrift-demo-server.thrift-demo.svc.cluster.local"

更多内容可查看 istio-thrift-example 。

该方案的确可以实现,但是非常繁杂,也容易出错。

2)Aeraki

由于难以手动对 EnvoyFilter 进行管理和维护 ,腾讯云Mesh团队创建了 Aeraki 项目来自动化这个流程。

Aeraki 的基本工作原理如下图所示:Aeraki 从 Istio 中拉取服务数据,根据 ServiceEntry 和 Aeraki 流量规则生成 Envoy 配置,并采用 EnvoyFilter 将生成的配置推送到 Istio 中。简而言之,你可以把 Aeraki 看做 Istio 中管理的七层协议的Operator。

该方案,又做了一些抽象,并且不会对Istio代码做侵入性改动。

3)通过给Istio增加新的future,增加对其他协议支持

上面我们已经讲到,目前istio正在增加对其他协议的支持,已经支持了mongo,thrift等。

这里可以看出社区终究会支持其他主流协议。

个人观点:如果所用协议为开源社区主流协议,尤其是envoy已经支持的协议,通过改动Istio代码会更加合适,当然如果可以贡献给社区,并且被接受,那就更加完美了。而且整体难度也不会特别大,按照社区对于mongo等支持的方式,添加对其他协议的支持。

比如thrift:

case protocol.Thrift:
		if features.EnableThriftFilter {
			// Thrift filter has route config, it is a terminating filter, no need append tcp filter.
			filterstack = append(filterstack, buildThriftFilter(statPrefix))
		} else {
			filterstack = append(filterstack, tcpFilter)
		}

如果我们启用了
PILOT_ENABLE_THRIFT_FILTER。filter列表中,将会直接添加thrift filter,而不是tcp filter。

相关文章

Zookeeper 的通信及会话(zookeeper通俗)

1. 前言在前面的章节中,我们学习了 Zookeeper 的 Java 客户端 ZkClient 和 Curator 的基本使用,那这些客户端是如何与 Zookeeper 服务端建立通信的呢?我们就带...

Java 泛型使用(类、方法、接口协议、类型通配符、通配符上下限)

一、简介泛型:是 JDK5 中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。一提到参数,最熟悉的就是定...

6 张图带你彻底搞懂分布式事务 XA 模式

XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口。目前主流的数据库,比如 oracle、DB2 都是支持 XA 协议的。mys...

太厉害了,终于有人能把HTTP 协议讲的明明白白了

作者:涤生_Woo一、概述1.计算机网络体系结构分层2.TCP/IP 通信传输流利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上走。如...

通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论

作者:梁倍宁 Apache Dubbo Contributor、陈有为 Apache Dubbo PMC摘要AliwareDubbo3 Triple 协议是参考 gRPC、gRPC-Web、Dubbo...

别再怀疑自己的智商了,Raft协议本来就不好理解

Raft声称是一种易于理解的分布式一致性算法。有不少工程师们翻了它的论文,参考了很多资料,最后只好怀疑自己是不是智商有问题。Raft一直以来是很多高级资深程序员技术上的天花板,捅破相当有难度。每次刚刚...