A Kubernetes in Service Mesh(第9部分):使用gRPC的乐趣和收益
A Kubernetes Service Mesh (Part 9): gRPC for Fun and Profit
原文作者:Alex Leong
原文地址:https://dzone.com/articles/a-service-mesh-for-kubernetes-part-ix-grpc-for-fun
译者微博:@从流域到海域
译者博客:blog.csdn.net/solo95
本文同样刊载于腾讯云+:https://cloud.tencent.com/developer/article/1017280
A Kubernetes Service Mesh(第9部分):使用gRPC的乐趣和收益
从今年早些时候发布的Linkerd 0.8.5开始, Linkerd开始支持gRPC和HTTP/2!这些强大的协议可以为使用这些协议的应用程序带来显著的好处。在这篇文章中,我们将演示如何将Linkerd与gRPC结合使用,允许使用gRPC的应用程序充分利用Linkerd的负载平衡,服务搜寻,熔断机制和分布式跟踪逻辑。
本文是关于Linkerd, Kubernetes和service meshes(可以直译服务网格,译者注)的一系列文章之一 。本系列的其他部分包括:
- Service的重要指标
- 以DaemonSet方式运行linkerd
- 加密所有的东西
- 通过流量切换进行连续部署
- Dogfood环境,入口和边缘路由
- 轻松预发布微服务
- 如何使分布式跟踪变得容易
- 使用Linkerd作为入口控制器
- 使用gRPC的乐趣和收益(这篇文章)
- The service mesh API
- 出口
- 重试预算,截止日期传播和如何让失败变得优雅(Retry budgets, deadline propagation, and failing gracefully)
- 通过顶层指标实现自动收缩(Autoscaling)
(译者注:第11部分的链接是译者追加的,来自另一个社区,另外,Kubernetes拥有中文社区官网,附上前6部分的社区官翻 - https://www.kubernetes.org.cn/3298.html)
对于这篇文章,我们将使用我们熟悉的 hello world
微服务应用程序和配置,这可以在linkerd-examples
找到(k8s配置看这里 和 hello world
代码看这里)找到。
这个hello world
应用程序由两个组件组成 - 一个 hello
服务调用world
服务来完成一个请求。hello
和world
使用gRPC实现相互之间的信息传递。我们将部署Linkerd作为DaemonSet(在每个主机上部署一个Linkerd实例),并从请求 hello
到 world
会像下面这样:
如上所示,当 hello
服务想要调用时 world
服务时,请求将通过其主机本地上Linkerd 的 outgoing 路由器送出,它不直接将请求发送到目标 world
服务,而是发送到在同一主机world
上运行的Linkerd实例(在incoming 路由器上)。Linkerd实例随后将请求发送给其主机上的 world
服务。这个三跳模型允许Linkerd将应用程序的协议从传输协议中分离出来,例如通过在TLS中包装实现跨节点连接。(有关部署此拓扑结构的更多信息,请参阅本系列的第II部分,以DaemonSet方式运行linkerd。)
你可以在家里尝试一下
让我们看看这个配置的具体实现!部署 hello
, world
和Linkerd到默认的 k8s
命名空间:
kubectl apply -f https://raw.githubusercontent.com/BuoyantIO/linkerd-examples/master/k8s-daemonset/k8s/hello-world-grpc.yml
kubectl apply -f https://raw.githubusercontent.com/BuoyantIO/
一旦Kubernetes为Linkerd提供外部LoadBalancer IP,我们就可以做一些测试请求!请注意,这些博客文章中的示例都假设k8s在GKE上运行(例如,外部LoadBalancer IP可用,不使用任何CNI插件)。其他环境可能需要稍作修改 - 请参阅我们 的Kubernetes维基页面 ,了解Minikube或CNI配置的Calico/Weave环境。
我们将使用hello world
Docker镜像 提供的helloworld-client 向hello world
服务发送用来测试的gRPC请求:
$ L5D_INGRESS_LB=$(kubectl get svc l5d -o jsonpath="{.status.loadBalancer.ingress[0].*}")
$ docker run --rm --entrypoint=helloworld-client buoyantio/helloworld:0.1.3 $L5D_INGRESS_LB:4140
Hello (10.196.1.242) world (10.196.1.243)!
成功了!
我们可以通过执行以下操作来查看Linkerd管理控制台:
$ open http://$L5D_INGRESS_LB:9990 # on OSX
就是这样!我们现在实现了在gRPC服务相互之间进行信息传递,方法是通过Linkerd路由转发它们的HTTP/2请求。现在我们可以在我们的gRPC微服务应用程序中使用所有 Linkerd的强大功能,包括单次路由请求,负载平衡,熔断,重试,TLS,分布式跟踪,服务搜寻集成等。
(以防翻译不够准确,原文:including per-request routing, load balancing, circuit-breaking, retries, TLS, distributed tracing, service discovery integration and more,译者注)
我们如何配置Libkerd以实现使用了HTTP/2协议的gRPC?
让我们退后一步,检查我们的配置。使用gRPC而不是HTTP / 1.1有什么不同?其实不同之出不是很多!如果将使用了gRPC的Linkerd配置 与 原来的HTTP / 1.1的配置进行路由(routing)进行对比(https://raw.githubusercontent.com/BuoyantIO/linkerd-examples/master/k8s-daemonset/k8s/linkerd-grpc.yml),你会发现它们非常相似(可以在这里找到配置HTTP / 2路由器的完整文档 )。
你能看到的变化是:
协议
我们已经把路由器的 protocol
从 http
改成了 h2
(这是自然而然的!),并设置experimental
标志为 true
来选择加入实验性HTTP / 2支持。
routers:
- protocol: h2
experimental: true
验证者(identifer)
我们使用 header path identifier 来分配一个基于gRPC请求的逻辑名称。gRPC客户端设置HTTP / 2的:path
伪首为 /package.Service/Method
。头部路径标识符使用这个伪首来为请求分配一个逻辑名称(例如 /svc/helloworld.Hello/Greeting
)。设置 segments
为1意味着我们只取路径的第一部分,换句话说,放弃gRPC Method
。得到的名称可以通过dtab来进行转换 ,我们可以在其中提取gRPC服务名称,并将请求转发到同名的Kubernetes服务中。有关Linkerd如何进行路由请求的更A多信息,请参阅我们的routing 文档。
identifier:
kind: io.l5d.header.path
segments: 1
dtab
我们已经稍微调整了dtab,现在我们从header path identifier以/serviceName
为前缀进行路由转发 。下面的dtab将由路径标识符(/svc/helloworld.Hello
)指定的逻辑名称转换为一个名称,告诉 io.l5d.k8s 编号器在默认命名空间(hello/#/io.l5d.k8s/default/grpc/Hello
)中查询服务 grpc
的API端口 。
domainToPathPfx namer 被用于从包限定GRPC服务名称提取服务名称,如在目录项可见 /svc => /$/io.buoyant.http.domainToPathPfx/grpc
。
代表团 world
是相似的,但是我们已经决定版本 world
服务,所以我们添加了额外的规则 /grpc/World => /srv/world-v1
来发送请求到world-v1。
完整的dtab现在是:
/srv => /#/io.l5d.k8s/default/grpc;
/grpc => /srv;
/grpc/World => /srv/world-v1;
/svc => /$/io.buoyant.http.domainToPathPfx/grpc;
结论
在本文中,我们已经看到如何使用Linkerd作为一个service mesh来进行针对gRPC的请求,向gRPC应用程序添加延迟感知负载均衡,断路和请求级别的路由。Linkerd和gRPC是一个很好的组合,特别是基于HTTP/2的gRPC提供了许多强大的机制,如多路复用流(streaming),背压机制(back pressure)和取消(cancelation),Linkerd可以充分利用这些机制。因为gRPC请求中包含路由信息,所以这对Linkerd来说是非常合适的,并且使得建立Linkerd来路由转发(route)RPC请求变得非常容易。更多围绕gRPC展开的Linkerd路线图信息,请参阅Oliver’s blog post on the topic。
最后,如果你想找关于配置gRPC服务的一个更高级的例子,可以看看我们的Gob microservice应用程序。在这个例子中,我们还部署了 Namerd,我们用它来集中管理我们的路由规则,而无需重新部署Linkerd来更新路由规则。这让我们可以在不同版本的服务之间进行类似于canarying和blue green的部署。
有关Linkerd,gRPC和HTTP/2的更多信息,请参阅 Linkerd gRPC文档 以及 HTTP/2的配置文档。