在Istio服务网格中部署Bookinfo在线书店微服务项目
文章目录
1.在线书店微服务项目介绍
Bookinfo在线书店微服务是Istio提供学习的一个案例,这个微服务程序中包括4个微服务程序,并且每个微服务程序都是通过不同的语言编写的,这个应用系统是模仿了书店的一个分类,会显示一本书的信息,在页面上会展示这本书的描述和评分等信息。
Bookinfo项目分为四个单独的微服务程序:
1)ProductPage(系统首页):ProductPage微服务会调用Reviews评论区系统、Details详情内容,用来生成页面。
2)Reviews(评论区):Reviews微服务包含了书籍的相关评论,会调用Ratings微服务。
3)Details(详情内容):Details微服务包含了书籍的信息,无系统调用。
3)Ratings(评分):Ratings微服务包含了由书籍评价组成的评级信息,无系统调用。
reviews 微服务有 3 个版本
1)v1 版本不会调用ratings服务。
2)v2 版本会调用ratings服务,并使用1到5个黑色星形图标来显示评分信息。
3)v3 版本会调用ratings服务,并使用1到5个红色星形图标来显示评分信息。
这三个版本用于实现灰度发布,根据上线不同的版本获取用户的体验数据,最终决定上线哪一个版本。
2.在线书店微服务系统架构图
Bookinfo在线书店中各个微服务应用都是由不同的语言编写的,这些服务对Istio没有任何依赖,其中ProductPage微服务以Python语言开发、Reviews微服务以JAVA语言开发、Details微服务以Ruby语言开发、Ratings微服务以NodeJS语言开发。
在线书店微服务部署在Istio服务网格之后的访问流程:
请求首先到达Istio的IngressGateway组件,根据配置的Gateway以及VirtualService资源,将请求转发到ProductPage首页微服务容器中的Envoy代理程序,各个程序之间的调用都通过Envoy代理程序进行通信,ProductPage系统首页微服务会调用Reviews展示评论区的内容,调用Details展示详情内容,Reviews微服务调用Ratings微服务显示评分内容。
3.部署在线书店微服务项目程序
3.1.Bookinfo资源编排文件解释
Bookinfo每个微服务程序都采用Deployment控制器进行部署,并且每个微服务程序都创建了一个SA账号。
和传统资源编排文件不同的地方在于:Reviews微服务需要同时部署多个不同版本的程序,并且不同的版本在Deployment资源编排文件中分包定义了不同的Pod标签,用于区分不同的程序版本实现灰度发布的机制,多版本会同时接入一个Service资源为线上用户提供服务,
Bookinfo在线书店的资源编排文件所在的路径为:istio-1.13.1/samples/bookinfo/platform/kube
Reviews微服务会部署三个不同的版本,以Reviews微服务程序V1版本为例简单看一下资源编排文件的内容。
apiVersion: v1
kind: Service #首先定义了一个service资源
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews #关联带有app=reviews标签的pod资源
---
apiVersion: v1
kind: ServiceAccount #定义了serviceaccount账号
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment #微服务通过deployment资源控制器部署
metadata:
name: reviews-v1
labels:
app: reviews #定义微服务程序的标签
version: v1 #定义当前使用的版本标签,主要是通过这个标签实现灰度发布
spec:
replicas: 1
selector:
matchLabels: #关联pod使用的标签
app: reviews
version: v1
template:
metadata:
labels:
app: reviews #定义微服务程序的标签
version: v1 #定义当前使用的版本标签,主要是通过这个标签实现灰度发布
spec:
serviceAccountName: bookinfo-reviews #指定SA账号
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2 #程序使用的镜像
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts: #数据挂载
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes: #采用的临时目录,线上环境一定要用远程存储
- name: wlp-output
emptyDir: {
}
- name: tmp
emptyDir: {
}
3.2.创建微服务使用的命名空间并开启自动注入
当配置了Sidecar自动注入后,创建Pod资源时,Istio会在编排文件中增加Sidecar代理程序的配置信息,将Sidecar与应用程序部署在同一个Pod资源中。
[root@k8s-master ~]# kubectl create ns bookinfo
namespace/bookinfo created
[root@k8s-master ~]# kubectl label namespace bookinfo istio-injection=enabled
namespace/bookinfo labeled
3.3.在Istio中部署在线书店微服务项目
1)部署在线书店微服务项目
1.进入Bookinfo项目提供的YAML文件路径
[root@k8s-master ~]# cd istio-1.8.2/samples/bookinfo/platform/kube/
2.在K8S集群中部署Bookinfo各个微服务程序
[root@k8s-master kube]# kubectl apply -f bookinfo.yaml -n bookinfo
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
3.查看部署的资源
[root@k8s-master kube]# kubectl get pod,deploy,svc -n bookinfo
NAME READY STATUS RESTARTS AGE
pod/details-v1-79f774bdb9-pg7vn 2/2 Running 0 11m
pod/productpage-v1-6b746f74dc-6k86p 2/2 Running 0 11m
pod/ratings-v1-b6994bb9-46bzz 2/2 Running 0 11m
pod/reviews-v1-545db77b95-v22lp 2/2 Running 0 11m
pod/reviews-v2-7bf8c9648f-m649b 2/2 Running 0 11m
pod/reviews-v3-84779c7bbc-gdf5q 2/2 Running 0 11m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/details ClusterIP 10.97.209.64 <none> 9080/TCP 11m
service/productpage ClusterIP 10.106.201.162 <none> 9080/TCP 11m
service/ratings ClusterIP 10.104.85.105 <none> 9080/TCP 11m
service/reviews ClusterIP 10.107.113.19 <none> 9080/TCP 11m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/details-v1 1/1 1 1 11m
deployment.apps/productpage-v1 1/1 1 1 11m
deployment.apps/ratings-v1 1/1 1 1 11m
deployment.apps/reviews-v1 1/1 1 1 11m
deployment.apps/reviews-v2 1/1 1 1 11m
deployment.apps/reviews-v3 1/1 1 1 11m
#Bookinfo微服务项目部署好之后就是一个带有灰度发布的机制,Reviews微服务有3个不同的版本,不同版本的应用程序分别通过Deployment资源创建,然后同时接入到一个Service资源中,用户访问时会访问到不同版本的程序。
2)测试项目的可访问性
[root@k8s-master kube]# kubectl exec -it $(kubectl get pod -l app=ratings -n bookinfo -o jsonpath='{.items[0].metadata.name}') -n bookinfo -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
#当返回Simple Bookstore APP时就表示在线书店微服务程序部署完成了
3.4.创建在线书店的Gateway及VirtualService资源
通过创建Gateway以及VirtualService资源将Istio中的应用程序通过IngressGateway发布在互联网环境。
1)查看资源编排文件的内容
1.进入网关资源的编排文件目录
[root@k8s-master kube]# cd /root/istio-1.8.2/samples/bookinfo/networking
2.网关资源编排文件内容
[root@k8s-master networking]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway #控制器类型为Gateway
metadata:
name: bookinfo-gateway #定义控制器的名称
spec:
selector:
istio: ingressgateway #关联带有istio=ingressgateway标签的gateway组件,将代理配置信息配置在ingressgateway中
servers: #定义服务使用的端口号
- port:
number: 80 #使用80端口,名称为http,协议为http
name: http
protocol: HTTP
hosts: #允许访问的主机
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService #控制器的类型为VirtualService
metadata:
name: bookinfo #定义控制器的名称
spec:
hosts: #定义流量转发的机器
- "*"
gateways: #关联Gateway资源
- bookinfo-gateway
http: #定义路由规则
- match:
- uri: #url表示根据url做路由转发规则
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route: #定义路由转发规则
- destination:
host: productpage #将指定的5个url路径全部转发到productpage的service资源上
port:
number: 9080 #service资源的端口号
2)创建资源控制器
1.创建资源
[root@k8s-master networking]# kubectl apply -f bookinfo-gateway.yaml -n bookinfo
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
2.查看资源的状态
[root@k8s-master networking]# kubectl get gw,vs -n bookinfo
NAME AGE
gateway.networking.istio.io/bookinfo-gateway 10s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/bookinfo ["bookinfo-gateway"] ["*"] 10s
3.5.访问Bookinfo图书评测系统
创建完Bookinfo微服务的Gateway及VirtualService资源后,就可以通过Istio的IngressGateway资源访问网格中的程序了。
[root@k8s-master networking]# kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egressgateway ClusterIP 10.98.153.235 <none> 80/TCP,443/TCP 18h
istio-ingressgateway LoadBalancer 10.109.142.180 <pending>
15021:31707/TCP,80:32544/TCP,443:31600/TCP,31400:32642/TCP,15443:31500/TCP 18h
istiod ClusterIP 10.98.63.3 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 18h
使用IngressGateway的80端口映射的NodePort端口进行访问:http://192.168.20.10:31105/productpage
。
4.通过域名的方式访问Istio中的应用程序
在前面我们都是通过IP+端口的方式访问Istio中的应用程序,试想一下,如果在Istio中部署的应用程序有多个,通过IP的形式肯定不能正常访问多个应用系统,接下来我们就来实现基于域名去访问Istio中的不同应用程序。
通过域名访问Istio中应用程序的方式:
- 通过LB设备反向代理IngressGateway的Nodeport端口
- 我们可以来搭建一个LB负载均衡,比如是Nginx,在Nginx中配置反向代理,将来自用户的所有域名请求全部转发到Istio的IngressGateway的NodePort端口上,从而通过域名来访问应用程序。
- Nginx反向代理转发时会携带请求头,头部信息中会包含域名地址,域名被带入到IngresssGateway,再由Gateway转发到应用程序Service资源上,完成请求的访问。
- 配置IngressGateway Service资源的Loadblancer外部地址
- IngressGateway采用LoadBlancer类型的Service资源,我们可以为LoadBlancer配置一个External-IP外部地址,这个地址可以是阿里云申请的公网IP地址也可以是局域网内的某个IP地址,Service资源会将这个IP与指定的端口做一组IPVS策略映射,配置完成后我们就可以通过这个IP+80端口来访问Istio中的应用程序。
- 实现了IP+80端口访问应用程序就可以将这个IP与域名进行映射,请求转发到IngressGateway时,头部信息会携带域名,最终转发到不同的应用程序上。
- 注意这个External IP地址不能是某个机器在使用的地址。
不管使用哪种方式通过域名去访问Istio中的应用程序,都需要在程序的Gateway以及VirtualService中绑定程序使用的域名,否则来着不同的域名请求还是会随机转发。
以在线书店项目为例,通过配置IngressGateway Service资源的Loadblancer外部地址的方式,来实现基于域名去访问Istio中的应用程序。
4.1.配置在线书店的GW和VS资源绑定程序域名
当VS和GW资源都绑定了域名后,就无法通过IP的形式访问应用程序了。
1.修改资源编排文件
[root@k8s-master networking]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "bookinfo.jiangxl.com" #在hosts字段中绑定程序的域名
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.jiangxl.com" #绑定程序的域名
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
2.更新资源编排文件
[root@k8s-master networking]# kubectl apply -f bookinfo-gateway.yaml -n bookinfo
gateway.networking.istio.io/bookinfo-gateway configured
virtualservice.networking.istio.io/bookinfo configured
4.2.配置IngressGateway的Service资源
我们可以看到IngressGateway的Service资源是Loadblancer类型,但是并没有指定Loadblancer使用的负载均衡器地址,因此会一直显示pending状态,接下来我们去配置一个Loadblancer的External-IP(外部地址),通过指定的Loadblancer负载均衡地址来访问应用程序。
在这里我们指定一个局域网环境内不存在的IP地址当做LoadBlancer的外部地址。
[root@k8s-master networking]# kubectl edit svc istio-ingressgateway -n istio-system
spec:
clusterIP: 10.109.142.180
externalIPs:
- 192.168.20.15
externalTrafficPolicy: Cluster
······
service/istio-ingressgateway edited
#切记不可用在edit中使用tab键
配置完成后即可生效。
4.3.查看Service资源生成的IPVS策略
策略的含义就是将制定的外部地址与Loadblancer的端口做了一个映射。
[root@k8s-master networking]# ipvsadm -Ln | grep 20.15
TCP 192.168.20.15:15021 rr
TCP 192.168.20.15:80 rr
TCP 192.168.20.15:443 rr
TCP 192.168.20.15:15443 rr
TCP 192.168.20.15:31400 rr
4.4.使用Loadblancer外部地址访问在线书店
首先在hosts解析中配置域名地址解析,通过域名的形式来访问在线书店。
192.168.20.15 bookinfo.jiangxl.com
即使我们Istio中部署了多个应用程序也不会影响各系统间的访问。
5.在Istio中卸载Bookinfo在线书店
[root@k8s-master bookinfo]# sh platform/kube/cleanup.sh
namespace ? [default] bookinfo
using NAMESPACE=bookinfo
virtualservice.networking.istio.io "bookinfo" deleted
gateway.networking.istio.io "bookinfo-gateway" deleted
Application cleanup may take up to one minute
service "details" deleted
serviceaccount "bookinfo-details" deleted
deployment.apps "details-v1" deleted
service "ratings" deleted
serviceaccount "bookinfo-ratings" deleted
deployment.apps "ratings-v1" deleted
service "reviews" deleted
serviceaccount "bookinfo-reviews" deleted
deployment.apps "reviews-v1" deleted
deployment.apps "reviews-v2" deleted
deployment.apps "reviews-v3" deleted
service "productpage" deleted
serviceaccount "bookinfo-productpage" deleted
deployment.apps "productpage-v1" deleted
Application cleanup successful