Service Mesh
Service Mesh 的中文译为“服务网格”,是一个用于处理服务和服务之间通信的基础设施层,它负责为构建复杂的云原生应用传递可靠的网络请求,并为服务通信实现了微服务所需的基本组件功能,例如服务发现、负载均衡、监控、流量管理、访问控制等。在实践中,服务网格通常实现为一组和应用程序部署在一起的轻量级的网络代理,但对应用程序来说是透明的。
Service Mesh 部署网络结构图
Service Mesh有四大特点:
- 治理能力独立(Sidecar)
- 应用程序无感知
- 服务通信的基础设施层
- 解耦应用程序的重试/超时、监控、追踪和服务发现

如此一来,Service Mesh将业务模块和服务治理分开。
从上图中我们看到,控制面和数据面分离,应用在部署的时候,每个应用附带一个Side Car,这个Side Car是拦截每一个应用对外请求的。同时控制面的服务治理策略下到Side Car中具体的执行,这样的话,即使业务模块升级和服务治理的升级也能互不影响的,还能动态调整服务治理的规则和策略
从Service Mesh的结构和特点,我们可以总结出其对于服务治理的理念:
1、微服务治理与业务逻辑解耦:把大部分SDK能力从应用中剥离出来,并拆解为独立进程,以 sidecar 的模式进行部署。
2、异构系统的统一治理:方便多语言的实施,解锁升级带来的困难。
3、价值:
(1)可观察性:服务网格捕获诸如来源、目的地、协议、URL、状态码、延迟、持续时间等线路数据;
(2)流量控制:为服务提供智能路由、超时重试、熔断、故障注入、流量镜像等各种控制能力。
(3)安全性高:服务的认证、服务间通讯的加密、安全相关策略的强制执行;
(4)健壮性:支持故障注入,对于容灾和故障演练等健壮性检验帮助巨大。
我们以Service Mesh的杰出代表Istio为例来聊聊最新的服务治理的架构,它对Service Mesh完全支持,架构清晰,拆分数据面、控制面;拥有通信、安全、控制、观察等功能,实现开放,且插件化,多种可选实现。
Istio可结合K8S使用,K8S提供服务生命周期的管理,Istio在K8S之上通过服务治理的整体的功能的实现。
1 Istio 概述
Isito是Service Mesh的产品化落地,是目前最受欢迎的服务网格,功能丰富、成熟度高。
Linkerd是世界上第一个服务网格类的产品
官方地址:https://istio.io
主要有以下特点
连接(Connect)
- 流量管理
- 负载均衡
- 灰度发布
- 流量管理
安全(Secure)
- 认证
- 鉴权
- 认证
控制(Control)
- 限流
- ACL
- 限流
观察(Observe)

注:此页中图片引用自Istio官网
◆ 性能总结
Istio 负载测试网格包含了 1000 个服务和 2000 个 sidecar,全网 格范围内,QPS 为 70,000。 在使用 Istio 1.6.2 运行测试后,我们 得到了如下结果:
• 通过代理的 QPS 有 1000 时,Envoy 使用了 0.5 vCPU 和 50 MB 内存。
• 网格总的 QPS 为 1000 时,istio-telemetry 服务使用了 0.6 vCPU。
• Pilot 使用了 1 vCPU 和 1.5 GB 内存。
• 90% 的情况 Envoy 代理只增加了 6.3 ms 的延迟
注:此页中图片和数据引用自Istio官网
3 在 Kubernetes 部署 Istio
可参考官方文档,以部署1.6版本作为演示,部署的demo模式,所有组件都安装
# wget https://github.com/istio/istio/releases/download/1.6.2/istio-1.6.2-linux-amd64.tar.gz# tar -zxvf istio-1.6.2-linux-amd64.tar.gz -C /data/# cd /data/istio-1.6.2/# mv bin/istioctl /usr/bin# istioctl profile listIstio configuration profiles:defaultdemoemptyminimalpreviewremote# istioctl install --set profile=demo# kubectl get pods -n istio-systemNAME READY STATUS RESTARTS AGEgrafana-75745787f9-jb79g 1/1 Running 0 2d8histio-egressgateway-78b89c9f79-f7g58 1/1 Running 0 2d2histio-ingressgateway-845967d5c6-4r7dm 1/1 Running 0 2d2histio-tracing-7fc897dbb8-gsgfq 1/1 Running 0 2d2histiod-b56f454c6-9rd5f 1/1 Running 0 55mkiali-5645f98f9-5jkjf 1/1 Running 0 2d1hprometheus-7778b9d84-ncb5r 2/2 Running 0 2d2h# kubectl get svc -n istio-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEistio-egressgateway ClusterIP 10.104.251.176 <none> 80/TCP,443/TCP,15443/TCP 71distio-ingressgateway NodePort 10.99.33.183 <none> 15020:41020/TCP,80:48035/TCP,443:41862/TCP,15029:44646/TCP,15030:35600/TCP,15031:49406/TCP,15032:41959/TCP,15443:49277/TCP 71distio-pilot ClusterIP 10.111.202.110 <none> 15010/TCP,15011/TCP,15012/TCP,8080/TCP,15014/TCP,443/TCP 71distiod ClusterIP 10.96.68.5 <none> 15012/TCP,443/TCP 71djaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 71djaeger-collector ClusterIP 10.106.32.219 <none> 14267/TCP,14268/TCP,14250/TCP 71djaeger-collector-headless ClusterIP None <none> 14250/TCP 71djaeger-query ClusterIP 10.96.35.176 <none> 16686/TCP 71dkiali ClusterIP 10.101.196.222 <none> 20001/TCP 71dprometheus ClusterIP 10.98.252.96 <none> 9090/TCP 71dtracing ClusterIP 10.101.199.222 <none> 80/TCP 71dzipkin ClusterIP 10.110.255.236 <none> 9411/TCP 71d
卸载:
istioctl manifest generate --set profile=demo | kubectl delete -f -
4 应用演示(以bookinfo项目为例)
4.1 Sidercar 注入
# 手动注入kubectl apply -f <(istioctl kube-inject -f xxx.yaml)或者istioctl kube-inject -f xxx.yaml|kubectl apply -f -# 自动注入kubectl label namespace xxx istio-injection=enabled#项目空间中所有应用进行重启#需要注意,有状态部署的应用需要手动注入,比如Apollo配置中心的server端
4.2 服务网关:Gateway
这里需要使用istio自带的ingressgateway来进行流量管理,因此需要把对应业务的流量从这里面写入,没有使用k8s自带的ingress,使用istio自带的ingress当作服务的边界,便于流量管理
Gateway为网格内服务提供负载均衡器,提供以下功能:
•L4-L6的负载均衡
•对外的mTLS
Gateway根据流入流出方向分为:
•IngressGateway:接收外部访问,并将流量转发到网格内的服务。
•EgressGateway:网格内服务访问外部应用。
示例:
| apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - ““ —- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - ““ gateways: - httpbin-gateway http: - route: - destination: host: httpbin port: number: 8000 |
|---|
4.3 部署 bookinfo 微服务示例
本节将部署一个多语言异构化的微服务示例(Bookinfo),让大家对服务网格有一个清晰的认识。
4.3.1 Bookinfo - 在线图书商店
Bookinfo 应用分为四个单独的微服务:
- productpage :productpage 微服务会调用 details 和reviews 两个微服务,用来生成页面。
- details :这个微服务包含了书籍的信息。
- reviews :这个微服务包含了书籍相关的评论。它还会调用ratings 微服务。
- ratings :ratings 微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
- v1 版本不会调用 ratings 服务。
- v2 版本会调用 ratings 服务,并使用 5个黑色五角星来显示评
分信息。
- v3 版本会调用 ratings 服务,并使用5个红色五角星 来显示评
4.3.2 部署Bookinfo到Istio
将Bookinfo部署到k8s默认命名空间,即default。
启动边车自动注入
kubectl label namespace default istio-injection=enabled
部署到k8s
# 进入istio的工作目录[root@master01 ~]# cd /data/istio-1.6.2/# 使用kubectl部署到k8s[root@master01 istio-1.6.2]# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yamlservice/details createdserviceaccount/bookinfo-details createddeployment.apps/details-v1 createdservice/ratings createdserviceaccount/bookinfo-ratings createddeployment.apps/ratings-v1 createdservice/reviews createdserviceaccount/bookinfo-reviews createddeployment.apps/reviews-v1 createddeployment.apps/reviews-v2 createddeployment.apps/reviews-v3 createdservice/productpage createdserviceaccount/bookinfo-productpage createddeployment.apps/productpage-v1 created
获取访问地址
# 为Bookinfo部署入口网关[root@master01 istio-1.6.2]# kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yamlgateway.networking.istio.io/bookinfo-gateway createdvirtualservice.networking.istio.io/bookinfo created# 获取网关地址[root@master01 istio-1.6.2]# export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')[root@master01 istio-1.6.2]# export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')[root@master01 istio-1.6.2]# export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT# 获取图书单品页地址echo http://${GATEWAY_URL}/productpage
备注:生产环境一般使用
istio-ingressgateway作为联网的唯一出入口。
访问
5、可视化监控
istio自带了三个监控平台
•监控指标(Grafana)
1、请求错误率
2、请求延时(响应时间)
•网格可视化(Kiali)
3、链路跳用拓扑图
4、RPS(每秒请求),也有请求错误率
5、请求/响应数据包大小
6、查看pod日志
7、istio配置资源在线编辑
•调用链跟踪(Jaeger)
8、一个服务涉及的调用情况
9、分析数据包中具体请求/响应信息
10、响应时间
[root@master01 opt]# istioctl dashboard -hAccess to Istio web UIsUsage:istioctl dashboard [flags]istioctl dashboard [command]Aliases:dashboard, dash, dAvailable Commands:controlz Open ControlZ web UIenvoy Open Envoy admin web UIgrafana Open Grafana web UIjaeger Open Jaeger web UIkiali Open Kiali web UIprometheus Open Prometheus web UIzipkin Open Zipkin web UIFlags:--address string Address to listen on. Only accepts IP address or localhost as a value. When localhost is supplied, istioctl will try to bind on both 127.0.0.1 and ::1 and will fail if neither of these address are available to bind. (default "localhost")-h, --help help for dashboard-p, --port int Local port to listen toGlobal Flags:--context string The name of the kubeconfig context to use-i, --istioNamespace string Istio system namespace (default "istio-system")-c, --kubeconfig string Kubernetes configuration file-n, --namespace string Config namespaceUse "istioctl dashboard [command] --help" for more information about a command.[root@master01 opt]# kubectl get pod -n istio-systemNAME READY STATUS RESTARTS AGEgrafana-75745787f9-w8md6 1/1 Running 0 25mistio-egressgateway-794db4db55-hstw6 1/1 Running 0 25mistio-ingressgateway-799b86d9-x2gkh 1/1 Running 0 25mistio-tracing-c7b59f68f-fp66x 1/1 Running 0 25mistiod-55fff4d845-zmdg8 1/1 Running 0 25mkiali-85dc7cdc48-vmh29 1/1 Running 0 25mprometheus-8685fb8c59-65qxl 2/2 Running 0 25m##临时开启可用如下办法[root@master01 opt]# istioctl dashboard controlz istiod-55fff4d845-zmdg8 -n istio-system --address=10.211.55.16http://localhost:33673
为了可以通过ingressgateway的能够访问三个监控平台,因此需要编写监控monitor-gateway.yaml
[root@master01 istio-1.6.2]# kubectl get svc -n istio-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEgrafana ClusterIP 10.68.185.28 <none> 3000/TCP 26histio-egressgateway ClusterIP 10.68.80.126 <none> 80/TCP,443/TCP,15443/TCP 26histio-ingressgateway LoadBalancer 10.68.139.54 <pending> 15021:30792/TCP,80:22516/TCP,443:34994/TCP,31400:21999/TCP,15443:22618/TCP 26histiod ClusterIP 10.68.213.107 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP,853/TCP 26h 26hkiali NodePort 10.68.227.1 <none> 20001:24347/TCP 26hprometheus ClusterIP 10.68.241.113 <none> 9090/TCP 26h 18mtracing ClusterIP 10.68.156.89 <none> 80/TCP 26hzipkin NodePort 10.68.182.176 <none> 9411:24218/TCP 26h
[root@master01 istio-1.6.2]# cat monitor-gateway.yaml---#网格可视化kialaapiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: monitor-gatewaynamespace: istio-systemspec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: kialinamespace: istio-systemspec:hosts:- "kiali.istio.double.com"gateways:- monitor-gatewayhttp:- route:- destination:host: kialiport:number: 20001---#监控可视化---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: grafananamespace: istio-systemspec:hosts:- "grafana.istio.double.com"gateways:- monitor-gatewayhttp:- route:- destination:host: grafanaport:number: 3000---#调用链---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: tracingnamespace: istio-systemspec:hosts:- "tracing.istio.double.com"gateways:- monitor-gatewayhttp:- route:- destination:host: tracingport:number: 80---#链路跟踪---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: zipkinnamespace: istio-systemspec:hosts:- "zipkin.istio.double.com"gateways:- monitor-gatewayhttp:- route:- destination:host: zipkinport:number: 8441
部署监控网关入口
[root@master01 istio-1.6.2]# kubectl apply -f monitor-gateway.yaml[root@localhost istio-1.6.2]# kubectl get gateway,vs -n istio-systemNAME AGEgateway.networking.istio.io/grafana-gateway 34sgateway.networking.istio.io/kiala-gateway 34sgateway.networking.istio.io/monitor-gateway 34sgateway.networking.istio.io/traing-gateway 34sNAME GATEWAYS HOSTS AGEvirtualservice.networking.istio.io/grafana [grafana-gateway] [grafana.istio.double.com] 34svirtualservice.networking.istio.io/kiali [kiala-gateway] [kiali.istio.double.com] 34svirtualservice.networking.istio.io/tracing [tracing-gateway] [tracing.istio.double.com] 34svirtualservice.networking.istio.io/zipkin [monitor-gateway] [zipkin.istio.double.com] 34s
安装nginx,作为lb,负载均衡到ingressgateway的暴露的nodeport端口上,所有的外部流量通过ingressgateway进去istio进行管理
[root@mysql-cloud-kafka-zk ~]# cat /data/nginx/vhosts/istio.holder.cn.conf....省略include /etc/nginx/conf.d/*.conf;upstream ingressgateway {server k8s的节点ip+nodeportip;}server {listen 80 default_server;listen [::]:80 default_server;server_name _;root /usr/share/nginx/html;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;location / {proxy_pass http://ingressgateway;proxy_set_header Host $host;proxy_http_version 1.1;}}
6、切换bookinfo的入口流量到ingressgateway
# 为Bookinfo部署入口网关[root@master01 istio-1.6.2]# cat samples/bookinfo/networking/bookinfo-gateway.yamlapiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: bookinfo-gatewayspec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: bookinfospec:hosts:- "bookinfo.istio.double.com"gateways:- bookinfo-gatewayhttp:- match:- uri:exact: /productpage- uri:prefix: /static- uri:exact: /login- uri:exact: /logout- uri:prefix: /api/v1/productsroute:- destination:host: productpageport:number: 9080[root@master01 istio-1.6.2]# kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yamlgateway.networking.istio.io/bookinfo-gateway unchangedvirtualservice.networking.istio.io/bookinfo changed# 获取网关地址[root@master01 istio-1.6.2]# kubectl get gateway,vsNAME AGEgateway.networking.istio.io/bookinfo-gateway 29hNAME GATEWAYS HOSTS AGEvirtualservice.networking.istio.io/bookinfo [bookinfo-gateway] [bookinfo.istio.double.com] 29h
绑定域名,然后访问bookinfo.istio.double.com既可访问,不停地刷新图书单品页,在kiali中会实时地绘制服务网格,如下:
请求响应如下:
基于权重流量的实时控制,如下:
监控指标如下:
对于服务的可观察性,kiali还提供了很多其他的功能,这也是Istio相较于其他服务网格框架的优势,这里就不展示了。
