Service Mesh实践之Istio初体验
閱讀本文約花費: 16 (分鐘)
微服务国内发展背景:
2014年,Martin Fowler撰写的《Microservices》使得许多国内的先行者接触到微服务这个概念并将其引入国内,2015年越来越多的人通过各种渠道了解到微服务的概念并有人开始在生产环境中落地,2016-2017年,微服务的概念被越来越多的人认可,带动了一大批公司以微服务和容器为核心开始技术架构的全面革新。
至今微服务已经历了两代发展,第一代以Spring Cloud为代表的微服务开发框架,该框架在微服务发展的前几年一度独领风骚,甚至在部分人群中成为微服务的代名词,但事实上该微服务框架并不是唯一实现微服务的方式;第二代微服务技术为服务网格(Service Mesh),它的出现解决了大部分开发人员在使用Spring Cloud中遇到的不足和痛点。
Service Mesh是如何解决这些问题的,又是何以赢得众多开发者的支持呢?笔者就这些问题给大家分享一篇以Istio为代表的第二代微服务实践。
一、微服务和Istio
Service Mesh基本概念
服务网格是一个基础设施层,主要用于处理服务间的通信。云原生应用有着复杂的服务拓扑,服务网格负责在这些拓扑中实现请求的可靠传递。在实践中,服务网格通常实现为一组轻量级网络代理,它们与应用程序部署在一起,而对应用程序透明。
图1展示了服务网格的拓扑,当微服务数量增多达到几十上百时,服务网格就会呈现服务网格状,其中绿色为微服务,蓝色为服务网格,服务网格以典型的sidecar方式部署在微服务旁。
sidecar:一种单节点、多容器的应用设计形式。sidecar主张以额外的容器来扩展或增强主容器,而这个额外的容器被称为sidecar容器。
Istio基本概念
Istio是由Google、IBM、Lyft联合开发的开源项目,2017年5月发布第一个release 0.1.0, 它是一个完全开源的服务网格,可以透明的分层到现有的分布式应用中,它也是一个平台,包括允许它集成到任何日志记录平台,遥测或策略系统的API。Istio 多样化功能集能够高效的运行在分布式微服务架构中,并同时提供保护、连接和监控微服务等方法。
Istio基本架构
由图2可知,Istio架构在网格逻辑上主要分为控制平面(Control Plane API)和数据平面(Data Plane)。
控制平面:负责管理和配置代理来路由流量。主要分为三个组件Pilot、Mixer、Citadel,由于篇幅有限,此处对概念进行简单介绍:
Pilot:为Envoy sidecar提供服务发现功能,为智能路由和弹性提供管理功能,它将控制流量行为的高级路由转化为特定于Envoy的配置,并在运行时将它们传播到sidecar。
Mixer:独立于平台,负责在Service Mesh上执行访问控制和使用策略,并从Envoy代理和其它服务中收集遥测数据。
Citadel:通过内置身份和凭证管理以提供服务与服务间的身份验证并且可以升级Service Mesh中未加密的流量。
数据平面:由一组以sidecar方式部署的智能代理组成,这些代理可以调节和控制微服务及Mixer之间所有的网络通信。Istio默认使用Envoy做智能代理,当然也支持其它代理,例如Linkerd、Nginmesh等。
Envoy:C++开发的高性能代理,用于调解Service Mesh中所有的入站和出站流量。Envoy含有许多的内置功能:动态服务发现、负载均衡、熔断器、健康检查、HTTP/2和gRPC代理等。Envoy在Istio中被部署为sidecar,和对应的微服务在同一个Kubernetes Pod中,Istio将其功能添加到sidecar中来对微服务进行管理而无需更改微服务应用代码,起到一个无侵入式的作用。
二、为什么要使用Istio?
随着微服务规模的增长,其复杂性也越来越高,其中面临许多需求,例如服务发现、故障恢复、监控、负载均衡、限流、访问控制等,Istio提供了一体化的方案,通过为整个Service Mesh提供管理来满足微服务应用中复杂变换的需求,其中提供了许多非常关键的需求:
流量管理:控制服务之间流量和API调用,使得调用更可靠。
可观察性:了解服务之间依赖关系,以及它们之间流量的本质和流向。
策略执行:策略应用于微服务之间互动,确保访问策略得以执行(执行是通过配置网格而不是修改程序代码)。
服务身份安全:为网格中的服务提供可靠身份验证,并提供保护流量的能力。
三、试用Istio
Istio实践主要分为三步,第一步下载并部署Istio;第二步部署Bookinfo微服务;第三步通过指定yaml文件测试Istio的功能特性。
主要配置环境如下:
操作系统:Ubuntu 16.04
Kubernetes对应版本:
图3 Kubernetes工具版本
Kubernetes集群为:
图4 Kubernetes节点信息
第一步 安装Istio
在终端首先获取最新的Istio安装包:
curl -L https://git.io/getLatestIstio | sh – |
进入安装包目录后进入install/kubernetes/目录安装Kubernetes所需yaml文件,如图5所示:
图5 Istio安装包
使用kubectl运行istio-demo.yaml文件(有四种方式安装,对应有不同的yaml文件,此处选择默认不启用TLS身份验证的安装方式,启用TLS安装方式的yaml文件为istio-demo-auth.yaml),安装过程如图6所示:
kubectl create –f istio-demo.yaml |
图6 Istio安装过程
显示已安装成功(由于安装内容较多,只截图了其中一部分),之后查看已部署的Istio Pod运行状况:
kubectl get po -o wide –all-namespaces |
图7 Istio中运行的Pod
由图7可以看出Kubernetes中命名空间为istio-system的Pod,其中包含许多组件,如用于监控的Grafana、Prometheus,用于服务查看的ServiceGraph,以及Istio组件citadel、mixer、pilot等。
可以再查看Istio安装包中安装的service,其中PORTS栏可以查看服务对外暴露的端口号,以便在外部访问,如图8所示:
kubectl get svc -n istio-system |
图8 Istio中运行的service
为了使用Istio的命令行工具istioctl,需要指定环境变量以便后期使用:
export PATH=/home/xxxx/istio-1.0.0/bin:$PATH |
下面可以简单看看istioctl的命令使用,如图9所示:
图9 istioctl基本命令
第二步 部署Bookinfo微服务
Bookinfo是Istio提供的一个样例应用,它由四个单独的微服务构成,用来演示多种 Istio 特性:
productpage:productpage微服务会调用details和reviews两个微服务,用来生成页面。
details:此微服务包含书籍的信息。
reviews:此微服务包含书籍的相关评论,它会调用ratings微服务。
ratings:此微服务包含书籍评价的评级信息。
其中reviews微服务包含三个版本:
v1版本不会调用ratings微服务。
v2版本调用ratings并使用5个黑色星型图标显示评分信息。
v3版本调用ratings并使用5个红色星型图标显示评分信息。
图10 Bookinfo架构图
其中所有的微服务都和Envoy sidecar集成在一起,所有服务的出入流量都被Envoy劫持,这样Istio的控制平面就可以为应用提供服务路由、遥测数据收集以及策略实施等内容。
由于之前已经下载了bookinfo相关yaml文件,所以直接执行就好了,如图11、12所示:
kubectl create –f bookinfo.yaml kubectl create –f bookinfo-gateway.yaml |
图11 运行Bookinfo
图12 运行bookinfo-gateway
查看Kubernetes中Bookinfo应用运行状况,如图13所示:
图13 Bookinfo运行的Pod
查看Bookinfo中service部署情况,如图14所示:
kubectl get svc |
图14 Bookinfo运行的service
至此Bookinfo应用已部署完毕,那么如何访问Bookinfo中的微服务呢?通过前面所讲可知Bookinfo有对应的Web微服务productpage,可以通过以下方式访问:
首先确定Ingress的IP和端口:
port:
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==”http2″)].nodePort}’) |
secure port:
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==”https”)].nodePort}’) |
host:
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o ‘jsonpath={.items[0].status.hostIP}’) |
GATEWAY_URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT |
具体操作如图15所示,可知网关入口为20.0.0.13:31380。
图15 配置Ingress地址
测试Bookinfo应用的运行情况,返回200为正常,如图16所示:
curl -o /dev/null -s -w “%{http_code}\n” http://${GATEWAY_URL}/productpage |
图16 测试Bookinfo运行情况
在Chrome浏览器中输入,如图17所示:http://192.168.19.13:31380/productpage。
图17 Bookinfo应用Web界面
上图可以看出Bookinfo应用由4个微服务组成,即web微服务页面productpage、页面左边部分为Book Details服务,右边部分为Book Reviews服务, reviews服务目前为v1状态即无星级评分。由于未设置请求路由,多刷新页面几次,请求路由流量会随机的在reviews服务v1、v2、v3中切换。
第三步:验证Istio功能
请求路由
此样例会把Bookinfo应用的进入流量导向reviews服务的v1版本,配置yaml文件如图18所示:
图18 route-rule-all-v1.yaml文件部分内容
终端执行以下命令,如图19所示:
kubectl apply -f route-rule-all-v1.yaml |
图19 route-rule-all-v1.yaml文件执行过程
此时多次刷新页面就会发现每次刷新reviews服务始终为v1版本。
如果想看具体的virtualservices和destinationrules可以通过命令查看:
kubectl get virtualservices -o yaml kubectl get destinationrules -o yaml |
请求也可以基于用户身份去路由,比如“xx”登录就是reviews服务的v1版本,其它用户登录则为v2版本。
故障注入
此样例会使用Istio测试Bookinfo应用的弹性,具体方式为当用户jason登录时在reviews:v2和ratings之间进行延迟注入。此样例对应yaml文件如图20所示:
图20 route-rule-ratings-test-delay.yaml文件内容
终端执行以下命令,如图21所示:
kubectl replace -f route-rule-ratings-test-delay.yaml |
图21 route-rule-ratings-test-delay.yaml文件执行过程
此时用jason账号登录就会发现每次请求路由到reviews微服务都要6秒左右,可以打开chrome浏览器开发者工具查看,并且reviews部分显示错误消息,如图22所示:
图22 故障注入页面展示
流量迁移
此样例会使用Istio将所有用户的流量按照权重进行转移,此样例对应的yaml文件如图23所示:
图23 route-rule-reviews-50-v3.yaml文件内容
由上图可知当有流量进入时,百分之五十流量迁移到reviews v1,另外百分之五十流量迁移到reviews v3,终端执行以下命令,如图21所示:
kubectl replace -f route-rule-reviews-50-v3.yaml |
此时刷新页面就会看到有一半的概率是reviews v3(红色星),一半概率是reviews v1(无评星)。
设定请求超时
此样例首先将流量全部导入reviews v2服务,再给ratings服务增加2秒延迟,最后为reviews服务调用添加0.5秒请求超时,顺序如图24-29所示:
图24 流量导入reviews v2
图25 productpage页面显示reviews v2
图26 ratings服务添加2秒延迟
图27 ratings服务添加延迟Web页面效果
图28 reviews服务添加0.5秒请求超时
图29 reviews服务加超时Web页面效果
最终刷新页面由图29显示,看到返回时间为1秒左右并且评论不可用,这是为什么呢?答案是productpage服务有硬编码重试,因此在页面刷新时,请求返回之前需要调用超时reviews服务两次,每次为0.5秒左右,两次就为1秒左右了。
大家想象下,当微服务的数量增多时,运维人员根据需求需要对部分微服务进行A/B测试,金丝雀发布或是限流、流量分片等操作,这无疑增加了运维人员的管理复杂度,Istio考虑的非常周全,在安装包中附加了监控、跟踪等组件,以下分别展示:
Trace:
图30 Bookinfo应用分布式追踪页面
图31 Bookinfo应用分布式追踪详细页面
Prometheus:
图32 Istio请求总数
Service Graph:
图33 Bookinfo应用service图表
Grafana:
图34 Grafana监控Web页面
Istio还有许多功能特性例如熔断机制,控制Ingress流量等,在此由于篇幅限制不多做描述,大家感兴趣的话可以去官网查看https://istio.io/docs/tasks/。
图35 Istio的安全架构
四、总结
通过以上对Istio的实践大家不难看出Istio相比于Spring Cloud的几个优点。首先相比于Spring Cloud学习组件内容多,门槛高的痛点,Istio是非常容易上手的,只需在Kubernetes平台上跑一个yaml文件即可完成部署;再者相比于Spring Cloud需要把认证授权、分布式追踪、监控等这些高级功能加入到应用程序内部导致了应用本身复杂度的痛点,反观Istio是很轻量级的,它将以上那些高级功能作为组件内置在Istio中,从而达到了对应用程序的无侵入性,只需要配置相应的yaml文件并下发至Istio控制平面执行后续的操作即可,操作过程用户是无感知的;最后相比于Spring Cloud对Java环境的过度依赖以及跨语言痛点,Istio也完美的解决了,其支持多种语言,包括新兴编程语言Golang、Rust、Node.js、R语言等。
虽然目前Istio在社区有众多的支持者,但从第一个版本到现在只有不到 一年半的时间,目前Istio国内生产落地的公司还相对较少,华为的CES Mesher、新浪微博的Motan、唯品会的OSP等都已经在使用,阿里云和腾讯云的持续跟进相信也不远了, Istio的未来一片光明,让我们共同期待。