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的负载平衡,服务搜寻,熔断机制和分布式跟踪逻辑。

本文是关于LinkerdKubernetes和service meshes(可以直译服务网格,译者注)的一系列文章之一 。本系列的其他部分包括:

  1. Service的重要指标
  2. 以DaemonSet方式运行linkerd
  3. 加密所有的东西
  4. 通过流量切换进行连续部署
  5. Dogfood环境,入口和边缘路由
  6. 轻松预发布微服务
  7. 如何使分布式跟踪变得容易
  8. 使用Linkerd作为入口控制器
  9. 使用gRPC的乐趣和收益(这篇文章)
  10. The service mesh API
  11. 出口
  12. 重试预算,截止日期传播和如何让失败变得优雅(Retry budgets, deadline propagation, and failing gracefully)
  13. 通过顶层指标实现自动收缩(Autoscaling)

(译者注:第11部分的链接是译者追加的,来自另一个社区,另外,Kubernetes拥有中文社区官网,附上前6部分的社区官翻 - https://www.kubernetes.org.cn/3298.html)

对于这篇文章,我们将使用我们熟悉的 hello world 微服务应用程序和配置,这可以在linkerd-examples 找到(k8s配置看这里hello world 代码看这里)找到。

这个hello world 应用程序由两个组件组成 - 一个 hello服务调用world 服务来完成一个请求。helloworld使用gRPC实现相互之间的信息传递。我们将部署Linkerd作为DaemonSet(在每个主机上部署一个Linkerd实例),并从请求 helloworld会像下面这样:

DaemonSet部署模型:每个主机配置一个Linkerd

如上所示,当 hello 服务想要调用时 world 服务时,请求将通过其主机本地上Linkerd 的 outgoing 路由器送出,它不直接将请求发送到目标 world 服务,而是发送到在同一主机world 上运行的Linkerd实例(在incoming 路由器上)。Linkerd实例随后将请求发送给其主机上的 world 服务。这个三跳模型允许Linkerd将应用程序的协议从传输协议中分离出来,例如通过在TLS中包装实现跨节点连接。(有关部署此拓扑结构的更多信息,请参阅本系列的第II部分,以DaemonSet方式运行linkerd。)

你可以在家里尝试一下

让我们看看这个配置的具体实现!部署 helloworld和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路由器的完整文档 )。

你能看到的变化是:

协议

我们已经把路由器的 protocolhttp 改成了 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的配置文档

posted @ 2018-01-09 17:56  从流域到海域  阅读(69)  评论(0编辑  收藏  举报