说明Svcb到外部服务的通信被打通了!

我们经常有这样的需求,当svcb运行一段时间后,svcb添加了新feature,版本要升级到v0.2了,这时我们会部署svcb:v0.2,并将流量逐步切到v0.2上。
我们先来部署一下svcb:v0.2:

// svcb-v0.2.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: svcb-v0.2 spec: replicas: 1 template: metadata: labels: app: svcb version: v0.2 spec: containers: - name: svcb image: docker.io/bigwhite/istio-demo-svcb:v0.2 imagePullPolicy: Always


我们可以看到,服务名不变,但版本的label变成了v0.2,我们来执行这次部署:

# kubectl apply -f <(istioctl kube-inject -f svcb-v0.2.yaml) deployment "svcb-v0.2" created # kubectl get pods NAME READY STATUS RESTARTS AGE svca-1997590752-pq9zg 2/2 Running 0 9h svcb-2008973769-gq0lh 2/2 Running 0 9h svcb-v0.2-3233505404-0g55w 2/2 Running 0 1m svcb服务下又增加了一个endpoint: # kubectl describe svc/svcb .... ... Selector: app=svcb Type: ClusterIP IP: 10.105.119.194 Port: <unset> 80/TCP Endpoints: 10.40.0.28:8080,10.46.0.12:8080 ... ...


此时,如果按照Kubernetes的调度方式,v0.1和v0.2版本的两个svcb pod应该1:1均衡地承载流量。为了方便查看流量分布,我们将每个版本的svcb的pod副本数量都扩展为2个(replicas: 2),这样Service Mesh中一共会有4个 svcb endpoints。
通过curl访问svca注入流量后,我们发现流量都集中在一个svcb:v0.2的pod上,并且长时间没有变化。我们通过下面的route rule规则来尝试将流量在svcb:v0.1和svcb:v0.2之间1:1均衡:

// route-rules-svcb-v0.2-50.yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: route-rules-svcb spec: destination: name: svcb precedence: 1 route: - labels: version: v0.1 weight: 50 - labels: version: v0.2 weight: 50 # istioctl create -f route-rules-svcb-v0.2-50.yaml Created config route-rule/default/route-rules-svcb at revision 30080638


按照Istio文档中的说法,这个规则的生效需要一些时间。之后我们注入流量,发现流量切换到svcb:v0.1的一个Pod上去了,并且很长一段时间不曾变化,未均衡到svcb:v0.2上去。
我们更新一下route rule,将流量全部切到svcb:v0.2上去:

//route-rules-svcb-v0.2-100.yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: route-rules-svcb spec: destination: name: svcb precedence: 1 route: - labels: version: v0.2 weight: 100 # istioctl replace -f route-rules-svcb-v0.2-100.yaml Updated config route-rule/default/route-rules-svcb to revision 30082944


我们用Istio的replace命令更新了规则:route-rules-svcb。更新后,再次注入流量,这回流量重新集中在svcb:v0.2的一个Pod上了,再过一段时间另外一个svcb:v0.2的pod上才有了一些流量。但svcb:v0.1上不再有流量,这个切换是成功的。
在Kubernetes的Service的负载均衡中,Kubernetes就利用了iptables的概率转发(random –probability 0.5),因此这种流量均衡并非是精确的,只有在长时间大量流量经过后,才能看到流量的分布与设定的权重是相似的,可能Istio也是如此,这里仅是入门,就不深入挖掘了。
当然Istio在路由规则设施方面的“能耐”远不止上面例子中所展示的那样,如果要悉数列出,那本文的长度可是要爆掉了。有兴趣的朋友可以去翻看官方文档。

五、插件安装

Istio的强大微服务治理能力还体现在其集成了Grafana、Prometheus、ServiceGraph、Zipkin等Addons,应用程序无需做任何改动,就可以具有数据收集、度量与可视化的监控能力、服务的分布式跟踪能力等。我们可以在Istio的安装包中找到这些Addons的安装文件,我们来逐一试试。
1、Prometheus & Grafana

我们先来安装一下Prometheus和Grafana插件(位于istio-0.4.0/install/kubernetes/addon下面):

# kubectl apply -f prometheus.yaml configmap "prometheus" created service "prometheus" created deployment "prometheus" created # kubectl apply -f grafana.yaml service "grafana" created deployment "grafana" created # kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE grafana-3617079618-zpglx 1/1 Running 0 5m prometheus-168775884-ppfxr 1/1 Running 0 5m ... ... # kubectl get svc -n istio-system NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana 10.105.21.25 <none> 3000/TCP 16m prometheus 10.103.160.37 <none> 9090/TCP 16m ... ...


浏览器中输入Prometheus的服务地址http://10.103.160.37:9090,访问Prometheus:


点击菜单项:status -> targets,查看各个target的状态是否正常:


如果像上图所示那样,各个target都是up状态,那就说明Istio运行时OK的。否则请参考istio troubleshooting中的内容对Istio逐一进行排查,尤其是istio-mesh这个Target在istio-0.3.0+kubernetes 1.7.3的环境中就是Down的状态。
浏览器输入grafana的服务地址


切换到Istio Dashboard,并向Istio Service Mesh注入流量,我们会看到仪表盘变化如下:


2、ServiceGraph
ServiceGraph插件是用来查看服务调用关系的,我们来创建一下该组件:

# kubectl apply -f servicegraph.yaml
deployment "servicegraph" created
service "servicegraph" created
# kubectl get svc -n istio-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
servicegraph 10.108.245.21 <none> 8088/TCP 52s
... ...

创建成功后,向Service Mesh网络注入流量,然后访问ServiceGraph:http://{servicegraph_ip}:8088/dotviz,在我的环境里,我看到的图示如下:


调用关系似乎有些乱,难道是我在程序使用的调用方法不够标准?:(
3、Zipkin
Istio集成了Zipkin,利用Zipkin我们可以做分布式服务调用的追踪。之前自己曾经搭建过基于Jaeger和OpenTracing的分布式调用服务,十分繁琐。并且要想使用tracing,对应用代码的侵入必不可少。
我们安装一下Zipkin Addon:

# kubectl apply -f zipkin.yaml
deployment "zipkin" created
service "zipkin" created
# kubectl get svc -n istio-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
zipkin 10.105.7.219 <none> 9411/TCP 1h

我们访问以下Zikpin的UI,通过浏览器打开http://{zipkinserviceip}:9411。


接下来,我们向Service Mesh注入一些流量,然后在Zipkin首页的“服务名”下拉框中选择”svcb”,查找跟踪情况:


我们看到:在没有对svca,svcb做任何修改的情况下,我们依然可以在Zipkin中找到svcb相关的调用。点击其中一个trace,可以查看细节: