导言
什么是service mesh,一个为云平台而设计的应用。它如何被云平台的本地应 用使用?本文中,我们将讲述在Kubernetes中如何应用Linkerd作为service mesh,如何捕获和报告顶层服务指标如成功率、请求量和延迟,而不需要更改应用的代码。
注意:这是关于Linkerd、Kubernetes和service mesh的系列文章其中一篇,其余部分包括:
1. Top-line service metrics (本文)
2. Pods are great, until they’re not
3. Encrypting all the things
4. Continuous deployment via traffic shifting
5. Dogfood environments, ingress, and edge routing
6. Staging microservices without the tears
7. Distributed tracing made easy
8. Linkerd as an ingress controller
9. gRPC for fun and profit
10. The Service Mesh API
11. Egress
12. Retry budgets, deadline propagation, and failing gracefully
13. Autoscaling by top-line metrics
使用service mesh的必要性
关于Linkerd最常见的一个疑问就是,到底什么是service mesh?当Kubernetes已经提供了如Service资源对象、负载均衡这样的基本功能后,为什么service mesh要作为云本地应用程序的关键组件。
简单来说,service mesh这一层管理着应用之间的通信(或者部分应用之间的通信如微服务)。传统应用中,这个逻辑直接构建到应用程序本身中:重试和超时,监控/可见性,追踪,服务发现等等。这些都被硬编码到每个应用程序中。
然而,随着应用程序架构被越来越多的分割成服务,将通信逻辑从应用中移出到底层基础设施中变得越来越重要。就像是应用程序不应该写它自己的TCP栈,他们也不应该管理自己的负载均衡逻辑,或他们自己的服务发现管理程序,以及他们自己的重试和超时逻辑。
像Linkerd这样的service mesh为大规模多服务应用程序提供关键的部件:
1. 基本的适应性功能:重试预算,deadline,熔断器模式
2. 顶层的服务指标:成功率,请求量,延迟
3. 延迟和失败容忍度:感应失败和延迟的负载均衡,它可以绕过缓慢的或者损坏的服务实例
4. 分发追踪:如Zipkin和OpenTracing
5. 服务发现:找到目标实例
6. 协议升级:在TLS中包装跨网络通信,或将HTTP/1.1转换为HTTP/2.0
7. 路由:不同版本的服务之间的路由请求,集群之间的故障转移等
本文中,我们仅重点关注可见性:service mesh是如何自动捕获并报告如成功率等顶层服务指标的,我们将展示一个Kubernetes的小例子以此来引导你。
在Kubernetes中使用Linkerd作为Service的监测器
在请求层进行操作的一个优势是service mesh可以访问成功和失败的协议级语义。举个例子,如果你正在运行一个HTTP服务,Linkerd可以理解200 、400、500响应的含义,从而可以自动计算如成功率这样的指标。
让我们通过一个小例子讲解如何在Kubernetes中安装Linkerd,从而自动的捕获顶层服务成功率而不需要更改应用程序。
安装Linkerd
使用Kubernetes配置文件安装Linkerd。它会将Linkerd作为DaemonSet安装,且运行在Kubernetes的default命名空间:
kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd.yml
你可以通过查看Linkerd的管理页面确认是否安装成功:
INGRESS_LB=$(kubectl get svc l5d -o jsonpath="{.status.loadBalancer.ingress[0].*}")
open http://$INGRESS_LB:9990 # on OS X
如果集群不支持外部负载均衡,使用hostIP:
HOST_IP=$(kubectl get po -l app=l5d -o jsonpath="{.items[0].status.hostIP}")
open http://$HOST_IP:$(kubectl get svc l5d -o 'jsonpath={.spec.ports[2].nodePort}') # on OS X
安装样例应用程序
在default命名空间下安装两个Service,“hello”和“world”。这些应用程序依赖于Kubernetes downward API提供的nodeName来发现Linkerd。为了检测你的集群是否支持nodeName,你可以运行:
kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/node-name-test.yml
然后看它的日志:
kubectl logs node-name-test
如果你看到了一个IP就说明支持。接下来继续部署hello world应用程序如下:
kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world.yml
如果你看到报错“server can’t find…”,就部署旧版本hello-world,它依赖于hostIP而非nodeName:
kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world-legacy.yml
这两个Service——“hello”和“world”——功能在一起使得高度可扩展,“hello world”微服务(“hello”Service调用“world”Service完成这个请求)。
你可以通过给Linkerd的外部IP发送请求来查看此操作:
http_proxy=$INGRESS_LB:4140 curl -s http://hello
或者直接使用hostIP:
http_proxy=$HOST_IP:$(kubectl get svc l5d -o 'jsonpath={.spec.ports[0].nodePort}') curl -s http://hello
你应该可以看到字符串“Hello world”。
安装Linkerd-viz
最后,通过安装Linkerd-viz,让我们可以看看Service正在做什么。Linkerd-viz是一个附加包,它包括一个简单的Prometheus和Grafana设置,并可以自动发现Linkerd。
下面的命令会将Linkerd-viz安装到default命名空间下:
kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-viz/master/k8s/linkerd-viz.yml
访问Linkerd-viz的外部IP查看dashboard:
VIZ_INGRESS_LB=$(kubectl get svc linkerd-viz -o jsonpath="{.status.loadBalancer.ingress[0].*}")
open http://$VIZ_INGRESS_LB # on OS X
如果集群不支持外部负载均衡,使用hostIP:
VIZ_HOST_IP=$(kubectl get po -l name=linkerd-viz -o jsonpath="{.items[0].status.hostIP}")
open http://$VIZ_HOST_IP:$(kubectl get svc linkerd-viz -o 'jsonpath={.spec.ports[0].nodePort}') # on OS X
你应该在dashboard上看到包括Service与实例的选择器,所有图表都反映了这些Service和实例的选择器。
Linkerd-viz的dashboard包括三部分:1. 顶层:集群范围的成功率与请求量2. Service指标:每个已部署应用的指标,包括成功率、请求量和延迟
3. 单个实例指标:集群上每一个node的成功率、请求量和延迟
结束语
用三个简单的命令我们就可以将Linkerd安装在集群上,安装应用,并且使用Linkerd了解应用程序Service的健康状况。当然,Linkerd提供的不仅仅是可见性,还提供了延迟感应负载均衡,自动重试和断路,分发追踪等功能。在该系列接下来的文章中,我们将讲述如何使用这些特性的优势。